Java tutorial
/* * Copyright 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.leec.tools.apps; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import android.content.ClipData; import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.util.Log; import android.view.*; import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.ListView; import android.widget.SimpleExpandableListAdapter; import android.widget.Toast; import com.leec.tools.common.AppUtils; import com.leec.tools.common.CheckListAdapter; public class DetailsActivity extends ActionBarActivity implements ActionBar.TabListener { private static final String TAG = DetailsActivity.class.getSimpleName(); public static final String ARG_PACKAGE_NAME = "package_name"; /** * The {@link android.support.v4.view.PagerAdapter} that will provide fragments for each of the * three primary sections of the app. We use a {@link android.support.v4.app.FragmentPagerAdapter} * derivative, which will keep every loaded fragment in memory. If this becomes too memory * intensive, it may be best to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}. */ private AppSectionsPagerAdapter mAppSectionsPagerAdapter; /** * The {@link ViewPager} that will display the three primary sections of the app, one at a * time. */ private ViewPager mViewPager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_app_details_pager); // Set up the action bar. final android.support.v7.app.ActionBar actionBar = this.getSupportActionBar(); Intent intent = getIntent(); String packageName = intent.getStringExtra(ARG_PACKAGE_NAME); PackageManager pm = getPackageManager(); if (actionBar != null) { //show icon false //actionBar.setDisplayShowHomeEnabled(false); //back action actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setSubtitle(packageName); try { PackageInfo p = pm.getPackageInfo(packageName, 0); actionBar.setTitle(pm.getApplicationLabel(p.applicationInfo)); actionBar.setIcon(pm.getApplicationIcon(p.applicationInfo)); } catch (NameNotFoundException e) { } } // Create the adapter that will return a fragment for each of the three primary sections // of the app. mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager(), packageName, this); // Set up the ViewPager, attaching the adapter and setting up a listener for when the // user swipes between sections. mViewPager = (ViewPager) findViewById(R.id.app_details_pager); mViewPager.setAdapter(mAppSectionsPagerAdapter); PagerTabStrip tabStrip = (PagerTabStrip) mViewPager.findViewById(R.id.pager_title); //tabStrip.setTabIndicatorColor(); tabStrip.setTabIndicatorColorResource(R.color.tab_indicator_color); // For each of the sections in the app, add a tab to the action bar. for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) { // Create a tab with text corresponding to the page title defined by the adapter. // Also specify this Activity object, which implements the TabListener interface, as the // listener for when this tab is selected. actionBar.addTab( actionBar.newTab().setText(mAppSectionsPagerAdapter.getPageTitle(i)).setTabListener(this)); } } /* -- replace with android.support.v7.app.ActionBar @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { // When the given tab is selected, switch to the corresponding page in the ViewPager. mViewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { }*/ @Override public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) { // When the given tab is selected, switch to the corresponding page in the ViewPager. mViewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) { } @Override public void onTabReselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) { } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: this.finish(); default: return super.onOptionsItemSelected(item); } } /** * A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary * sections of the app. */ public static class AppSectionsPagerAdapter extends FragmentPagerAdapter { private String mPackageName; private Context mContext; private String[] mAppTabs; public AppSectionsPagerAdapter(FragmentManager fm, String packageName, Context context) { super(fm); mPackageName = packageName; mContext = context; mAppTabs = mContext.getResources().getStringArray(R.array.app_details_tabs); } @Override public Fragment getItem(int i) { Fragment fragment; Bundle args = new Bundle(); if (i < 3) { fragment = new ComponentFragment(); fragment.setHasOptionsMenu(true); args.putInt(ComponentFragment.ARG_SECTION_NUMBER, i); } else { fragment = new PermissionFragment(); } args.putString(ARG_PACKAGE_NAME, mPackageName); fragment.setArguments(args); return fragment; } @Override public int getCount() { return mAppTabs.length; } @Override public CharSequence getPageTitle(int position) { return mAppTabs[position]; } } /** * A dummy fragment representing a section of the app, but that simply displays dummy text. */ public static class ComponentFragment extends Fragment implements SearchView.OnQueryTextListener { public static final String ARG_SECTION_NUMBER = "section_number"; private String mPackageName; private int mSectionNumber; private ListView mListView; private CheckListAdapter mAdapter; private PackageManager mPackageManager; private List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.activity_app_details, container, false); Bundle args = getArguments(); mPackageName = args.getString(ARG_PACKAGE_NAME); mSectionNumber = args.getInt(ARG_SECTION_NUMBER); mPackageManager = getActivity().getPackageManager(); mAdapter = new CheckListAdapter(getActivity(), datas, R.layout.app_details_list_item, new String[] { "component_name" }, new int[] { R.id.component_name }); mAdapter.setQueryFields(new String[] { "component_name" }); mAdapter.setViewBinder(new AppViewBinder()); mAdapter.setViewPost(new StateViewPost()); mListView = (ListView) rootView.findViewById(R.id.app_detail_list_view); mListView.setAdapter(mAdapter); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() { @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { // Here you can do something when items are // selected/de-selected, // such as update the title in the CAB mAdapter.getCheckState()[position] = checked ? 1 : 0; mAdapter.notifyDataSetChanged(); mode.setTitle(String.valueOf(mListView.getCheckedItemCount())); } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // Respond to clicks on the actions in the CAB @SuppressWarnings("unchecked") final List<ComponentName> components = (List<ComponentName>) mAdapter .getCheckedValues("component"); switch (item.getItemId()) { case R.id.action_copy: StringBuilder text = new StringBuilder(); for (ComponentName component : components) { text.append(component.getClassName()).append("\n"); } ClipboardManager clipboardManager = (ClipboardManager) getActivity() .getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setPrimaryClip(ClipData.newPlainText("component_names", text.toString())); Toast.makeText(getActivity(), components.size() + " components has copied to clipboard", Toast.LENGTH_LONG).show(); mAdapter.uncheckAll(); mode.finish(); // Action picked, so close the CAB reloadListDatas(); return true; case R.id.action_enable: AppUtils.processWithSecurity(getActivity(), new AppUtils.Processor() { @Override public void process(Context context) { AppUtils.setComponentEnabledState(components, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, mPackageManager); Toast.makeText(getActivity(), components.size() + " components enabled success", Toast.LENGTH_LONG).show(); } }); mAdapter.uncheckAll(); mode.finish(); // Action picked, so close the CAB reloadListDatas(); return true; case R.id.action_disable: AppUtils.processWithSecurity(getActivity(), new AppUtils.Processor() { @Override public void process(Context context) { AppUtils.setComponentEnabledState(components, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, mPackageManager); Toast.makeText(getActivity(), components.size() + " components disabled success", Toast.LENGTH_LONG).show(); } }); mAdapter.uncheckAll(); mode.finish(); // Action picked, so close the CAB reloadListDatas(); return true; default: return false; } } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate the menu for the CAB MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.app_details_action_menu, menu); return true; } @Override public void onDestroyActionMode(ActionMode mode) { // Here you can make any necessary updates to the activity when // the CAB is removed. By default, selected items are deselected/unchecked. mAdapter.uncheckAll(); } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // Here you can perform updates to the CAB due to // an invalidate() request return false; } }); return rootView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); reloadListDatas(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { super.onCreateOptionsMenu(menu, menuInflater); menuInflater.inflate(R.menu.action_search, menu); SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); searchView.setOnQueryTextListener(this); searchView.setQueryHint(getString(R.string.search_hint)); } @Override public boolean onQueryTextChange(String newText) { mAdapter.setQuery(newText); return true; } @Override public boolean onQueryTextSubmit(String query) { int next = mAdapter.getNextQueryPosition(); if (next == -1) { Toast.makeText(getActivity(), "No more search result!", Toast.LENGTH_LONG).show(); } else { mListView.setSelection(next); } return true; } protected void reloadListDatas() { Log.d(TAG, "Load packages details..."); datas.clear(); datas.addAll(AppUtils.getPackageDetails(mPackageName, mPackageManager, (Integer) AppUtils.decode(mSectionNumber, 0, PackageManager.GET_ACTIVITIES, 1, PackageManager.GET_SERVICES, 2, PackageManager.GET_RECEIVERS, 0))); mAdapter.notifyDataSetChanged(); } } public static class PermissionFragment extends Fragment { private String mPackageName; private ExpandableListView mListView; private BaseExpandableListAdapter mAdapter; private PackageManager mPackageManager; private List<Map<String, Object>> groupDatas = new ArrayList<Map<String, Object>>(); private List<List<Map<String, Object>>> childDatas = new ArrayList<List<Map<String, Object>>>(); private String[] mGroupTitles; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.activity_app_permissions, container, false); Bundle args = getArguments(); mPackageName = args.getString(ARG_PACKAGE_NAME); mPackageManager = getActivity().getPackageManager(); mGroupTitles = getResources().getStringArray(R.array.app_details_permission_groups); loadListDatas(); mAdapter = new SimpleExpandableListAdapter(getActivity(), groupDatas, R.layout.app_details_list_group, new String[] { "permission_group" }, new int[] { R.id.group_title }, childDatas, R.layout.app_details_list_item, new String[] { "permission_name" }, new int[] { R.id.component_name }); mListView = (ExpandableListView) rootView.findViewById(R.id.app_permissions_expand_list_view); mListView.setAdapter(mAdapter); // expand all int groupCount = mListView.getCount(); for (int i = 0; i < groupCount; i++) { mListView.expandGroup(i); } mListView.setGroupIndicator(null); mListView.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { @SuppressWarnings("unchecked") Map<String, Object> group = (Map<String, Object>) mAdapter.getGroup(groupPosition); //USES-FEATURES can't be view permissions. if (mGroupTitles[0].equals(group.get("permission_group"))) return false; @SuppressWarnings("unchecked") Map<String, Object> child = (Map<String, Object>) mAdapter.getChild(groupPosition, childPosition); startAppPermissions((String) child.get("permission_name")); return true; } }); return rootView; } protected void loadListDatas() { Log.d(TAG, "Load permissions details..."); groupDatas.clear(); for (String title : mGroupTitles) { Map<String, Object> map = new HashMap<String, Object>(); map.put("permission_group", title); groupDatas.add(map); } childDatas.clear(); childDatas.addAll(AppUtils.getPermissions(mPackageName, mPackageManager)); Iterator<List<Map<String, Object>>> it = childDatas.iterator(); int i = 0; while (it.hasNext()) { if (it.next().isEmpty()) { it.remove(); groupDatas.remove(i); } else { i++; } } } protected void startAppPermissions(String permissionName) { Intent intent = new Intent(getActivity(), SameAppsActivity.class); intent.putExtra(SameAppsActivity.ARG_PERMISSION_NAME, permissionName); startActivity(intent); } } }