1ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng/* 2ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Copyright (C) 2010 The Android Open Source Project 3ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * 4ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * you may not use this file except in compliance with the License. 6ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * You may obtain a copy of the License at 7ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * 8ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 9ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * 10ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Unless required by applicable law or agreed to in writing, software 11ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * See the License for the specific language governing permissions and 14ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * limitations under the License. 15ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 16ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengpackage com.android.contacts.common.list; 17ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 18ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.app.ActivityManager; 19ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.ContentResolver; 20ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.Context; 21ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.Intent; 22ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.content.res.Resources; 23ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.database.Cursor; 24ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.Bitmap; 25ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.BitmapFactory; 26ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.Canvas; 27ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.Paint; 28ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.Paint.FontMetricsInt; 29ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.Rect; 30ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.drawable.BitmapDrawable; 31ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.graphics.drawable.Drawable; 32ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.net.Uri; 33ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.os.AsyncTask; 34ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract; 35ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract.CommonDataKinds.Phone; 36ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract.CommonDataKinds.Photo; 37ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract.Contacts; 38ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.provider.ContactsContract.Data; 39ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.text.TextPaint; 40ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.text.TextUtils; 41ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport android.text.TextUtils.TruncateAt; 42ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 43ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.CallUtil; 44ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengimport com.android.contacts.common.R; 45ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 46ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng/** 47ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Constructs shortcut intents. 48ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 49ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Chengpublic class ShortcutIntentBuilder { 50ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 51ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final String[] CONTACT_COLUMNS = { 52ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Contacts.DISPLAY_NAME, 53ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Contacts.PHOTO_ID, 54ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }; 55ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 56ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int CONTACT_DISPLAY_NAME_COLUMN_INDEX = 0; 57ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int CONTACT_PHOTO_ID_COLUMN_INDEX = 1; 58ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 59ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final String[] PHONE_COLUMNS = { 60ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Phone.DISPLAY_NAME, 61ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Phone.PHOTO_ID, 62ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Phone.NUMBER, 63ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Phone.TYPE, 64ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Phone.LABEL 65ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }; 66ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 67ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int PHONE_DISPLAY_NAME_COLUMN_INDEX = 0; 68ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int PHONE_PHOTO_ID_COLUMN_INDEX = 1; 69ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int PHONE_NUMBER_COLUMN_INDEX = 2; 70ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int PHONE_TYPE_COLUMN_INDEX = 3; 71ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int PHONE_LABEL_COLUMN_INDEX = 4; 72ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 73ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final String[] PHOTO_COLUMNS = { 74ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Photo.PHOTO, 75ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng }; 76ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 77ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final int PHOTO_PHOTO_COLUMN_INDEX = 0; 78ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 79ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private static final String PHOTO_SELECTION = Photo._ID + "=?"; 80ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 81ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final OnShortcutIntentCreatedListener mListener; 82ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final Context mContext; 83ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private int mIconSize; 84ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final int mIconDensity; 85ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final int mBorderWidth; 86ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final int mBorderColor; 87ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 88ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 89ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * This is a hidden API of the launcher in JellyBean that allows us to disable the animation 90ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * that it would usually do, because it interferes with our own animation for QuickContact 91ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 92ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION = 93ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng "com.android.launcher.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION"; 94ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 95ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 96ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Listener interface. 97ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 98ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public interface OnShortcutIntentCreatedListener { 99ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 100ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 101ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Callback for shortcut intent creation. 102ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * 103ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * @param uri the original URI for which the shortcut intent has been 104ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * created. 105ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * @param shortcutIntent resulting shortcut intent. 106ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 107ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng void onShortcutIntentCreated(Uri uri, Intent shortcutIntent); 108ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 109ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 110ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public ShortcutIntentBuilder(Context context, OnShortcutIntentCreatedListener listener) { 111ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mContext = context; 112ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mListener = listener; 113ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 114ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Resources r = context.getResources(); 115ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final ActivityManager am = (ActivityManager) context 116ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .getSystemService(Context.ACTIVITY_SERVICE); 117ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mIconSize = r.getDimensionPixelSize(R.dimen.shortcut_icon_size); 118ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mIconSize == 0) { 119ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mIconSize = am.getLauncherLargeIconSize(); 120ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 121ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mIconDensity = am.getLauncherLargeIconDensity(); 122ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mBorderWidth = r.getDimensionPixelOffset( 123ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.dimen.shortcut_icon_border_width); 124ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mBorderColor = r.getColor(R.color.shortcut_overlay_text_background); 125ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 126ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 127ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void createContactShortcutIntent(Uri contactUri) { 128ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng new ContactLoadingAsyncTask(contactUri).execute(); 129ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 130ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 131ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public void createPhoneNumberShortcutIntent(Uri dataUri, String shortcutAction) { 132ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng new PhoneNumberLoadingAsyncTask(dataUri, shortcutAction).execute(); 133ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 134ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 135ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 136ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * An asynchronous task that loads name, photo and other data from the database. 137ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 138ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private abstract class LoadingAsyncTask extends AsyncTask<Void, Void, Void> { 139ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected Uri mUri; 140ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected String mContentType; 141ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected String mDisplayName; 142ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected byte[] mBitmapData; 143ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected long mPhotoId; 144ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 145ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public LoadingAsyncTask(Uri uri) { 146ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mUri = uri; 147ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 148ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 149ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 150ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected Void doInBackground(Void... params) { 151ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mContentType = mContext.getContentResolver().getType(mUri); 152ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng loadData(); 153ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng loadPhoto(); 154ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return null; 155ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 156ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 157ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected abstract void loadData(); 158ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 159ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private void loadPhoto() { 160ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (mPhotoId == 0) { 161ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return; 162ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 163ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 164ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ContentResolver resolver = mContext.getContentResolver(); 165ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Cursor cursor = resolver.query(Data.CONTENT_URI, PHOTO_COLUMNS, PHOTO_SELECTION, 166ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng new String[] { String.valueOf(mPhotoId) }, null); 167ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor != null) { 168ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng try { 169ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor.moveToFirst()) { 170ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mBitmapData = cursor.getBlob(PHOTO_PHOTO_COLUMN_INDEX); 171ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 172ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } finally { 173ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng cursor.close(); 174ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 175ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 176ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 177ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 178ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 179ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final class ContactLoadingAsyncTask extends LoadingAsyncTask { 180ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public ContactLoadingAsyncTask(Uri uri) { 181ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super(uri); 182ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 183ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 184ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 185ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void loadData() { 186ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ContentResolver resolver = mContext.getContentResolver(); 187ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Cursor cursor = resolver.query(mUri, CONTACT_COLUMNS, null, null, null); 188ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor != null) { 189ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng try { 190ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor.moveToFirst()) { 191ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mDisplayName = cursor.getString(CONTACT_DISPLAY_NAME_COLUMN_INDEX); 192ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mPhotoId = cursor.getLong(CONTACT_PHOTO_ID_COLUMN_INDEX); 193ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 194ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } finally { 195ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng cursor.close(); 196ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 197ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 198ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 199ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 200ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onPostExecute(Void result) { 201ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng createContactShortcutIntent(mUri, mContentType, mDisplayName, mBitmapData); 202ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 203ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 204ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 205ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final class PhoneNumberLoadingAsyncTask extends LoadingAsyncTask { 206ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private final String mShortcutAction; 207ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private String mPhoneNumber; 208ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private int mPhoneType; 209ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private String mPhoneLabel; 210ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 211ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng public PhoneNumberLoadingAsyncTask(Uri uri, String shortcutAction) { 212ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng super(uri); 213ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mShortcutAction = shortcutAction; 214ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 215ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 216ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 217ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void loadData() { 218ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ContentResolver resolver = mContext.getContentResolver(); 219ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Cursor cursor = resolver.query(mUri, PHONE_COLUMNS, null, null, null); 220ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor != null) { 221ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng try { 222ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (cursor.moveToFirst()) { 223ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mDisplayName = cursor.getString(PHONE_DISPLAY_NAME_COLUMN_INDEX); 224ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mPhotoId = cursor.getLong(PHONE_PHOTO_ID_COLUMN_INDEX); 225ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mPhoneNumber = cursor.getString(PHONE_NUMBER_COLUMN_INDEX); 226ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mPhoneType = cursor.getInt(PHONE_TYPE_COLUMN_INDEX); 227ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mPhoneLabel = cursor.getString(PHONE_LABEL_COLUMN_INDEX); 228ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 229ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } finally { 230ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng cursor.close(); 231ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 232ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 233ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 234ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 235ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng @Override 236ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng protected void onPostExecute(Void result) { 237ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng createPhoneNumberShortcutIntent(mUri, mDisplayName, mBitmapData, mPhoneNumber, 238ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mPhoneType, mPhoneLabel, mShortcutAction); 239ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 240ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 241ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 242ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private Bitmap getPhotoBitmap(byte[] bitmapData) { 243ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Bitmap bitmap; 244ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (bitmapData != null) { 245ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length, null); 246ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 247ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng bitmap = ((BitmapDrawable) mContext.getResources().getDrawableForDensity( 248ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.drawable.ic_contact_picture_holo_light, mIconDensity)).getBitmap(); 249ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 250ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return bitmap; 251ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 252ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 253ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private void createContactShortcutIntent(Uri contactUri, String contentType, String displayName, 254ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng byte[] bitmapData) { 255ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Bitmap bitmap = getPhotoBitmap(bitmapData); 256ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 257ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Intent shortcutIntent = new Intent(ContactsContract.QuickContact.ACTION_QUICK_CONTACT); 258ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 259ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // When starting from the launcher, start in a new, cleared task. 260ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // CLEAR_WHEN_TASK_RESET cannot reset the root of a task, so we 261ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // clear the whole thing preemptively here since QuickContactActivity will 262ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // finish itself when launching other detail activities. 263ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 264ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 265ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Tell the launcher to not do its animation, because we are doing our own 266ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng shortcutIntent.putExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION, true); 267ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 268ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng shortcutIntent.setDataAndType(contactUri, contentType); 269ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_MODE, 270ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng ContactsContract.QuickContact.MODE_LARGE); 271ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng shortcutIntent.putExtra(ContactsContract.QuickContact.EXTRA_EXCLUDE_MIMES, 272ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng (String[]) null); 273ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 274ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Bitmap icon = generateQuickContactIcon(bitmap); 275ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 276ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Intent intent = new Intent(); 277ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon); 278ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); 279ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (TextUtils.isEmpty(displayName)) { 280ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mContext.getResources().getString( 281ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.string.missing_name)); 282ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 283ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName); 284ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 285ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 286ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mListener.onShortcutIntentCreated(contactUri, intent); 287ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 288ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 289ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private void createPhoneNumberShortcutIntent(Uri uri, String displayName, byte[] bitmapData, 290ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng String phoneNumber, int phoneType, String phoneLabel, String shortcutAction) { 291ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Bitmap bitmap = getPhotoBitmap(bitmapData); 292ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 293ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Uri phoneUri; 294ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (Intent.ACTION_CALL.equals(shortcutAction)) { 295ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Make the URI a direct tel: URI so that it will always continue to work 296ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng phoneUri = Uri.fromParts(CallUtil.SCHEME_TEL, phoneNumber, null); 297ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng bitmap = generatePhoneNumberIcon(bitmap, phoneType, phoneLabel, 298ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.drawable.badge_action_call); 299ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } else { 300ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng phoneUri = Uri.fromParts(CallUtil.SCHEME_SMSTO, phoneNumber, null); 301ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng bitmap = generatePhoneNumberIcon(bitmap, phoneType, phoneLabel, 302ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng R.drawable.badge_action_sms); 303ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 304ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 305ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Intent shortcutIntent = new Intent(shortcutAction, phoneUri); 306ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 307ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 308ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Intent intent = new Intent(); 309ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap); 310ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); 311ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName); 312ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 313ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mListener.onShortcutIntentCreated(uri, intent); 314ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 315ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 316ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private void drawBorder(Canvas canvas, Rect dst) { 317ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Darken the border 318ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Paint workPaint = new Paint(); 319ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng workPaint.setColor(mBorderColor); 320ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng workPaint.setStyle(Paint.Style.STROKE); 321ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // The stroke is drawn centered on the rect bounds, and since half will be drawn outside the 322ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // bounds, we need to double the width for it to appear as intended. 323ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng workPaint.setStrokeWidth(mBorderWidth * 2); 324ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.drawRect(dst, workPaint); 325ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 326ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 327ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private Bitmap generateQuickContactIcon(Bitmap photo) { 328ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 329ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Setup the drawing classes 330ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Bitmap icon = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888); 331ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Canvas canvas = new Canvas(icon); 332ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 333ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Copy in the photo 334ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Paint photoPaint = new Paint(); 335ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng photoPaint.setDither(true); 336ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng photoPaint.setFilterBitmap(true); 337ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Rect src = new Rect(0,0, photo.getWidth(),photo.getHeight()); 338ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Rect dst = new Rect(0,0, mIconSize, mIconSize); 339ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.drawBitmap(photo, src, dst, photoPaint); 340ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 341ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng drawBorder(canvas, dst); 342ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 343ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Drawable overlay = mContext.getResources().getDrawableForDensity( 344ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng com.android.internal.R.drawable.quickcontact_badge_overlay_dark, mIconDensity); 345ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 346ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng overlay.setBounds(dst); 347ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng overlay.draw(canvas); 348ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.setBitmap(null); 349ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 350ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return icon; 351ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 352ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 353ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng /** 354ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * Generates a phone number shortcut icon. Adds an overlay describing the type of the phone 355ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng * number, and if there is a photo also adds the call action icon. 356ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng */ 357ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng private Bitmap generatePhoneNumberIcon(Bitmap photo, int phoneType, String phoneLabel, 358ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng int actionResId) { 359ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Resources r = mContext.getResources(); 360ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final float density = r.getDisplayMetrics().density; 361ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 362ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Bitmap phoneIcon = ((BitmapDrawable) r.getDrawableForDensity(actionResId, mIconDensity)) 363ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .getBitmap(); 364ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 365ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Setup the drawing classes 366ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Bitmap icon = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888); 367ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Canvas canvas = new Canvas(icon); 368ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 369ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Copy in the photo 370ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Paint photoPaint = new Paint(); 371ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng photoPaint.setDither(true); 372ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng photoPaint.setFilterBitmap(true); 373ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Rect src = new Rect(0, 0, photo.getWidth(), photo.getHeight()); 374ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng Rect dst = new Rect(0, 0, mIconSize, mIconSize); 375ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.drawBitmap(photo, src, dst, photoPaint); 376ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 377ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng drawBorder(canvas, dst); 378ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 379ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Create an overlay for the phone number type 380ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng CharSequence overlay = Phone.getTypeLabel(r, phoneType, phoneLabel); 381ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 382ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng if (overlay != null) { 383ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); 384ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng textPaint.setTextSize(r.getDimension(R.dimen.shortcut_overlay_text_size)); 385ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng textPaint.setColor(r.getColor(R.color.textColorIconOverlay)); 386ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng textPaint.setShadowLayer(4f, 0, 2f, r.getColor(R.color.textColorIconOverlayShadow)); 387ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 388ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final FontMetricsInt fmi = textPaint.getFontMetricsInt(); 389ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 390ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // First fill in a darker background around the text to be drawn 391ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final Paint workPaint = new Paint(); 392ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng workPaint.setColor(mBorderColor); 393ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng workPaint.setStyle(Paint.Style.FILL); 394ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final int textPadding = r 395ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng .getDimensionPixelOffset(R.dimen.shortcut_overlay_text_background_padding); 396ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final int textBandHeight = (fmi.descent - fmi.ascent) + textPadding * 2; 397ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng dst.set(0 + mBorderWidth, mIconSize - textBandHeight, mIconSize - mBorderWidth, 398ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng mIconSize - mBorderWidth); 399ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.drawRect(dst, workPaint); 400ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 401ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final float sidePadding = mBorderWidth; 402ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng overlay = TextUtils.ellipsize(overlay, textPaint, mIconSize - 2 * sidePadding, 403ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng TruncateAt.END_SMALL); 404ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng final float textWidth = textPaint.measureText(overlay, 0, overlay.length()); 405ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.drawText(overlay, 0, overlay.length(), (mIconSize - textWidth) / 2, mIconSize 406ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng - fmi.descent - textPadding, textPaint); 407ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 408ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 409ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng // Draw the phone action icon as an overlay 410ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng src.set(0, 0, phoneIcon.getWidth(), phoneIcon.getHeight()); 411ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng int iconWidth = icon.getWidth(); 412ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng dst.set(iconWidth - ((int) (20 * density)), -1, 413ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng iconWidth, ((int) (19 * density))); 414ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng dst.offset(-mBorderWidth, mBorderWidth); 415ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.drawBitmap(phoneIcon, src, dst, photoPaint); 416ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 417ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng canvas.setBitmap(null); 418ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng 419ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng return icon; 420ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng } 421ba2c125b07086a88a3517fcf381a3a400c42afd3Chiao Cheng} 422