1919import com.android.internal.R;
2020import com.android.internal.content.PackageMonitor;
2121
22+ import android.app.ActivityManager;
2223import android.content.ComponentName;
2324import android.content.Context;
24- import android.content.DialogInterface;
2525import android.content.Intent;
2626import android.content.IntentFilter;
2727import android.content.pm.ActivityInfo;
2828import android.content.pm.LabeledIntent;
2929import android.content.pm.PackageManager;
30+ import android.content.pm.PackageManager.NameNotFoundException;
3031import android.content.pm.ResolveInfo;
32+ import android.content.res.Resources;
3133import android.graphics.drawable.Drawable;
3234import android.net.Uri;
3335import android.os.Bundle;
3840import android.view.ViewGroup;
3941import android.widget.AdapterView;
4042import android.widget.BaseAdapter;
41- import android.widget.CheckBox ;
42- import android.widget.CompoundButton ;
43+ import android.widget.Button ;
44+ import android.widget.GridView ;
4345import android.widget.ImageView;
4446import android.widget.ListView;
4547import android.widget.TextView;
5658 * which there is more than one matching activity, allowing the user to decide
5759 * which to go to. It is not normally used directly by application developers.
5860 */
59- public class ResolverActivity extends AlertActivity implements
60- DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener {
61+ public class ResolverActivity extends AlertActivity implements AdapterView.OnItemClickListener {
62+ private static final String TAG = "ResolverActivity";
63+
6164 private ResolveListAdapter mAdapter;
62- private CheckBox mAlwaysCheck;
63- private TextView mClearDefaultHint;
6465 private PackageManager mPm;
66+ private boolean mAlwaysUseOption;
67+ private boolean mShowExtended;
68+ private GridView mGrid;
69+ private Button mAlwaysButton;
70+ private Button mOnceButton;
71+ private int mIconDpi;
72+ private int mIconSize;
73+
74+ private static final int MAX_COLUMNS = 4;
6575
6676 private boolean mRegistered;
6777 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@@ -91,49 +101,93 @@ protected void onCreate(Bundle savedInstanceState) {
91101 protected void onCreate(Bundle savedInstanceState, Intent intent,
92102 CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
93103 boolean alwaysUseOption) {
104+ setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
94105 super.onCreate(savedInstanceState);
95106 mPm = getPackageManager();
107+ mAlwaysUseOption = alwaysUseOption;
96108 intent.setComponent(null);
97109
98110 AlertController.AlertParams ap = mAlertParams;
99111
100112 ap.mTitle = title;
101- ap.mOnClickListener = this;
102113
103114 mPackageMonitor.register(this, getMainLooper(), false);
104115 mRegistered = true;
105116
106- if (alwaysUseOption) {
107- LayoutInflater inflater = (LayoutInflater) getSystemService(
108- Context.LAYOUT_INFLATER_SERVICE);
109- ap.mView = inflater.inflate(R.layout.always_use_checkbox, null);
110- mAlwaysCheck = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
111- mAlwaysCheck.setText(R.string.alwaysUse);
112- mAlwaysCheck.setOnCheckedChangeListener(this);
113- mClearDefaultHint = (TextView)ap.mView.findViewById(
114- com.android.internal.R.id.clearDefaultHint);
115- mClearDefaultHint.setVisibility(View.GONE);
116- }
117+ final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
118+ mIconDpi = am.getLauncherLargeIconDensity();
119+ mIconSize = am.getLauncherLargeIconSize();
120+
117121 mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList);
118122 int count = mAdapter.getCount();
119123 if (count > 1) {
120- ap.mAdapter = mAdapter;
124+ ap.mView = getLayoutInflater().inflate(R.layout.resolver_grid, null);
125+ mGrid = (GridView) ap.mView.findViewById(R.id.resolver_grid);
126+ mGrid.setAdapter(mAdapter);
127+ mGrid.setOnItemClickListener(this);
128+ mGrid.setOnItemLongClickListener(new ItemLongClickListener());
129+
130+ if (alwaysUseOption) {
131+ mGrid.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
132+ }
133+
134+ resizeGrid();
121135 } else if (count == 1) {
122136 startActivity(mAdapter.intentForPosition(0));
123137 mPackageMonitor.unregister();
124138 mRegistered = false;
125139 finish();
126140 return;
127141 } else {
128- ap.mMessage = getResources().getText(com.android.internal. R.string.noApplications);
142+ ap.mMessage = getResources().getText(R.string.noApplications);
129143 }
130144
131145 setupAlert();
132146
133- ListView lv = mAlert.getListView();
134- if (lv != null) {
135- lv.setOnItemLongClickListener(new ItemLongClickListener());
147+ if (alwaysUseOption) {
148+ final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar);
149+ buttonLayout.setVisibility(View.VISIBLE);
150+ mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
151+ mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
152+ }
153+ }
154+
155+ void resizeGrid() {
156+ final int itemCount = mAdapter.getCount();
157+ mGrid.setNumColumns(Math.min(itemCount, MAX_COLUMNS));
158+ }
159+
160+ Drawable getIcon(Resources res, int resId) {
161+ Drawable result;
162+ try {
163+ result = res.getDrawableForDensity(resId, mIconDpi);
164+ } catch (Resources.NotFoundException e) {
165+ result = null;
166+ }
167+
168+ return result;
169+ }
170+
171+ Drawable loadIconForResolveInfo(ResolveInfo ri) {
172+ Drawable dr;
173+ try {
174+ if (ri.resolvePackageName != null && ri.icon != 0) {
175+ dr = getIcon(mPm.getResourcesForApplication(ri.resolvePackageName), ri.icon);
176+ if (dr != null) {
177+ return dr;
178+ }
179+ }
180+ final int iconRes = ri.getIconResource();
181+ if (iconRes != 0) {
182+ dr = getIcon(mPm.getResourcesForApplication(ri.activityInfo.packageName), iconRes);
183+ if (dr != null) {
184+ return dr;
185+ }
186+ }
187+ } catch (NameNotFoundException e) {
188+ Log.e(TAG, "Couldn't find resources for package", e);
136189 }
190+ return ri.loadIcon(mPm);
137191 }
138192
139193 @Override
@@ -155,11 +209,28 @@ protected void onStop() {
155209 }
156210 }
157211
158- public void onClick(DialogInterface dialog, int which) {
212+ @Override
213+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
214+ if (mAlwaysUseOption) {
215+ final int checkedPos = mGrid.getCheckedItemPosition();
216+ final boolean enabled = checkedPos != GridView.INVALID_POSITION;
217+ mAlwaysButton.setEnabled(enabled);
218+ mOnceButton.setEnabled(enabled);
219+ } else {
220+ startSelected(position, false);
221+ }
222+ }
223+
224+ public void onButtonClick(View v) {
225+ final int id = v.getId();
226+ startSelected(mGrid.getCheckedItemPosition(), id == R.id.button_always);
227+ dismiss();
228+ }
229+
230+ void startSelected(int which, boolean always) {
159231 ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
160232 Intent intent = mAdapter.intentForPosition(which);
161- boolean alwaysCheck = (mAlwaysCheck != null && mAlwaysCheck.isChecked());
162- onIntentSelected(ri, intent, alwaysCheck);
233+ onIntentSelected(ri, intent, always);
163234 finish();
164235 }
165236
@@ -249,6 +320,12 @@ protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysChe
249320 }
250321 }
251322
323+ void showAppDetails(ResolveInfo ri) {
324+ Intent in = new Intent().setAction("android.settings.APPLICATION_DETAILS_SETTINGS")
325+ .setData(Uri.fromParts("package", ri.activityInfo.packageName, null));
326+ startActivity(in);
327+ }
328+
252329 private final class DisplayResolveInfo {
253330 ResolveInfo ri;
254331 CharSequence displayLabel;
@@ -285,12 +362,18 @@ public ResolveListAdapter(Context context, Intent intent,
285362 }
286363
287364 public void handlePackagesChanged() {
365+ final int oldItemCount = getCount();
288366 rebuildList();
289367 notifyDataSetChanged();
290368 if (mList.size() <= 0) {
291369 // We no longer have any items... just finish the activity.
292370 finish();
293371 }
372+
373+ final int newItemCount = getCount();
374+ if (newItemCount != oldItemCount) {
375+ resizeGrid();
376+ }
294377 }
295378
296379 private void rebuildList() {
@@ -299,7 +382,7 @@ private void rebuildList() {
299382 } else {
300383 mCurrentResolveList = mPm.queryIntentActivities(
301384 mIntent, PackageManager.MATCH_DEFAULT_ONLY
302- | (mAlwaysCheck != null ? PackageManager.GET_RESOLVED_FILTER : 0));
385+ | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0));
303386 }
304387 int N;
305388 if ((mCurrentResolveList != null) && ((N = mCurrentResolveList.size()) > 0)) {
@@ -363,6 +446,7 @@ private void rebuildList() {
363446 r0 = mCurrentResolveList.get(0);
364447 int start = 0;
365448 CharSequence r0Label = r0.loadLabel(mPm);
449+ mShowExtended = false;
366450 for (int i = 1; i < N; i++) {
367451 if (r0Label == null) {
368452 r0Label = r0.activityInfo.packageName;
@@ -393,6 +477,7 @@ private void processGroup(List<ResolveInfo> rList, int start, int end, ResolveIn
393477 // No duplicate labels. Use label for entry at start
394478 mList.add(new DisplayResolveInfo(ro, roLabel, null, null));
395479 } else {
480+ mShowExtended = true;
396481 boolean usePkg = false;
397482 CharSequence startApp = ro.activityInfo.applicationInfo.loadLabel(mPm);
398483 if (startApp == null) {
@@ -473,6 +558,11 @@ public View getView(int position, View convertView, ViewGroup parent) {
473558 if (convertView == null) {
474559 view = mInflater.inflate(
475560 com.android.internal.R.layout.resolve_list_item, parent, false);
561+
562+ // Fix the icon size even if we have different sized resources
563+ ImageView icon = (ImageView)view.findViewById(R.id.icon);
564+ ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
565+ lp.width = lp.height = mIconSize;
476566 } else {
477567 view = convertView;
478568 }
@@ -485,37 +575,25 @@ private final void bindView(View view, DisplayResolveInfo info) {
485575 TextView text2 = (TextView)view.findViewById(com.android.internal.R.id.text2);
486576 ImageView icon = (ImageView)view.findViewById(R.id.icon);
487577 text.setText(info.displayLabel);
488- if (info.extendedInfo != null ) {
578+ if (mShowExtended ) {
489579 text2.setVisibility(View.VISIBLE);
490580 text2.setText(info.extendedInfo);
491581 } else {
492582 text2.setVisibility(View.GONE);
493583 }
494584 if (info.displayIcon == null) {
495- info.displayIcon = info.ri.loadIcon(mPm );
585+ info.displayIcon = loadIconForResolveInfo( info.ri);
496586 }
497587 icon.setImageDrawable(info.displayIcon);
498588 }
499589 }
500590
501- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
502- if (mClearDefaultHint == null) return;
503-
504- if(isChecked) {
505- mClearDefaultHint.setVisibility(View.VISIBLE);
506- } else {
507- mClearDefaultHint.setVisibility(View.GONE);
508- }
509- }
510-
511591 class ItemLongClickListener implements AdapterView.OnItemLongClickListener {
512592
513593 @Override
514594 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
515595 ResolveInfo ri = mAdapter.resolveInfoForPosition(position);
516- Intent in = new Intent().setAction("android.settings.APPLICATION_DETAILS_SETTINGS")
517- .setData(Uri.fromParts("package", ri.activityInfo.packageName, null));
518- startActivity(in);
596+ showAppDetails(ri);
519597 return true;
520598 }
521599
0 commit comments