diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 41ec207a226..b3058603fc8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3330,8 +3330,14 @@
android:value="@string/menu_key_connected_devices"/>
-
+
+
+
+
diff --git a/src/com/android/settings/development/AppPicker.java b/src/com/android/settings/development/AppPicker.java
index a11788cb83d..1026ff27d5b 100644
--- a/src/com/android/settings/development/AppPicker.java
+++ b/src/com/android/settings/development/AppPicker.java
@@ -16,8 +16,6 @@
package com.android.settings.development;
-import android.app.ActionBar;
-import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -33,15 +31,19 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.ListFragment;
+
+import com.android.settings.SettingsActivity;
+
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-public class AppPicker extends ListActivity {
- private AppListAdapter mAdapter;
-
+public class AppPicker extends SettingsActivity {
public static final String EXTRA_REQUESTIING_PERMISSION
= "com.android.settings.extra.REQUESTIING_PERMISSION";
public static final String EXTRA_DEBUGGABLE = "com.android.settings.extra.DEBUGGABLE";
@@ -50,32 +52,20 @@ public class AppPicker extends ListActivity {
public static final int RESULT_NO_MATCHING_APPS = -2;
- private String mPermissionName;
- private boolean mDebuggableOnly;
- private boolean mNonSystemOnly;
- private boolean mIncludeNothing;
-
@Override
protected void onCreate(Bundle icicle) {
+ final Intent intent = getIntent();
+
+ String permissionName = getIntent().getStringExtra(EXTRA_REQUESTIING_PERMISSION);
+ boolean debuggableOnly = getIntent().getBooleanExtra(EXTRA_DEBUGGABLE, false);
+ boolean nonSystemOnly = getIntent().getBooleanExtra(EXTRA_NON_SYSTEM, false);
+ boolean includeNothing = getIntent().getBooleanExtra(EXTRA_INCLUDE_NOTHING, true);
+
+ intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS,
+ AppPickerListFragment.withArgs(permissionName, debuggableOnly, nonSystemOnly,
+ includeNothing));
+
super.onCreate(icicle);
-
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- }
-
- mPermissionName = getIntent().getStringExtra(EXTRA_REQUESTIING_PERMISSION);
- mDebuggableOnly = getIntent().getBooleanExtra(EXTRA_DEBUGGABLE, false);
- mNonSystemOnly = getIntent().getBooleanExtra(EXTRA_NON_SYSTEM, false);
- mIncludeNothing = getIntent().getBooleanExtra(EXTRA_INCLUDE_NOTHING, true);
-
- mAdapter = new AppListAdapter(this);
- if (mAdapter.getCount() <= 0) {
- setResult(RESULT_NO_MATCHING_APPS);
- finish();
- } else {
- setListAdapter(mAdapter);
- }
}
@Override
@@ -88,16 +78,12 @@ public class AppPicker extends ListActivity {
}
@Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
- MyApplicationInfo app = mAdapter.getItem(position);
- Intent intent = new Intent();
- if (app.info != null) intent.setAction(app.info.packageName);
- setResult(RESULT_OK, intent);
- finish();
+ protected boolean isValidFragment(String fragmentName) {
+ return AppPickerListFragment.class.getName().equals(fragmentName);
}
private void handleBackPressed() {
- if (getFragmentManager().getBackStackEntryCount() > 1) {
+ if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
super.onBackPressed();
} else {
setResult(RESULT_CANCELED);
@@ -105,106 +91,168 @@ public class AppPicker extends ListActivity {
}
}
- class MyApplicationInfo {
- ApplicationInfo info;
- CharSequence label;
- }
+ public static class AppPickerListFragment extends ListFragment {
+ private static final String EXTRA_PERMISSION_NAME = "extra_permission_name";
+ private static final String EXTRA_DEBUGGABLE_ONLY = "extra_debuggable_only";
+ private static final String EXTRA_NON_SYSTEM_ONLY = "extra_non_system_only";
+ private static final String EXTRA_INCLUDE_NOTHING = "extra_include_nothing";
- public class AppListAdapter extends ArrayAdapter {
- private final List mPackageInfoList = new ArrayList();
- private final LayoutInflater mInflater;
+ private String mPermissionName = "";
+ private boolean mDebuggableOnly;
+ private boolean mNonSystemOnly;
+ private boolean mIncludeNothing;
- public AppListAdapter(Context context) {
- super(context, 0);
- mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- List pkgs = context.getPackageManager().getInstalledApplications(0);
- for (int i=0; i {
+ private final List mPackageInfoList =
+ new ArrayList();
+ private final LayoutInflater mInflater;
+
+ public AppListAdapter(Context context) {
+ super(context, 0);
+ mInflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ List pkgs = context.getPackageManager().getInstalledApplications(
+ 0);
+ for (int i = 0; i < pkgs.size(); i++) {
+ ApplicationInfo ai = pkgs.get(i);
+ if (ai.uid == Process.SYSTEM_UID) {
+ continue;
+ }
+
+ // Filter out apps that are not debuggable if required.
+ if (mDebuggableOnly) {
+ // On a user build, we only allow debugging of apps that
+ // are marked as debuggable. Otherwise (for platform development)
+ // we allow all apps.
+ if ((ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0
+ && "user".equals(Build.TYPE)) {
+ continue;
+ }
+ }
+
+ // Filter out apps that are system apps if requested
+ if (mNonSystemOnly && ai.isSystemApp()) {
+ continue;
+ }
+
+ // Filter out apps that do not request the permission if required.
+ if (mPermissionName != null) {
+ boolean requestsPermission = false;
+ try {
+ PackageInfo pi = getContext().getPackageManager().getPackageInfo(
+ ai.packageName, PackageManager.GET_PERMISSIONS);
+ if (pi.requestedPermissions == null) {
+ continue;
+ }
+ for (String requestedPermission : pi.requestedPermissions) {
+ if (requestedPermission.equals(mPermissionName)) {
+ requestsPermission = true;
+ break;
+ }
+ }
+ if (!requestsPermission) {
+ continue;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ continue;
+ }
+ }
+
+ MyApplicationInfo info = new MyApplicationInfo();
+ info.info = ai;
+ info.label = info.info.loadLabel(getContext().getPackageManager()).toString();
+ mPackageInfoList.add(info);
+ }
+ Collections.sort(mPackageInfoList, sDisplayNameComparator);
+ if (mIncludeNothing) {
+ MyApplicationInfo info = new MyApplicationInfo();
+ info.label = context.getText(com.android.settingslib.R.string.no_application);
+ mPackageInfoList.add(0, info);
+ }
+ addAll(mPackageInfoList);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // A ViewHolder keeps references to children views to avoid unnecessary calls
+ // to findViewById() on each row.
+ AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
+ convertView = holder.rootView;
+ MyApplicationInfo info = getItem(position);
+ holder.appName.setText(info.label);
+ if (info.info != null) {
+ holder.appIcon.setImageDrawable(
+ info.info.loadIcon(getContext().getPackageManager()));
+ holder.summary.setText(info.info.packageName);
+ } else {
+ holder.appIcon.setImageDrawable(null);
+ holder.summary.setText("");
+ }
+ holder.disabled.setVisibility(View.GONE);
+ holder.widget.setVisibility(View.GONE);
+ return convertView;
+ }
+ }
+
+ private final static Comparator sDisplayNameComparator
+ = new Comparator() {
+ public final int
+ compare(MyApplicationInfo a, MyApplicationInfo b) {
+ return collator.compare(a.label, b.label);
+ }
+
+ private final Collator collator = Collator.getInstance();
+ };
}
-
- private final static Comparator sDisplayNameComparator
- = new Comparator() {
- public final int
- compare(MyApplicationInfo a, MyApplicationInfo b) {
- return collator.compare(a.label, b.label);
- }
-
- private final Collator collator = Collator.getInstance();
- };
}