165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.util; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.accounts.Account; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.ContentUris; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.ContentProviderClient; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent.ShortcutIconResource; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.database.Cursor; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.Uri; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.ContactsContract; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.ContactsContract.Data; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.ContactsContract.RawContacts; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.provider.ContactsContract.CommonDataKinds.Photo; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.text.TextUtils; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Utility functions for retrieving account pictures. 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic final class AccountImageHelper { 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane static final String[] CONTACT_PROJECTION_DATA = new String[] { 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ContactsContract.Data._ID, 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ContactsContract.Data.CONTACT_ID, 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ContactsContract.Data.RAW_CONTACT_ID, 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ContactsContract.Data.LOOKUP_KEY, 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ContactsContract.Data.PHOTO_URI, 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ContactsContract.Data.PHOTO_FILE_ID 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane static final String CONTACT_SELECTION = 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ContactsContract.CommonDataKinds.Email.ADDRESS + " LIKE ?"; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Non instantiable. 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private AccountImageHelper() { 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Tries to retrieve the Picture for the provided account, from the Contacts database. 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static String getAccountPictureUri(Context context, Account account) { 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Look up this account in the contacts database. 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] selectionArgs = new String[] { 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane account.name }; 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Cursor c = null; 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane long contactId = -1; 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String lookupKey = null; 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String photoUri = null; 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int photoFileId = 0; 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane long rawContactId = 0; 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane c = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane CONTACT_PROJECTION_DATA, CONTACT_SELECTION, selectionArgs, null); 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (c.moveToNext()) { 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane contactId = c.getLong(1); 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane rawContactId = c.getLong(2); 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane lookupKey = c.getString(3); 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane photoUri = c.getString(4); 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane photoFileId = c.getInt(5); 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } finally { 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (c != null) { 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane c.close(); 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (contactId != -1 && !TextUtils.isEmpty(lookupKey) && !TextUtils.isEmpty(photoUri)) { 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (photoFileId == 0) { 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Trigger a VIEW action on this photo, which will force the Contacts 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Sync adapter to sync the HiRes version of the contact photo. 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane syncContactHiResPhoto(context, rawContactId); 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return photoUri; 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getDefaultPictureUri(context); 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static void syncContactHiResPhoto(Context context, long rawContactId) { 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final String serviceName = "com.google.android.syncadapters.contacts." + 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane "SyncHighResPhotoIntentService"; 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final String servicePackageName = "com.google.android.syncadapters.contacts"; 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane rawContactId); 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final Intent intent = new Intent(); 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.setClassName(servicePackageName, serviceName); 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.setAction(Intent.ACTION_VIEW); 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.setDataAndType(uri, RawContacts.CONTENT_ITEM_TYPE); 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane context.startService(intent); 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (Exception e) { 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Returns a default image to be used when an account has no picture associated with it. 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static String getDefaultPictureUri(Context context) { 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: get a better default image. 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ShortcutIconResource iconResource = new ShortcutIconResource(); 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane iconResource.packageName = context.getPackageName(); 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane iconResource.resourceName = context.getResources().getResourceName( 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.drawable.default_contact_picture); 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return UriUtils.getShortcutIconResourceUri(iconResource).toString(); 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 128