1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/* 2173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Copyright (C) 2009 The Android Open Source Project 3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License. 6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at 7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and 14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License. 15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */ 16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings; 18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 193418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guyimport android.graphics.ColorFilter; 20267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guyimport android.util.DisplayMetrics; 21173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport com.android.internal.app.AlertActivity; 22173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport com.android.internal.app.AlertController; 23173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 24173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.app.Activity; 25173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.Context; 26173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.DialogInterface; 27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent; 28173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.Intent.ShortcutIconResource; 29173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.pm.PackageManager; 30173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.pm.ResolveInfo; 31173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 32173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.res.Resources; 33173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Bitmap; 34173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Canvas; 35173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Paint; 36173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.PaintFlagsDrawFilter; 37173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.PixelFormat; 38173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Rect; 39173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.drawable.BitmapDrawable; 40173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.drawable.Drawable; 41173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.drawable.PaintDrawable; 42173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.os.Bundle; 43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Parcelable; 44173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.view.LayoutInflater; 45afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View; 46173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.view.ViewGroup; 47173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.widget.BaseAdapter; 48173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.widget.TextView; 49173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 50173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport java.util.ArrayList; 51173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport java.util.Collections; 52173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport java.util.List; 53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/** 55173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Displays a list of all activities matching the incoming 56173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link Intent#EXTRA_INTENT} query, along with any injected items. 57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */ 58173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeypublic class ActivityPicker extends AlertActivity implements 59173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey DialogInterface.OnClickListener, DialogInterface.OnCancelListener { 60173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 61173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 62173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Adapter of items that are displayed in this dialog. 63173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 64173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private PickAdapter mAdapter; 65173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 66173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 67173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Base {@link Intent} used when building list. 68173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 69173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private Intent mBaseIntent; 70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project @Override 72173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected void onCreate(Bundle savedInstanceState) { 73173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey super.onCreate(savedInstanceState); 74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 75173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey final Intent intent = getIntent(); 76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 77173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Read base intent from extras, otherwise assume default 78afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project Parcelable parcel = intent.getParcelableExtra(Intent.EXTRA_INTENT); 79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project if (parcel instanceof Intent) { 80173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mBaseIntent = (Intent) parcel; 81173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } else { 82173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mBaseIntent = new Intent(Intent.ACTION_MAIN, null); 83173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mBaseIntent.addCategory(Intent.CATEGORY_DEFAULT); 84afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 85173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 86173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Create dialog parameters 87173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey AlertController.AlertParams params = mAlertParams; 88173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mOnClickListener = this; 89173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mOnCancelListener = this; 90afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 91173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Use custom title if provided, otherwise default window title 92173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (intent.hasExtra(Intent.EXTRA_TITLE)) { 93173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mTitle = intent.getStringExtra(Intent.EXTRA_TITLE); 94173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } else { 95173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mTitle = getTitle(); 96173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 97173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 98173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Build list adapter of pickable items 99173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey List<PickAdapter.Item> items = getItems(); 100173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mAdapter = new PickAdapter(this, items); 101173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mAdapter = mAdapter; 102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 103173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey setupAlert(); 104173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 105173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 106173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 107173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Handle clicking of dialog item by passing back 108173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link #getIntentForPosition(int)} in {@link #setResult(int, Intent)}. 109173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 110173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public void onClick(DialogInterface dialog, int which) { 111173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Intent intent = getIntentForPosition(which); 112173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey setResult(Activity.RESULT_OK, intent); 113173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey finish(); 114173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 115173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 116173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 117173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Handle canceled dialog by passing back {@link Activity#RESULT_CANCELED}. 118173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 119173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public void onCancel(DialogInterface dialog) { 120173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey setResult(Activity.RESULT_CANCELED); 121afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project finish(); 122afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 123afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 124173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 125173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Build the specific {@link Intent} for a given list position. Convenience 126173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * method that calls through to {@link PickAdapter.Item#getIntent(Intent)}. 127173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 128173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected Intent getIntentForPosition(int position) { 129173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey PickAdapter.Item item = (PickAdapter.Item) mAdapter.getItem(position); 130173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return item.getIntent(mBaseIntent); 131173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 132173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 133173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 134173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Build and return list of items to be shown in dialog. Default 135173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * implementation mixes activities matching {@link #mBaseIntent} from 136173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link #putIntentItems(Intent, List)} with any injected items from 137173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link Intent#EXTRA_SHORTCUT_NAME}. Override this method in subclasses to 138173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * change the items shown. 139173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 140173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected List<PickAdapter.Item> getItems() { 141173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey PackageManager packageManager = getPackageManager(); 142173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey List<PickAdapter.Item> items = new ArrayList<PickAdapter.Item>(); 143173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 144173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Add any injected pick items 145173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey final Intent intent = getIntent(); 146173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ArrayList<String> labels = 147173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.getStringArrayListExtra(Intent.EXTRA_SHORTCUT_NAME); 148173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ArrayList<ShortcutIconResource> icons = 149173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.getParcelableArrayListExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 150173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 151173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (labels != null && icons != null && labels.size() == icons.size()) { 152173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey for (int i = 0; i < labels.size(); i++) { 153173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey String label = labels.get(i); 154173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Drawable icon = null; 155173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 156173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey try { 157173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Try loading icon from requested package 158173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ShortcutIconResource iconResource = icons.get(i); 159173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Resources res = packageManager.getResourcesForApplication( 160173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey iconResource.packageName); 161173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey icon = res.getDrawable(res.getIdentifier( 162173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey iconResource.resourceName, null, null)); 163173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } catch (NameNotFoundException e) { 164267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy // Ignore 165173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 166173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 167173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey items.add(new PickAdapter.Item(this, label, icon)); 168173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 169173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 170173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 171173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Add any intent items if base was given 172173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (mBaseIntent != null) { 173173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey putIntentItems(mBaseIntent, items); 174173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 175173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 176173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return items; 177173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 178173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 179173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 180173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Fill the given list with any activities matching the base {@link Intent}. 181173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 182173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected void putIntentItems(Intent baseIntent, List<PickAdapter.Item> items) { 183173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey PackageManager packageManager = getPackageManager(); 184173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey List<ResolveInfo> list = packageManager.queryIntentActivities(baseIntent, 185173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 0 /* no flags */); 186173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager)); 187173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 188173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey final int listSize = list.size(); 189173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey for (int i = 0; i < listSize; i++) { 190173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ResolveInfo resolveInfo = list.get(i); 191173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey items.add(new PickAdapter.Item(this, packageManager, resolveInfo)); 192173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 193173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 194173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 195173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 196173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Adapter which shows the set of activities that can be performed for a 197173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * given {@link Intent}. 198173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 199173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected static class PickAdapter extends BaseAdapter { 200173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 201173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 202173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Item that appears in a {@link PickAdapter} list. 203173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 2040b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka public static class Item implements AppWidgetLoader.LabelledItem { 205173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected static IconResizer sResizer; 206173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 207173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected IconResizer getResizer(Context context) { 208173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (sResizer == null) { 209267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy final Resources resources = context.getResources(); 210267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy int size = (int) resources.getDimension(android.R.dimen.app_icon_size); 211267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy sResizer = new IconResizer(size, size, resources.getDisplayMetrics()); 212173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 213173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return sResizer; 214173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 215173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 216173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey CharSequence label; 217173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Drawable icon; 218173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey String packageName; 219173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey String className; 220173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Bundle extras; 221173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 222173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 223173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Create a list item from given label and icon. 224173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 225173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Item(Context context, CharSequence label, Drawable icon) { 226173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey this.label = label; 227173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey this.icon = getResizer(context).createIconThumbnail(icon); 228173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 229173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 230173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 231173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Create a list item and fill it with details from the given 232173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link ResolveInfo} object. 233173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 234173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Item(Context context, PackageManager pm, ResolveInfo resolveInfo) { 235173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey label = resolveInfo.loadLabel(pm); 236173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (label == null && resolveInfo.activityInfo != null) { 237173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey label = resolveInfo.activityInfo.name; 238173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 239267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy 240173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey icon = getResizer(context).createIconThumbnail(resolveInfo.loadIcon(pm)); 241173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey packageName = resolveInfo.activityInfo.applicationInfo.packageName; 242173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey className = resolveInfo.activityInfo.name; 243173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 244267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy 245173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 246173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Build the {@link Intent} described by this item. If this item 247267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy * can't create a valid {@link android.content.ComponentName}, it will return 248173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link Intent#ACTION_CREATE_SHORTCUT} filled with the item label. 249173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 250173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Intent getIntent(Intent baseIntent) { 251173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Intent intent = new Intent(baseIntent); 252173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (packageName != null && className != null) { 253173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Valid package and class, so fill details as normal intent 254173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.setClassName(packageName, className); 255173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (extras != null) { 256173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.putExtras(extras); 257173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 258173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } else { 259173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // No valid package or class, so treat as shortcut with label 260173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.setAction(Intent.ACTION_CREATE_SHORTCUT); 261173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label); 262173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 263173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return intent; 264173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 2650b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka 2660b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka public CharSequence getLabel() { 2670b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka return label; 2680b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka } 269173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 270173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 271173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private final LayoutInflater mInflater; 272267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final List<Item> mItems; 273173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 274173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 275173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Create an adapter for the given items. 276173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 277173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public PickAdapter(Context context, List<Item> items) { 278267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 279173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mItems = items; 280173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 281173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 282173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 283173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 284173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 285173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public int getCount() { 286173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return mItems.size(); 287173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 288173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 289173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 290173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 291173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 292173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public Object getItem(int position) { 293173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return mItems.get(position); 294173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 295173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 296173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 297173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 298173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 299173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public long getItemId(int position) { 300173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return position; 301173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 302173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 303173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 304173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 305173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 306173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public View getView(int position, View convertView, ViewGroup parent) { 307173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (convertView == null) { 308267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy convertView = mInflater.inflate(R.layout.pick_item, parent, false); 309173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 310173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 311173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Item item = (Item) getItem(position); 312173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey TextView textView = (TextView) convertView; 313173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey textView.setText(item.label); 314173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey textView.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null); 315173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 316173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return convertView; 317173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 318173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 319173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 320173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 321173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Utility class to resize icons to match default icon size. Code is mostly 322173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * borrowed from Launcher. 323173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 324173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private static class IconResizer { 325267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final int mIconWidth; 326267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final int mIconHeight; 327173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 328267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final DisplayMetrics mMetrics; 329173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private final Rect mOldBounds = new Rect(); 330267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final Canvas mCanvas = new Canvas(); 331173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 332267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy public IconResizer(int width, int height, DisplayMetrics metrics) { 333173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 334173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Paint.FILTER_BITMAP_FLAG)); 335267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy 336267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mMetrics = metrics; 337267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mIconWidth = width; 338267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mIconHeight = height; 339173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 340173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 341173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 342173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Returns a Drawable representing the thumbnail of the specified Drawable. 343173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * The size of the thumbnail is defined by the dimension 344173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * android.R.dimen.launcher_application_icon_size. 345173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * 346173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * This method is not thread-safe and should be invoked on the UI thread only. 347173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * 348173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * @param icon The icon to get a thumbnail of. 349173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * 350173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * @return A thumbnail for the specified icon or the icon itself if the 351173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * thumbnail could not be created. 352173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 353173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public Drawable createIconThumbnail(Drawable icon) { 354173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey int width = mIconWidth; 355173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey int height = mIconHeight; 356173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 3573418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (icon == null) { 3583418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return new EmptyDrawable(width, height); 359173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 3603418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3613418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy try { 3623418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (icon instanceof PaintDrawable) { 3633418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy PaintDrawable painter = (PaintDrawable) icon; 3643418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy painter.setIntrinsicWidth(width); 3653418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy painter.setIntrinsicHeight(height); 3663418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } else if (icon instanceof BitmapDrawable) { 3673418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // Ensure the bitmap has a density. 3683418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 3693418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy Bitmap bitmap = bitmapDrawable.getBitmap(); 3703418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 3713418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy bitmapDrawable.setTargetDensity(mMetrics); 372173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 373173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 3743418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy int iconWidth = icon.getIntrinsicWidth(); 3753418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy int iconHeight = icon.getIntrinsicHeight(); 3763418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3773418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (iconWidth > 0 && iconHeight > 0) { 3783418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (width < iconWidth || height < iconHeight) { 3793418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final float ratio = (float) iconWidth / iconHeight; 3803418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3813418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (iconWidth > iconHeight) { 3823418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy height = (int) (width / ratio); 3833418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } else if (iconHeight > iconWidth) { 3843418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy width = (int) (height * ratio); 3853418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 3863418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3873418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ? 3883418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; 3893418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c); 3903418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Canvas canvas = mCanvas; 3913418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy canvas.setBitmap(thumb); 3923418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // Copy the old bounds to restore them later 3933418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // If we were to do oldBounds = icon.getBounds(), 3943418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // the call to setBounds() that follows would 3953418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // change the same instance and we would lose the 3963418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // old bounds 3973418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mOldBounds.set(icon.getBounds()); 3983418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int x = (mIconWidth - width) / 2; 3993418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int y = (mIconHeight - height) / 2; 4003418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(x, y, x + width, y + height); 4013418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.draw(canvas); 4023418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(mOldBounds); 4033418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy //noinspection deprecation 4043418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon = new BitmapDrawable(thumb); 4053418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy ((BitmapDrawable) icon).setTargetDensity(mMetrics); 406419740de685fecb03a996132508e3fa9d4932383Dianne Hackborn canvas.setBitmap(null); 4073418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } else if (iconWidth < width && iconHeight < height) { 4083418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap.Config c = Bitmap.Config.ARGB_8888; 4093418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c); 4103418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Canvas canvas = mCanvas; 4113418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy canvas.setBitmap(thumb); 4123418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mOldBounds.set(icon.getBounds()); 4133418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int x = (width - iconWidth) / 2; 4143418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int y = (height - iconHeight) / 2; 4153418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(x, y, x + iconWidth, y + iconHeight); 4163418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.draw(canvas); 4173418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(mOldBounds); 4183418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy //noinspection deprecation 4193418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon = new BitmapDrawable(thumb); 4203418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy ((BitmapDrawable) icon).setTargetDensity(mMetrics); 421419740de685fecb03a996132508e3fa9d4932383Dianne Hackborn canvas.setBitmap(null); 4223418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4233418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4243418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4253418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } catch (Throwable t) { 4263418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon = new EmptyDrawable(width, height); 427173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 428173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 429173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return icon; 430173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 431173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 4323418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4333418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy private static class EmptyDrawable extends Drawable { 4343418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy private final int mWidth; 4353418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy private final int mHeight; 4363418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4373418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy EmptyDrawable(int width, int height) { 4383418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mWidth = width; 4393418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mHeight = height; 4403418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4413418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4423418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4433418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getIntrinsicWidth() { 4443418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mWidth; 4453418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4463418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4473418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4483418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getIntrinsicHeight() { 4493418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mHeight; 4503418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4513418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4523418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4533418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getMinimumWidth() { 4543418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mWidth; 4553418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4563418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4573418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4583418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getMinimumHeight() { 4593418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mHeight; 4603418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4613418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4623418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4633418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public void draw(Canvas canvas) { 4643418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4653418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4663418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4673418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public void setAlpha(int alpha) { 4683418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4693418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4703418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4713418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public void setColorFilter(ColorFilter cf) { 4723418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4733418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4743418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4753418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getOpacity() { 4763418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return PixelFormat.TRANSLUCENT; 4773418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4780b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka } 479afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project} 480