1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.contacts.common.list; 17 18 import android.content.Context; 19 import android.database.Cursor; 20 import android.net.Uri; 21 import android.provider.ContactsContract; 22 import android.provider.ContactsContract.Contacts; 23 import android.provider.ContactsContract.Directory; 24 import android.provider.ContactsContract.SearchSnippets; 25 import android.view.ViewGroup; 26 import com.android.contacts.common.R; 27 import com.android.contacts.common.preference.ContactsPreferences; 28 import com.android.dialer.contactphoto.ContactPhotoManager.DefaultImageRequest; 29 30 /** 31 * A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type. Also 32 * includes support for including the {@link ContactsContract.Profile} record in the list. 33 */ 34 public abstract class ContactListAdapter extends ContactEntryListAdapter { 35 36 private CharSequence mUnknownNameText; 37 38 public ContactListAdapter(Context context) { 39 super(context); 40 41 mUnknownNameText = context.getText(R.string.missing_name); 42 } 43 44 protected static Uri buildSectionIndexerUri(Uri uri) { 45 return uri.buildUpon().appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true").build(); 46 } 47 48 public Uri getContactUri(int partitionIndex, Cursor cursor) { 49 long contactId = cursor.getLong(ContactQuery.CONTACT_ID); 50 String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY); 51 Uri uri = Contacts.getLookupUri(contactId, lookupKey); 52 long directoryId = ((DirectoryPartition) getPartition(partitionIndex)).getDirectoryId(); 53 if (uri != null && directoryId != Directory.DEFAULT) { 54 uri = 55 uri.buildUpon() 56 .appendQueryParameter( 57 ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)) 58 .build(); 59 } 60 return uri; 61 } 62 63 @Override 64 protected ContactListItemView newView( 65 Context context, int partition, Cursor cursor, int position, ViewGroup parent) { 66 ContactListItemView view = super.newView(context, partition, cursor, position, parent); 67 view.setUnknownNameText(mUnknownNameText); 68 view.setQuickContactEnabled(isQuickContactEnabled()); 69 view.setAdjustSelectionBoundsEnabled(isAdjustSelectionBoundsEnabled()); 70 view.setActivatedStateSupported(isSelectionVisible()); 71 return view; 72 } 73 74 protected void bindSectionHeaderAndDivider( 75 ContactListItemView view, int position, Cursor cursor) { 76 view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled()); 77 if (isSectionHeaderDisplayEnabled()) { 78 Placement placement = getItemPlacementInSection(position); 79 view.setSectionHeader(placement.sectionHeader); 80 } else { 81 view.setSectionHeader(null); 82 } 83 } 84 85 protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) { 86 if (!isPhotoSupported(partitionIndex)) { 87 view.removePhotoView(); 88 return; 89 } 90 91 // Set the photo, if available 92 long photoId = 0; 93 if (!cursor.isNull(ContactQuery.CONTACT_PHOTO_ID)) { 94 photoId = cursor.getLong(ContactQuery.CONTACT_PHOTO_ID); 95 } 96 97 if (photoId != 0) { 98 getPhotoLoader() 99 .loadThumbnail(view.getPhotoView(), photoId, false, getCircularPhotos(), null); 100 } else { 101 final String photoUriString = cursor.getString(ContactQuery.CONTACT_PHOTO_URI); 102 final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString); 103 DefaultImageRequest request = null; 104 if (photoUri == null) { 105 request = 106 getDefaultImageRequestFromCursor( 107 cursor, ContactQuery.CONTACT_DISPLAY_NAME, ContactQuery.CONTACT_LOOKUP_KEY); 108 } 109 getPhotoLoader() 110 .loadDirectoryPhoto(view.getPhotoView(), photoUri, false, getCircularPhotos(), request); 111 } 112 } 113 114 protected void bindNameAndViewId(final ContactListItemView view, Cursor cursor) { 115 view.showDisplayName(cursor, ContactQuery.CONTACT_DISPLAY_NAME); 116 // Note: we don't show phonetic any more (See issue 5265330) 117 118 bindViewId(view, cursor, ContactQuery.CONTACT_ID); 119 } 120 121 protected void bindPresenceAndStatusMessage(final ContactListItemView view, Cursor cursor) { 122 view.showPresenceAndStatusMessage( 123 cursor, ContactQuery.CONTACT_PRESENCE_STATUS, ContactQuery.CONTACT_CONTACT_STATUS); 124 } 125 126 protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) { 127 view.showSnippet(cursor, ContactQuery.CONTACT_SNIPPET); 128 } 129 130 @Override 131 public void changeCursor(int partitionIndex, Cursor cursor) { 132 super.changeCursor(partitionIndex, cursor); 133 134 if (cursor == null || !cursor.moveToFirst()) { 135 return; 136 } 137 138 // hasProfile tells whether the first row is a profile 139 final boolean hasProfile = cursor.getInt(ContactQuery.CONTACT_IS_USER_PROFILE) == 1; 140 141 // Add ME profile on top of favorites 142 cursor.moveToFirst(); 143 setProfileExists(hasProfile); 144 } 145 146 /** @return Projection useful for children. */ 147 protected final String[] getProjection(boolean forSearch) { 148 final int sortOrder = getContactNameDisplayOrder(); 149 if (forSearch) { 150 if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) { 151 return ContactQuery.FILTER_PROJECTION_PRIMARY; 152 } else { 153 return ContactQuery.FILTER_PROJECTION_ALTERNATIVE; 154 } 155 } else { 156 if (sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) { 157 return ContactQuery.CONTACT_PROJECTION_PRIMARY; 158 } else { 159 return ContactQuery.CONTACT_PROJECTION_ALTERNATIVE; 160 } 161 } 162 } 163 164 protected static class ContactQuery { 165 166 public static final int CONTACT_ID = 0; 167 public static final int CONTACT_DISPLAY_NAME = 1; 168 public static final int CONTACT_PRESENCE_STATUS = 2; 169 public static final int CONTACT_CONTACT_STATUS = 3; 170 public static final int CONTACT_PHOTO_ID = 4; 171 public static final int CONTACT_PHOTO_URI = 5; 172 public static final int CONTACT_LOOKUP_KEY = 6; 173 public static final int CONTACT_IS_USER_PROFILE = 7; 174 public static final int CONTACT_PHONETIC_NAME = 8; 175 public static final int CONTACT_STARRED = 9; 176 public static final int CONTACT_SNIPPET = 10; 177 private static final String[] CONTACT_PROJECTION_PRIMARY = 178 new String[] { 179 Contacts._ID, // 0 180 Contacts.DISPLAY_NAME_PRIMARY, // 1 181 Contacts.CONTACT_PRESENCE, // 2 182 Contacts.CONTACT_STATUS, // 3 183 Contacts.PHOTO_ID, // 4 184 Contacts.PHOTO_THUMBNAIL_URI, // 5 185 Contacts.LOOKUP_KEY, // 6 186 Contacts.IS_USER_PROFILE, // 7 187 Contacts.PHONETIC_NAME, // 8 188 Contacts.STARRED, // 9 189 }; 190 private static final String[] CONTACT_PROJECTION_ALTERNATIVE = 191 new String[] { 192 Contacts._ID, // 0 193 Contacts.DISPLAY_NAME_ALTERNATIVE, // 1 194 Contacts.CONTACT_PRESENCE, // 2 195 Contacts.CONTACT_STATUS, // 3 196 Contacts.PHOTO_ID, // 4 197 Contacts.PHOTO_THUMBNAIL_URI, // 5 198 Contacts.LOOKUP_KEY, // 6 199 Contacts.IS_USER_PROFILE, // 7 200 Contacts.PHONETIC_NAME, // 8 201 Contacts.STARRED, // 9 202 }; 203 private static final String[] FILTER_PROJECTION_PRIMARY = 204 new String[] { 205 Contacts._ID, // 0 206 Contacts.DISPLAY_NAME_PRIMARY, // 1 207 Contacts.CONTACT_PRESENCE, // 2 208 Contacts.CONTACT_STATUS, // 3 209 Contacts.PHOTO_ID, // 4 210 Contacts.PHOTO_THUMBNAIL_URI, // 5 211 Contacts.LOOKUP_KEY, // 6 212 Contacts.IS_USER_PROFILE, // 7 213 Contacts.PHONETIC_NAME, // 8 214 Contacts.STARRED, // 9 215 SearchSnippets.SNIPPET, // 10 216 }; 217 private static final String[] FILTER_PROJECTION_ALTERNATIVE = 218 new String[] { 219 Contacts._ID, // 0 220 Contacts.DISPLAY_NAME_ALTERNATIVE, // 1 221 Contacts.CONTACT_PRESENCE, // 2 222 Contacts.CONTACT_STATUS, // 3 223 Contacts.PHOTO_ID, // 4 224 Contacts.PHOTO_THUMBNAIL_URI, // 5 225 Contacts.LOOKUP_KEY, // 6 226 Contacts.IS_USER_PROFILE, // 7 227 Contacts.PHONETIC_NAME, // 8 228 Contacts.STARRED, // 9 229 SearchSnippets.SNIPPET, // 10 230 }; 231 } 232 } 233