1 /* 2 * Copyright (C) 2016 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.list; 17 18 import android.content.ContentUris; 19 import android.content.Context; 20 import android.content.CursorLoader; 21 import android.database.Cursor; 22 import android.net.Uri; 23 import android.net.Uri.Builder; 24 import android.os.Bundle; 25 import android.provider.ContactsContract; 26 import android.provider.ContactsContract.CommonDataKinds.Phone; 27 import android.text.TextUtils; 28 import android.view.View; 29 import android.view.ViewGroup; 30 31 import com.android.contacts.group.GroupUtil; 32 import com.android.contacts.preference.ContactsPreferences; 33 34 /** Phone Numbers multi-select cursor adapter. */ 35 public class MultiSelectPhoneNumbersListAdapter extends MultiSelectEntryContactListAdapter { 36 37 public static class PhoneQuery { 38 public static final String[] PROJECTION_PRIMARY = new String[] { 39 Phone._ID, // 0 40 Phone.TYPE, // 1 41 Phone.LABEL, // 2 42 Phone.NUMBER, // 3 43 Phone.CONTACT_ID, // 4 44 Phone.LOOKUP_KEY, // 5 45 Phone.PHOTO_ID, // 6 46 Phone.DISPLAY_NAME_PRIMARY, // 7 47 Phone.PHOTO_THUMBNAIL_URI, // 8 48 }; 49 50 public static final String[] PROJECTION_ALTERNATIVE = new String[] { 51 Phone._ID, // 0 52 Phone.TYPE, // 1 53 Phone.LABEL, // 2 54 Phone.NUMBER, // 3 55 Phone.CONTACT_ID, // 4 56 Phone.LOOKUP_KEY, // 5 57 Phone.PHOTO_ID, // 6 58 Phone.DISPLAY_NAME_ALTERNATIVE, // 7 59 Phone.PHOTO_THUMBNAIL_URI, // 8 60 }; 61 62 public static final int PHONE_ID = 0; 63 public static final int PHONE_TYPE = 1; 64 public static final int PHONE_LABEL = 2; 65 public static final int PHONE_NUMBER = 3; 66 public static final int CONTACT_ID = 4; 67 public static final int LOOKUP_KEY = 5; 68 public static final int PHOTO_ID = 6; 69 public static final int DISPLAY_NAME = 7; 70 public static final int PHOTO_URI = 8; 71 } 72 73 private final CharSequence mUnknownNameText; 74 private long[] mContactIdsFilter = null; 75 76 public MultiSelectPhoneNumbersListAdapter(Context context) { 77 super(context, PhoneQuery.PHONE_ID); 78 79 mUnknownNameText = context.getText(android.R.string.unknownName); 80 } 81 82 public void setArguments(Bundle bundle) { 83 mContactIdsFilter = bundle.getLongArray(UiIntentActions.SELECTION_ITEM_LIST); 84 } 85 86 @Override 87 public void configureLoader(CursorLoader loader, long directoryId) { 88 final Builder builder; 89 if (isSearchMode()) { 90 builder = Phone.CONTENT_FILTER_URI.buildUpon(); 91 final String query = getQueryString(); 92 builder.appendPath(TextUtils.isEmpty(query) ? "" : query); 93 } else { 94 builder = Phone.CONTENT_URI.buildUpon(); 95 if (isSectionHeaderDisplayEnabled()) { 96 builder.appendQueryParameter(Phone.EXTRA_ADDRESS_BOOK_INDEX, "true"); 97 } 98 } 99 builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, 100 String.valueOf(directoryId)); 101 loader.setUri(builder.build()); 102 103 if (mContactIdsFilter != null) { 104 loader.setSelection(ContactsContract.Data.CONTACT_ID 105 + " IN (" + GroupUtil.convertArrayToString(mContactIdsFilter) + ")"); 106 } 107 108 if (getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) { 109 loader.setProjection(PhoneQuery.PROJECTION_PRIMARY); 110 } else { 111 loader.setProjection(PhoneQuery.PROJECTION_ALTERNATIVE); 112 } 113 114 if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) { 115 loader.setSortOrder(Phone.SORT_KEY_PRIMARY); 116 } else { 117 loader.setSortOrder(Phone.SORT_KEY_ALTERNATIVE); 118 } 119 } 120 121 @Override 122 public String getContactDisplayName(int position) { 123 return ((Cursor) getItem(position)).getString(PhoneQuery.DISPLAY_NAME); 124 } 125 126 /** 127 * Builds a {@link Data#CONTENT_URI} for the current cursor position. 128 */ 129 public Uri getDataUri(int position) { 130 final long id = ((Cursor) getItem(position)).getLong(PhoneQuery.PHONE_ID); 131 return ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id); 132 } 133 134 @Override 135 protected ContactListItemView newView( 136 Context context, int partition, Cursor cursor, int position, ViewGroup parent) { 137 final ContactListItemView view = super.newView(context, partition, cursor, position, parent); 138 view.setUnknownNameText(mUnknownNameText); 139 view.setQuickContactEnabled(isQuickContactEnabled()); 140 return view; 141 } 142 143 @Override 144 protected void bindView(View itemView, int partition, Cursor cursor, int position) { 145 super.bindView(itemView, partition, cursor, position); 146 final ContactListItemView view = (ContactListItemView)itemView; 147 148 cursor.moveToPosition(position); 149 boolean isFirstEntry = true; 150 final long currentContactId = cursor.getLong(PhoneQuery.CONTACT_ID); 151 if (cursor.moveToPrevious() && !cursor.isBeforeFirst()) { 152 final long previousContactId = cursor.getLong(PhoneQuery.CONTACT_ID); 153 if (currentContactId == previousContactId) { 154 isFirstEntry = false; 155 } 156 } 157 cursor.moveToPosition(position); 158 159 bindViewId(view, cursor, PhoneQuery.PHONE_ID); 160 if (isFirstEntry) { 161 bindName(view, cursor); 162 bindPhoto(view, cursor, PhoneQuery.PHOTO_ID, PhoneQuery.LOOKUP_KEY, 163 PhoneQuery.DISPLAY_NAME); 164 } else { 165 unbindName(view); 166 view.removePhotoView(true, false); 167 } 168 bindPhoneNumber(view, cursor); 169 } 170 171 protected void unbindName(final ContactListItemView view) { 172 view.hideDisplayName(); 173 } 174 175 protected void bindPhoneNumber(ContactListItemView view, Cursor cursor) { 176 CharSequence label = null; 177 if (!cursor.isNull(PhoneQuery.PHONE_TYPE)) { 178 final int type = cursor.getInt(PhoneQuery.PHONE_TYPE); 179 final String customLabel = cursor.getString(PhoneQuery.PHONE_LABEL); 180 181 // TODO cache 182 label = Phone.getTypeLabel(getContext().getResources(), type, customLabel); 183 } 184 view.setLabel(label); 185 view.showData(cursor, PhoneQuery.PHONE_NUMBER); 186 } 187 188 protected void bindName(final ContactListItemView view, Cursor cursor) { 189 view.showDisplayName(cursor, PhoneQuery.DISPLAY_NAME, getContactNameDisplayOrder()); 190 } 191 } 192