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 19173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.app.Activity; 20173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.Context; 21173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.DialogInterface; 22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent; 23173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.Intent.ShortcutIconResource; 24173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.pm.PackageManager; 25173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 2639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.content.pm.ResolveInfo; 27173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.content.res.Resources; 28173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Bitmap; 29173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Canvas; 3039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.graphics.ColorFilter; 31173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Paint; 32173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.PaintFlagsDrawFilter; 33173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.PixelFormat; 34173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.Rect; 35173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.drawable.BitmapDrawable; 36173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.drawable.Drawable; 37173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.graphics.drawable.PaintDrawable; 38173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.os.Bundle; 39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Parcelable; 4039b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.util.DisplayMetrics; 41173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.view.LayoutInflater; 42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View; 43173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.view.ViewGroup; 44173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.widget.BaseAdapter; 45173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkeyimport android.widget.TextView; 46173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 4739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.app.AlertActivity; 4839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport com.android.internal.app.AlertController; 4939b467482d1bf256a111c757e9b7621c6f523271Jason Monk 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; 813f218e8431cb5648bcb46131551c133ba53ef870Jeff Sharkey mBaseIntent.setFlags(mBaseIntent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION 823f218e8431cb5648bcb46131551c133ba53ef870Jeff Sharkey | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 833f218e8431cb5648bcb46131551c133ba53ef870Jeff Sharkey | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 843f218e8431cb5648bcb46131551c133ba53ef870Jeff Sharkey | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)); 85173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } else { 86173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mBaseIntent = new Intent(Intent.ACTION_MAIN, null); 87173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mBaseIntent.addCategory(Intent.CATEGORY_DEFAULT); 88afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 89173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 90173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Create dialog parameters 91173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey AlertController.AlertParams params = mAlertParams; 92173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mOnClickListener = this; 93173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mOnCancelListener = this; 94afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 95173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Use custom title if provided, otherwise default window title 96173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (intent.hasExtra(Intent.EXTRA_TITLE)) { 97173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mTitle = intent.getStringExtra(Intent.EXTRA_TITLE); 98173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } else { 99173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mTitle = getTitle(); 100173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 101173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 102173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Build list adapter of pickable items 103173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey List<PickAdapter.Item> items = getItems(); 104173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mAdapter = new PickAdapter(this, items); 105173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey params.mAdapter = mAdapter; 106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 107173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey setupAlert(); 108173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 109173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 110173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 111173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Handle clicking of dialog item by passing back 112173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link #getIntentForPosition(int)} in {@link #setResult(int, Intent)}. 113173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 114173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public void onClick(DialogInterface dialog, int which) { 115173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Intent intent = getIntentForPosition(which); 116173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey setResult(Activity.RESULT_OK, intent); 117173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey finish(); 118173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 119173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 120173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 121173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Handle canceled dialog by passing back {@link Activity#RESULT_CANCELED}. 122173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 123173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public void onCancel(DialogInterface dialog) { 124173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey setResult(Activity.RESULT_CANCELED); 125afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project finish(); 126afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 127afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 128173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 129173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Build the specific {@link Intent} for a given list position. Convenience 130173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * method that calls through to {@link PickAdapter.Item#getIntent(Intent)}. 131173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 132173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected Intent getIntentForPosition(int position) { 133173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey PickAdapter.Item item = (PickAdapter.Item) mAdapter.getItem(position); 134173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return item.getIntent(mBaseIntent); 135173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 136173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 137173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 138173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Build and return list of items to be shown in dialog. Default 139173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * implementation mixes activities matching {@link #mBaseIntent} from 140173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link #putIntentItems(Intent, List)} with any injected items from 141173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link Intent#EXTRA_SHORTCUT_NAME}. Override this method in subclasses to 142173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * change the items shown. 143173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 144173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected List<PickAdapter.Item> getItems() { 145173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey PackageManager packageManager = getPackageManager(); 146173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey List<PickAdapter.Item> items = new ArrayList<PickAdapter.Item>(); 147173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 148173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Add any injected pick items 149173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey final Intent intent = getIntent(); 150173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ArrayList<String> labels = 151173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.getStringArrayListExtra(Intent.EXTRA_SHORTCUT_NAME); 152173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ArrayList<ShortcutIconResource> icons = 153173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.getParcelableArrayListExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 154173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 155173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (labels != null && icons != null && labels.size() == icons.size()) { 156173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey for (int i = 0; i < labels.size(); i++) { 157173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey String label = labels.get(i); 158173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Drawable icon = null; 159173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 160173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey try { 161173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Try loading icon from requested package 162173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ShortcutIconResource iconResource = icons.get(i); 163173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Resources res = packageManager.getResourcesForApplication( 164173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey iconResource.packageName); 165173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey icon = res.getDrawable(res.getIdentifier( 1660ba89bd54c4b44b3803342da10b0c08b0bf76ad4Alan Viverette iconResource.resourceName, null, null), null); 167173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } catch (NameNotFoundException e) { 168267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy // Ignore 169173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 170173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 171173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey items.add(new PickAdapter.Item(this, label, icon)); 172173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 173173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 174173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 175173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Add any intent items if base was given 176173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (mBaseIntent != null) { 177173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey putIntentItems(mBaseIntent, items); 178173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 179173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 180173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return items; 181173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 182173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 183173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 184173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Fill the given list with any activities matching the base {@link Intent}. 185173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 186173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected void putIntentItems(Intent baseIntent, List<PickAdapter.Item> items) { 187173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey PackageManager packageManager = getPackageManager(); 188173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey List<ResolveInfo> list = packageManager.queryIntentActivities(baseIntent, 189173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 0 /* no flags */); 190173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager)); 191173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 192173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey final int listSize = list.size(); 193173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey for (int i = 0; i < listSize; i++) { 194173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey ResolveInfo resolveInfo = list.get(i); 195173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey items.add(new PickAdapter.Item(this, packageManager, resolveInfo)); 196173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 197173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 198173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 199173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 200173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Adapter which shows the set of activities that can be performed for a 201173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * given {@link Intent}. 202173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 203173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected static class PickAdapter extends BaseAdapter { 204173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 205173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 206173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Item that appears in a {@link PickAdapter} list. 207173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 2080b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka public static class Item implements AppWidgetLoader.LabelledItem { 209173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected static IconResizer sResizer; 210173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 211173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey protected IconResizer getResizer(Context context) { 212173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (sResizer == null) { 213267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy final Resources resources = context.getResources(); 214267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy int size = (int) resources.getDimension(android.R.dimen.app_icon_size); 215267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy sResizer = new IconResizer(size, size, resources.getDisplayMetrics()); 216173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 217173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return sResizer; 218173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 219173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 220173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey CharSequence label; 221173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Drawable icon; 222173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey String packageName; 223173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey String className; 224173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Bundle extras; 225173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 226173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 227173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Create a list item from given label and icon. 228173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 229173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Item(Context context, CharSequence label, Drawable icon) { 230173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey this.label = label; 231173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey this.icon = getResizer(context).createIconThumbnail(icon); 232173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 233173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 234173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 235173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Create a list item and fill it with details from the given 236173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link ResolveInfo} object. 237173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 238173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Item(Context context, PackageManager pm, ResolveInfo resolveInfo) { 239173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey label = resolveInfo.loadLabel(pm); 240173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (label == null && resolveInfo.activityInfo != null) { 241173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey label = resolveInfo.activityInfo.name; 242173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 243267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy 244173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey icon = getResizer(context).createIconThumbnail(resolveInfo.loadIcon(pm)); 245173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey packageName = resolveInfo.activityInfo.applicationInfo.packageName; 246173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey className = resolveInfo.activityInfo.name; 247173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 248267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy 249173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 250173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Build the {@link Intent} described by this item. If this item 251267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy * can't create a valid {@link android.content.ComponentName}, it will return 252173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@link Intent#ACTION_CREATE_SHORTCUT} filled with the item label. 253173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 254173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Intent getIntent(Intent baseIntent) { 255173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Intent intent = new Intent(baseIntent); 256173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (packageName != null && className != null) { 257173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // Valid package and class, so fill details as normal intent 258173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.setClassName(packageName, className); 259173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (extras != null) { 260173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.putExtras(extras); 261173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 262173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } else { 263173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey // No valid package or class, so treat as shortcut with label 264173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.setAction(Intent.ACTION_CREATE_SHORTCUT); 265173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label); 266173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 267173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return intent; 268173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 2690b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka 2700b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka public CharSequence getLabel() { 2710b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka return label; 2720b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka } 273173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 274173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 275173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private final LayoutInflater mInflater; 276267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final List<Item> mItems; 277173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 278173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 279173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Create an adapter for the given items. 280173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 281173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public PickAdapter(Context context, List<Item> items) { 282267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 283173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mItems = items; 284173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 285173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 286173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 287173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 288173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 289173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public int getCount() { 290173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return mItems.size(); 291173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 292173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 293173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 294173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 295173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 296173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public Object getItem(int position) { 297173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return mItems.get(position); 298173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 299173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 300173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 301173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 302173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 303173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public long getItemId(int position) { 304173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return position; 305173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 306173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 307173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 308173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * {@inheritDoc} 309173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 310173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public View getView(int position, View convertView, ViewGroup parent) { 311173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey if (convertView == null) { 312267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy convertView = mInflater.inflate(R.layout.pick_item, parent, false); 313173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 314173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 315173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Item item = (Item) getItem(position); 316173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey TextView textView = (TextView) convertView; 317173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey textView.setText(item.label); 318173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey textView.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null); 319173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 320173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return convertView; 321173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 322173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 323173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 324173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 325173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Utility class to resize icons to match default icon size. Code is mostly 326173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * borrowed from Launcher. 327173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 328173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private static class IconResizer { 329267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final int mIconWidth; 330267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final int mIconHeight; 331173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 332267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final DisplayMetrics mMetrics; 333173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey private final Rect mOldBounds = new Rect(); 334267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy private final Canvas mCanvas = new Canvas(); 335173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 336267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy public IconResizer(int width, int height, DisplayMetrics metrics) { 337173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 338173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey Paint.FILTER_BITMAP_FLAG)); 339267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy 340267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mMetrics = metrics; 341267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mIconWidth = width; 342267a47e683f744e4d77b9aa6aec017e5068bb443Romain Guy mIconHeight = height; 343173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 344173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 345173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey /** 346173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * Returns a Drawable representing the thumbnail of the specified Drawable. 347173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * The size of the thumbnail is defined by the dimension 348173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * android.R.dimen.launcher_application_icon_size. 349173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * 350173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * This method is not thread-safe and should be invoked on the UI thread only. 351173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * 352173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * @param icon The icon to get a thumbnail of. 353173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * 354173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * @return A thumbnail for the specified icon or the icon itself if the 355173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey * thumbnail could not be created. 356173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey */ 357173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey public Drawable createIconThumbnail(Drawable icon) { 358173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey int width = mIconWidth; 359173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey int height = mIconHeight; 360173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 3613418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (icon == null) { 3623418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return new EmptyDrawable(width, height); 363173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 3643418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3653418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy try { 3663418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (icon instanceof PaintDrawable) { 3673418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy PaintDrawable painter = (PaintDrawable) icon; 3683418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy painter.setIntrinsicWidth(width); 3693418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy painter.setIntrinsicHeight(height); 3703418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } else if (icon instanceof BitmapDrawable) { 3713418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // Ensure the bitmap has a density. 3723418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 3733418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy Bitmap bitmap = bitmapDrawable.getBitmap(); 3743418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 3753418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy bitmapDrawable.setTargetDensity(mMetrics); 376173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 377173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 3783418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy int iconWidth = icon.getIntrinsicWidth(); 3793418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy int iconHeight = icon.getIntrinsicHeight(); 3803418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3813418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (iconWidth > 0 && iconHeight > 0) { 3823418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (width < iconWidth || height < iconHeight) { 3833418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final float ratio = (float) iconWidth / iconHeight; 3843418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3853418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy if (iconWidth > iconHeight) { 3863418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy height = (int) (width / ratio); 3873418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } else if (iconHeight > iconWidth) { 3883418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy width = (int) (height * ratio); 3893418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 3903418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 3913418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ? 3923418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; 3933418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c); 3943418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Canvas canvas = mCanvas; 3953418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy canvas.setBitmap(thumb); 3963418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // Copy the old bounds to restore them later 3973418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // If we were to do oldBounds = icon.getBounds(), 3983418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // the call to setBounds() that follows would 3993418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // change the same instance and we would lose the 4003418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy // old bounds 4013418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mOldBounds.set(icon.getBounds()); 4023418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int x = (mIconWidth - width) / 2; 4033418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int y = (mIconHeight - height) / 2; 4043418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(x, y, x + width, y + height); 4053418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.draw(canvas); 4063418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(mOldBounds); 4073418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy //noinspection deprecation 4083418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon = new BitmapDrawable(thumb); 4093418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy ((BitmapDrawable) icon).setTargetDensity(mMetrics); 410419740de685fecb03a996132508e3fa9d4932383Dianne Hackborn canvas.setBitmap(null); 4113418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } else if (iconWidth < width && iconHeight < height) { 4123418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap.Config c = Bitmap.Config.ARGB_8888; 4133418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c); 4143418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final Canvas canvas = mCanvas; 4153418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy canvas.setBitmap(thumb); 4163418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mOldBounds.set(icon.getBounds()); 4173418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int x = (width - iconWidth) / 2; 4183418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy final int y = (height - iconHeight) / 2; 4193418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(x, y, x + iconWidth, y + iconHeight); 4203418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.draw(canvas); 4213418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon.setBounds(mOldBounds); 4223418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy //noinspection deprecation 4233418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon = new BitmapDrawable(thumb); 4243418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy ((BitmapDrawable) icon).setTargetDensity(mMetrics); 425419740de685fecb03a996132508e3fa9d4932383Dianne Hackborn canvas.setBitmap(null); 4263418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4273418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4283418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4293418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } catch (Throwable t) { 4303418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy icon = new EmptyDrawable(width, height); 431173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 432173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey 433173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey return icon; 434173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 435173545e63b5078d9d0e194552e39bb5e9f358082Jeffrey Sharkey } 4363418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4373418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy private static class EmptyDrawable extends Drawable { 4383418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy private final int mWidth; 4393418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy private final int mHeight; 4403418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4413418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy EmptyDrawable(int width, int height) { 4423418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mWidth = width; 4433418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy mHeight = height; 4443418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4453418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4463418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4473418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getIntrinsicWidth() { 4483418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mWidth; 4493418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4503418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4513418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4523418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getIntrinsicHeight() { 4533418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mHeight; 4543418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4553418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4563418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4573418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getMinimumWidth() { 4583418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mWidth; 4593418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4603418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4613418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4623418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getMinimumHeight() { 4633418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return mHeight; 4643418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4653418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4663418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4673418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public void draw(Canvas canvas) { 4683418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4693418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4703418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4713418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public void setAlpha(int alpha) { 4723418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4733418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4743418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4753418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public void setColorFilter(ColorFilter cf) { 4763418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4773418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy 4783418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy @Override 4793418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy public int getOpacity() { 4803418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy return PixelFormat.TRANSLUCENT; 4813418cb4df5c1ada031ca06d84374abe6a16e6dd3Romain Guy } 4820b2bd8d11d6947a6ce71db0691ba341aec7a2964Michael Jurka } 483afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project} 484