163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng/* 263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Copyright (C) 2010 The Android Open Source Project 363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * 463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * you may not use this file except in compliance with the License. 663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * You may obtain a copy of the License at 763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * 863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * 1063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Unless required by applicable law or agreed to in writing, software 1163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 1263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * See the License for the specific language governing permissions and 1463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * limitations under the License. 1563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng */ 1663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengpackage com.android.contacts.common.list; 1763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 1863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.content.ContentUris; 1963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.content.Context; 2063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.content.CursorLoader; 2163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.database.Cursor; 2263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.net.Uri; 2363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.net.Uri.Builder; 2463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract; 2563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract.CommonDataKinds.Callable; 2663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract.CommonDataKinds.Phone; 2763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract.CommonDataKinds.SipAddress; 2863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract.Contacts; 2963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract.Data; 3063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.provider.ContactsContract.Directory; 3141d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Leeimport android.text.TextUtils; 3263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.util.Log; 3363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.view.View; 3463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport android.view.ViewGroup; 3563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 36e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunnimport com.android.contacts.common.CallUtil; 3744192bbce136eda4305e8ffa2cafc7663b3e25d2Victor Changimport com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; 38d19d35ef8347038f5296ed7020cab79396874937Victor Changimport com.android.contacts.common.ContactsUtils; 396af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albertimport com.android.contacts.common.GeoUtil; 4063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport com.android.contacts.common.R; 41cd0b29ddbf3648e48f048196c62245d545bc6122Ricky Waiimport com.android.contacts.common.compat.CallableCompat; 4292a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wangimport com.android.contacts.common.compat.CompatUtils; 43cd0b29ddbf3648e48f048196c62245d545bc6122Ricky Waiimport com.android.contacts.common.compat.DirectoryCompat; 44cd0b29ddbf3648e48f048196c62245d545bc6122Ricky Waiimport com.android.contacts.common.compat.PhoneCompat; 45ad582fa758c6a276c26c5cc52079613a653c81bfBen Giladimport com.android.contacts.common.extensions.ExtendedPhoneDirectoriesManager; 46ad582fa758c6a276c26c5cc52079613a653c81bfBen Giladimport com.android.contacts.common.extensions.ExtensionsFactory; 47495c732e471c1c68db91ca6e824440130fdb7146Yorke Leeimport com.android.contacts.common.preference.ContactsPreferences; 48b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albertimport com.android.contacts.common.util.Constants; 4963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 5092a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wangimport com.google.common.collect.Lists; 5192a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang 5263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport java.util.ArrayList; 5363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengimport java.util.List; 5463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 5563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng/** 5663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * A cursor adapter for the {@link Phone#CONTENT_ITEM_TYPE} and 5763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * {@link SipAddress#CONTENT_ITEM_TYPE}. 5863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * 5963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * By default this adapter just handles phone numbers. When {@link #setUseCallableUri(boolean)} is 6063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * called with "true", this adapter starts handling SIP addresses too, by using {@link Callable} 6163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * API instead of {@link Phone}. 6263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng */ 6363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Chengpublic class PhoneNumberListAdapter extends ContactEntryListAdapter { 64ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 6563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng private static final String TAG = PhoneNumberListAdapter.class.getSimpleName(); 6663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 67e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public interface Listener { 68e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn void onVideoCallIconClicked(int position); 69e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 70e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 71ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // A list of extended directories to add to the directories from the database 72ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad private final List<DirectoryPartition> mExtendedDirectories; 73ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 74e3cc993cb72230b0ca9465763d927b8a851da8fbWenyi Wang // Extended directories will have ID's that are higher than any of the id's from the database, 75e3cc993cb72230b0ca9465763d927b8a851da8fbWenyi Wang // so that we can identify them and set them up properly. If no extended directories 76ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // exist, this will be Long.MAX_VALUE 77ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad private long mFirstExtendedDirectoryId = Long.MAX_VALUE; 78ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 79a81953a2b1818066ef5e44817f374ac288bab343Christine Chen public static class PhoneQuery { 806a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn 816a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn /** 826a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * Optional key used as part of a JSON lookup key to specify an analytics category 836a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * associated with the row. 846a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn */ 856a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn public static final String ANALYTICS_CATEGORY = "analytics_category"; 866a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn 876a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn /** 886a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * Optional key used as part of a JSON lookup key to specify an analytics action associated 896a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * with the row. 906a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn */ 916a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn public static final String ANALYTICS_ACTION = "analytics_action"; 926a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn 936a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn /** 946a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * Optional key used as part of a JSON lookup key to specify an analytics value associated 956a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * with the row. 966a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn */ 976a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn public static final String ANALYTICS_VALUE = "analytics_value"; 986a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn 9992a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang public static final String[] PROJECTION_PRIMARY_INTERNAL = new String[] { 10063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone._ID, // 0 10163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.TYPE, // 1 10263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.LABEL, // 2 10363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.NUMBER, // 3 10463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.CONTACT_ID, // 4 10563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.LOOKUP_KEY, // 5 10663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.PHOTO_ID, // 6 10763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.DISPLAY_NAME_PRIMARY, // 7 1087a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner Phone.PHOTO_THUMBNAIL_URI, // 8 10963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng }; 11063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 11192a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang public static final String[] PROJECTION_PRIMARY; 11292a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang 11392a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang static { 11492a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang final List<String> projectionList = Lists.newArrayList(PROJECTION_PRIMARY_INTERNAL); 11592a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang if (CompatUtils.isMarshmallowCompatible()) { 11692a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang projectionList.add(Phone.CARRIER_PRESENCE); // 9 11792a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang } 11892a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang PROJECTION_PRIMARY = projectionList.toArray(new String[projectionList.size()]); 11992a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang } 12092a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang 12192a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang public static final String[] PROJECTION_ALTERNATIVE_INTERNAL = new String[] { 12263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone._ID, // 0 12363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.TYPE, // 1 12463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.LABEL, // 2 12563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.NUMBER, // 3 12663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.CONTACT_ID, // 4 12763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.LOOKUP_KEY, // 5 12863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.PHOTO_ID, // 6 12963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Phone.DISPLAY_NAME_ALTERNATIVE, // 7 1307a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner Phone.PHOTO_THUMBNAIL_URI, // 8 13163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng }; 13263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 13392a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang public static final String[] PROJECTION_ALTERNATIVE; 13492a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang 13592a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang static { 13692a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang final List<String> projectionList = Lists.newArrayList(PROJECTION_ALTERNATIVE_INTERNAL); 13792a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang if (CompatUtils.isMarshmallowCompatible()) { 13892a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang projectionList.add(Phone.CARRIER_PRESENCE); // 9 13992a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang } 14092a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang PROJECTION_ALTERNATIVE = projectionList.toArray(new String[projectionList.size()]); 14192a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang } 14292a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang 1437a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int PHONE_ID = 0; 1447a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int PHONE_TYPE = 1; 1457a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int PHONE_LABEL = 2; 1467a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int PHONE_NUMBER = 3; 1477a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int CONTACT_ID = 4; 1487a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int LOOKUP_KEY = 5; 1497a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int PHOTO_ID = 6; 1507a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int DISPLAY_NAME = 7; 1517a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public static final int PHOTO_URI = 8; 152e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public static final int CARRIER_PRESENCE = 9; 15363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 15463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 15541d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee private static final String IGNORE_NUMBER_TOO_LONG_CLAUSE = 15641d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee "length(" + Phone.NUMBER + ") < 1000"; 15741d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee 15863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng private final CharSequence mUnknownNameText; 15962dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee private final String mCountryIso; 16063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 16163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng private ContactListItemView.PhotoPosition mPhotoPosition; 16263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 16363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng private boolean mUseCallableUri; 16463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 165e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private Listener mListener; 166e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 167e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private boolean mIsVideoEnabled; 168e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn private boolean mIsPresenceEnabled; 169e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 17063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public PhoneNumberListAdapter(Context context) { 17163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng super(context); 17263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng setDefaultFilterHeaderText(R.string.list_filter_phones); 17363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng mUnknownNameText = context.getText(android.R.string.unknownName); 17462dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee mCountryIso = GeoUtil.getCurrentCountryIso(context); 175ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 176ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final ExtendedPhoneDirectoriesManager manager 177ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad = ExtensionsFactory.getExtendedPhoneDirectoriesManager(); 178ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (manager != null) { 179ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad mExtendedDirectories = manager.getExtendedDirectories(mContext); 180ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } else { 181a6057cf46a154666c6f2888702d4109504b4da29Alon Albert // Empty list to avoid sticky NPE's 182a6057cf46a154666c6f2888702d4109504b4da29Alon Albert mExtendedDirectories = new ArrayList<DirectoryPartition>(); 183ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 184e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 185e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn int videoCapabilities = CallUtil.getVideoCallingAvailability(context); 186e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mIsVideoEnabled = (videoCapabilities & CallUtil.VIDEO_CALLING_ENABLED) != 0; 187e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mIsPresenceEnabled = (videoCapabilities & CallUtil.VIDEO_CALLING_PRESENCE) != 0; 18863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 18963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 19063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng protected CharSequence getUnknownNameText() { 19163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng return mUnknownNameText; 19263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 19363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 19463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng @Override 19563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public void configureLoader(CursorLoader loader, long directoryId) { 196ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad String query = getQueryString(); 197ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (query == null) { 198ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad query = ""; 199ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 200ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (isExtendedDirectory(directoryId)) { 201ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final DirectoryPartition directory = getExtendedDirectoryFromId(directoryId); 202768324c2d917f9ce79747007c57efcefbc06b472Alon Albert final String contentUri = directory.getContentUri(); 203768324c2d917f9ce79747007c57efcefbc06b472Alon Albert if (contentUri == null) { 204768324c2d917f9ce79747007c57efcefbc06b472Alon Albert throw new IllegalStateException("Extended directory must have a content URL: " 205768324c2d917f9ce79747007c57efcefbc06b472Alon Albert + directory); 206768324c2d917f9ce79747007c57efcefbc06b472Alon Albert } 207768324c2d917f9ce79747007c57efcefbc06b472Alon Albert final Builder builder = Uri.parse(contentUri).buildUpon(); 208ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder.appendPath(query); 209ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder.appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, 210ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad String.valueOf(getDirectoryResultLimit(directory))); 211ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad loader.setUri(builder.build()); 212ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad loader.setProjection(PhoneQuery.PROJECTION_PRIMARY); 213ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } else { 214bf0104458b0c59762f0fc9df8c9012fca33220abRicky Wai final boolean isRemoteDirectoryQuery 215bf0104458b0c59762f0fc9df8c9012fca33220abRicky Wai = DirectoryCompat.isRemoteDirectoryId(directoryId); 216ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final Builder builder; 217ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (isSearchMode()) { 218ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final Uri baseUri; 219ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (isRemoteDirectoryQuery) { 220cd0b29ddbf3648e48f048196c62245d545bc6122Ricky Wai baseUri = PhoneCompat.getContentFilterUri(); 221ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } else if (mUseCallableUri) { 222cd0b29ddbf3648e48f048196c62245d545bc6122Ricky Wai baseUri = CallableCompat.getContentFilterUri(); 223ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } else { 224cd0b29ddbf3648e48f048196c62245d545bc6122Ricky Wai baseUri = PhoneCompat.getContentFilterUri(); 225ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 226ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder = baseUri.buildUpon(); 227ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder.appendPath(query); // Builder will encode the query 228ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, 229ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad String.valueOf(directoryId)); 230ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (isRemoteDirectoryQuery) { 231ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder.appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, 232ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad String.valueOf(getDirectoryResultLimit(getDirectoryById(directoryId)))); 233ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 2347a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } else { 235e3cc993cb72230b0ca9465763d927b8a851da8fbWenyi Wang Uri baseUri = mUseCallableUri ? Callable.CONTENT_URI : Phone.CONTENT_URI; 236ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder = baseUri.buildUpon().appendQueryParameter( 237ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT)); 238ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (isSectionHeaderDisplayEnabled()) { 239d9ba7ce0739281fc903ece843b5c84e10344adb3Yorke Lee builder.appendQueryParameter(Phone.EXTRA_ADDRESS_BOOK_INDEX, "true"); 240ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 241ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad applyFilter(loader, builder, directoryId, getFilter()); 2427a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 243ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 24441d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee // Ignore invalid phone numbers that are too long. These can potentially cause freezes 24541d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee // in the UI and there is no reason to display them. 24641d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee final String prevSelection = loader.getSelection(); 24741d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee final String newSelection; 24841d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee if (!TextUtils.isEmpty(prevSelection)) { 24941d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee newSelection = prevSelection + " AND " + IGNORE_NUMBER_TOO_LONG_CLAUSE; 25041d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee } else { 25141d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee newSelection = IGNORE_NUMBER_TOO_LONG_CLAUSE; 25241d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee } 25341d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee loader.setSelection(newSelection); 25441d16000cdd94f5f69f5d5c7c6c1519d82bc15feYorke Lee 255ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // Remove duplicates when it is possible. 256ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad builder.appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true"); 257ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad loader.setUri(builder.build()); 258ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 259ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // TODO a projection that includes the search snippet 260495c732e471c1c68db91ca6e824440130fdb7146Yorke Lee if (getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) { 261ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad loader.setProjection(PhoneQuery.PROJECTION_PRIMARY); 26263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } else { 263ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad loader.setProjection(PhoneQuery.PROJECTION_ALTERNATIVE); 2647a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 265ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 266495c732e471c1c68db91ca6e824440130fdb7146Yorke Lee if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) { 267ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad loader.setSortOrder(Phone.SORT_KEY_PRIMARY); 268ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } else { 269ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad loader.setSortOrder(Phone.SORT_KEY_ALTERNATIVE); 27063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 27163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 272ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 27363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 2741a2b2a318d9d0dacf183d49fd2363cb79a9f2335Jay Shrauner protected boolean isExtendedDirectory(long directoryId) { 275ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad return directoryId >= mFirstExtendedDirectoryId; 276ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 27763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 278ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad private DirectoryPartition getExtendedDirectoryFromId(long directoryId) { 279ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final int directoryIndex = (int) (directoryId - mFirstExtendedDirectoryId); 280ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad return mExtendedDirectories.get(directoryIndex); 28163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 28263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 28363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng /** 28463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Configure {@code loader} and {@code uriBuilder} according to {@code directoryId} and {@code 28563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * filter}. 28663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng */ 28763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng private void applyFilter(CursorLoader loader, Uri.Builder uriBuilder, long directoryId, 28863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng ContactListFilter filter) { 28963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (filter == null || directoryId != Directory.DEFAULT) { 29063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng return; 29163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 29263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 29363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng final StringBuilder selection = new StringBuilder(); 29463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng final List<String> selectionArgs = new ArrayList<String>(); 29563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 29663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng switch (filter.filterType) { 29763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng case ContactListFilter.FILTER_TYPE_CUSTOM: { 29863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng selection.append(Contacts.IN_VISIBLE_GROUP + "=1"); 29963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng selection.append(" AND " + Contacts.HAS_PHONE_NUMBER + "=1"); 30063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng break; 30163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 30263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng case ContactListFilter.FILTER_TYPE_ACCOUNT: { 30363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng filter.addAccountQueryParameterToUrl(uriBuilder); 30463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng break; 30563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 30663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS: 30763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng case ContactListFilter.FILTER_TYPE_DEFAULT: 30863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng break; // No selection needed. 30963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng case ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY: 31063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng break; // This adapter is always "phone only", so no selection needed either. 31163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng default: 31263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Log.w(TAG, "Unsupported filter type came " + 31363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng "(type: " + filter.filterType + ", toString: " + filter + ")" + 31463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng " showing all contacts."); 31563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // No selection. 31663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng break; 31763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 31863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng loader.setSelection(selection.toString()); 31963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng loader.setSelectionArgs(selectionArgs.toArray(new String[0])); 32063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 32163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 32263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng @Override 32363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public String getContactDisplayName(int position) { 3247a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner return ((Cursor) getItem(position)).getString(PhoneQuery.DISPLAY_NAME); 3257a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 3267a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner 3277a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public String getPhoneNumber(int position) { 3287a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final Cursor item = (Cursor)getItem(position); 3297a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner return item != null ? item.getString(PhoneQuery.PHONE_NUMBER) : null; 33063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 33163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 33263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng /** 33363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * Builds a {@link Data#CONTENT_URI} for the given cursor position. 33463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * 33563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng * @return Uri for the data. may be null if the cursor is not ready. 33663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng */ 33763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public Uri getDataUri(int position) { 3387a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final int partitionIndex = getPartitionForPosition(position); 3397a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final Cursor item = (Cursor)getItem(position); 3407a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner return item != null ? getDataUri(partitionIndex, item) : null; 3417a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 3427a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner 3437a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner public Uri getDataUri(int partitionIndex, Cursor cursor) { 3446af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert final long directoryId = 3456af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert ((DirectoryPartition)getPartition(partitionIndex)).getDirectoryId(); 346bf0104458b0c59762f0fc9df8c9012fca33220abRicky Wai if (DirectoryCompat.isRemoteDirectoryId(directoryId)) { 347d19d35ef8347038f5296ed7020cab79396874937Victor Chang return null; 348d19d35ef8347038f5296ed7020cab79396874937Victor Chang } else if (DirectoryCompat.isEnterpriseDirectoryId(directoryId)) { 349d19d35ef8347038f5296ed7020cab79396874937Victor Chang /* 350d19d35ef8347038f5296ed7020cab79396874937Victor Chang * ContentUris.withAppendedId(Data.CONTENT_URI, phoneId), is invalid if 351d19d35ef8347038f5296ed7020cab79396874937Victor Chang * isEnterpriseDirectoryId returns true, because the uri itself will fail since the 352d19d35ef8347038f5296ed7020cab79396874937Victor Chang * ContactsProvider in Android Framework currently doesn't support it. return null until 353d19d35ef8347038f5296ed7020cab79396874937Victor Chang * Android framework has enterprise version of Data.CONTENT_URI 354d19d35ef8347038f5296ed7020cab79396874937Victor Chang */ 355d19d35ef8347038f5296ed7020cab79396874937Victor Chang return null; 356d19d35ef8347038f5296ed7020cab79396874937Victor Chang } else { 3577a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final long phoneId = cursor.getLong(PhoneQuery.PHONE_ID); 3587a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner return ContentUris.withAppendedId(Data.CONTENT_URI, phoneId); 35963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 36063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 36163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 3626a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn /** 3636a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * Retrieves the lookup key for the given cursor position. 3646a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * 3656a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * @param position The cursor position. 3666a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn * @return The lookup key. 3676a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn */ 3686a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn public String getLookupKey(int position) { 3696a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn final Cursor item = (Cursor)getItem(position); 3706a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn return item != null ? item.getString(PhoneQuery.LOOKUP_KEY) : null; 3716a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn } 3726a5cdf69228f23ecd0d13019ac7bcc16ccf375cdTyler Gunn 37363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng @Override 3741f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee protected ContactListItemView newView( 3751f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee Context context, int partition, Cursor cursor, int position, ViewGroup parent) { 3761f1e90d36fe914a7ce51e6f9884199580115d891Andrew Lee ContactListItemView view = super.newView(context, partition, cursor, position, parent); 37763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.setUnknownNameText(mUnknownNameText); 37863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.setQuickContactEnabled(isQuickContactEnabled()); 37963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.setPhotoPosition(mPhotoPosition); 38063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng return view; 38163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 38263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 383a81953a2b1818066ef5e44817f374ac288bab343Christine Chen protected void setHighlight(ContactListItemView view, Cursor cursor) { 384a81953a2b1818066ef5e44817f374ac288bab343Christine Chen view.setHighlightedPrefix(isSearchMode() ? getUpperCaseQueryString() : null); 385a81953a2b1818066ef5e44817f374ac288bab343Christine Chen } 386a81953a2b1818066ef5e44817f374ac288bab343Christine Chen 387f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner // Override default, which would return number of phone numbers, so we 388f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner // instead return number of contacts. 389f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner @Override 390f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner protected int getResultCount(Cursor cursor) { 391f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner if (cursor == null) { 392f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner return 0; 393f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner } 394f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner cursor.moveToPosition(-1); 395f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner long curContactId = -1; 396f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner int numContacts = 0; 397f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner while(cursor.moveToNext()) { 398f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner final long contactId = cursor.getLong(PhoneQuery.CONTACT_ID); 399f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner if (contactId != curContactId) { 400f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner curContactId = contactId; 401f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner ++numContacts; 402f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner } 403f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner } 404f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner return numContacts; 405f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner } 406f210d229b042bef22863712b97a6cb20eaa2eadfJay Shrauner 40763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng @Override 40863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng protected void bindView(View itemView, int partition, Cursor cursor, int position) { 409aca984b5bc95a5e3c82ab79319694cb60b443315Brian Attwell super.bindView(itemView, partition, cursor, position); 41063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng ContactListItemView view = (ContactListItemView)itemView; 41163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 412a81953a2b1818066ef5e44817f374ac288bab343Christine Chen setHighlight(view, cursor); 41363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 41463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // Look at elements before and after this position, checking if contact IDs are same. 41563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // If they have one same contact ID, it means they can be grouped. 41663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // 41763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // In one group, only the first entry will show its photo and its name, and the other 41863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // entries in the group show just their data (e.g. phone number, email address). 41963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng cursor.moveToPosition(position); 42063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng boolean isFirstEntry = true; 42163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng boolean showBottomDivider = true; 4227a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final long currentContactId = cursor.getLong(PhoneQuery.CONTACT_ID); 42363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (cursor.moveToPrevious() && !cursor.isBeforeFirst()) { 4247a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final long previousContactId = cursor.getLong(PhoneQuery.CONTACT_ID); 42563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (currentContactId == previousContactId) { 42663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng isFirstEntry = false; 42763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 42863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 42963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng cursor.moveToPosition(position); 43063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (cursor.moveToNext() && !cursor.isAfterLast()) { 4317a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final long nextContactId = cursor.getLong(PhoneQuery.CONTACT_ID); 43263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (currentContactId == nextContactId) { 43363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // The following entry should be in the same group, which means we don't want a 43463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // divider between them. 43563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // TODO: we want a different divider than the divider between groups. Just hiding 43663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // this divider won't be enough. 43763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng showBottomDivider = false; 43863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 43963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 44063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng cursor.moveToPosition(position); 44163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 4424cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell bindViewId(view, cursor, PhoneQuery.PHONE_ID); 4434cbafe71ec04d4a511fe894c46915bb69c91b804Brian Attwell 44463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng bindSectionHeaderAndDivider(view, position); 44563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (isFirstEntry) { 44663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng bindName(view, cursor); 44763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (isQuickContactEnabled()) { 4487a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner bindQuickContact(view, partition, cursor, PhoneQuery.PHOTO_ID, 4497a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner PhoneQuery.PHOTO_URI, PhoneQuery.CONTACT_ID, 4506084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee PhoneQuery.LOOKUP_KEY, PhoneQuery.DISPLAY_NAME); 45163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } else { 4527a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner if (getDisplayPhotos()) { 4537a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner bindPhoto(view, partition, cursor); 4547a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 45563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 45663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } else { 45763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng unbindName(view); 45863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 45963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.removePhotoView(true, false); 46063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 4616af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert 4626af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert final DirectoryPartition directory = (DirectoryPartition) getPartition(partition); 463e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn bindPhoneNumber(view, cursor, directory.isDisplayNumber(), position); 46463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 46563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 466e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn protected void bindPhoneNumber(ContactListItemView view, Cursor cursor, boolean displayNumber, 467e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn int position) { 46863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng CharSequence label = null; 4696af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert if (displayNumber && !cursor.isNull(PhoneQuery.PHONE_TYPE)) { 47063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng final int type = cursor.getInt(PhoneQuery.PHONE_TYPE); 47163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng final String customLabel = cursor.getString(PhoneQuery.PHONE_LABEL); 47263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 47363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // TODO cache 47463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng label = Phone.getTypeLabel(getContext().getResources(), type, customLabel); 47563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 47663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.setLabel(label); 4776af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert final String text; 4786af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert if (displayNumber) { 4796af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert text = cursor.getString(PhoneQuery.PHONE_NUMBER); 4806af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert } else { 4816af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert // Display phone label. If that's null, display geocoded location for the number 4826af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert final String phoneLabel = cursor.getString(PhoneQuery.PHONE_LABEL); 4836af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert if (phoneLabel != null) { 4846af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert text = phoneLabel; 4856af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert } else { 4866af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert final String phoneNumber = cursor.getString(PhoneQuery.PHONE_NUMBER); 4876af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert text = GeoUtil.getGeocodedLocationFor(mContext, phoneNumber); 4886af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert } 4896af66a800ccf7599ea37374c8fc99a1489ef8fcbAlon Albert } 49062dbbf2f10e0e3bcb4d699d859a71a68c896f4a7Andrew Lee view.setPhoneNumber(text, mCountryIso); 491e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 49292a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang if (CompatUtils.isVideoCompatible()) { 49392a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang // Determine if carrier presence indicates the number supports video calling. 49492a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang int carrierPresence = cursor.getInt(PhoneQuery.CARRIER_PRESENCE); 49592a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang boolean isPresent = (carrierPresence & Phone.CARRIER_PRESENCE_VT_CAPABLE) != 0; 496e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 49792a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang boolean isVideoIconShown = mIsVideoEnabled && ( 49892a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang mIsPresenceEnabled && isPresent || !mIsPresenceEnabled); 49992a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang view.setShowVideoCallIcon(isVideoIconShown, mListener, position); 50092a65fd6f8af0d357376f7a9c0d3eafad795e79cWenyi Wang } 50163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 50263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 50363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng protected void bindSectionHeaderAndDivider(final ContactListItemView view, int position) { 50463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng if (isSectionHeaderDisplayEnabled()) { 50563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng Placement placement = getItemPlacementInSection(position); 50663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.setSectionHeader(placement.firstInSection ? placement.sectionHeader : null); 50763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } else { 50863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.setSectionHeader(null); 50963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 51063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 51163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 51263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng protected void bindName(final ContactListItemView view, Cursor cursor) { 5137a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner view.showDisplayName(cursor, PhoneQuery.DISPLAY_NAME, getContactNameDisplayOrder()); 51463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng // Note: we don't show phonetic names any more (see issue 5265330) 51563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 51663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 51763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng protected void unbindName(final ContactListItemView view) { 51863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng view.hideDisplayName(); 51963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 52063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 521ad8ca26bd5a5fa5ab7e872ef4438b09fc21d90f0Tony Mak @Override 522ad8ca26bd5a5fa5ab7e872ef4438b09fc21d90f0Tony Mak protected void bindWorkProfileIcon(final ContactListItemView view, int partition) { 523d19d35ef8347038f5296ed7020cab79396874937Victor Chang final DirectoryPartition directory = (DirectoryPartition) getPartition(partition); 524d19d35ef8347038f5296ed7020cab79396874937Victor Chang final long directoryId = directory.getDirectoryId(); 525d19d35ef8347038f5296ed7020cab79396874937Victor Chang final long userType = ContactsUtils.determineUserType(directoryId, null); 52686e847593405bf39333af825cfa58b2ac057d4dfVictor Chang // Work directory must not be a extended directory. An extended directory is custom 52786e847593405bf39333af825cfa58b2ac057d4dfVictor Chang // directory in the app, but not a directory provided by framework. So it can't be 52886e847593405bf39333af825cfa58b2ac057d4dfVictor Chang // USER_TYPE_WORK. 52986e847593405bf39333af825cfa58b2ac057d4dfVictor Chang view.setWorkProfileIconEnabled( 53086e847593405bf39333af825cfa58b2ac057d4dfVictor Chang !isExtendedDirectory(directoryId) && userType == ContactsUtils.USER_TYPE_WORK); 531d19d35ef8347038f5296ed7020cab79396874937Victor Chang } 532d19d35ef8347038f5296ed7020cab79396874937Victor Chang 5337a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) { 5347a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner if (!isPhotoSupported(partitionIndex)) { 5357a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner view.removePhotoView(); 5367a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner return; 5377a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 5387a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner 53963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng long photoId = 0; 5407a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner if (!cursor.isNull(PhoneQuery.PHOTO_ID)) { 5417a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner photoId = cursor.getLong(PhoneQuery.PHOTO_ID); 54263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 54363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 5447a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner if (photoId != 0) { 5453f9c2f426058413055fa54c08c69ad9461717658Yorke Lee getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false, 5463f9c2f426058413055fa54c08c69ad9461717658Yorke Lee getCircularPhotos(), null); 5477a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } else { 5487a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final String photoUriString = cursor.getString(PhoneQuery.PHOTO_URI); 5497a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString); 5506084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee 5516084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee DefaultImageRequest request = null; 5526084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee if (photoUri == null) { 5536084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee final String displayName = cursor.getString(PhoneQuery.DISPLAY_NAME); 5546084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee final String lookupKey = cursor.getString(PhoneQuery.LOOKUP_KEY); 5551b1221ba8291599675cb1399713c966728ed3c52Brian Attwell request = new DefaultImageRequest(displayName, lookupKey, getCircularPhotos()); 5566084726fbdda78bdb16e2d4cc1c3b81c84fd5da1Yorke Lee } 5573f9c2f426058413055fa54c08c69ad9461717658Yorke Lee getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, false, 5583f9c2f426058413055fa54c08c69ad9461717658Yorke Lee getCircularPhotos(), request); 5597a160466a38bb631da02b7e93ab907eb2b3a2558Jay Shrauner } 56063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 56163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 56263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) { 56363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng mPhotoPosition = photoPosition; 56463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 56563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 56663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public ContactListItemView.PhotoPosition getPhotoPosition() { 56763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng return mPhotoPosition; 56863ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 56963ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 57063ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public void setUseCallableUri(boolean useCallableUri) { 57163ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng mUseCallableUri = useCallableUri; 57263ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 57363ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng 57463ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng public boolean usesCallableUri() { 57563ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng return mUseCallableUri; 57663ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng } 577ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad 578ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad /** 579ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * Override base implementation to inject extended directories between local & remote 580ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * directories. This is done in the following steps: 581ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * 1. Call base implementation to add directories from the cursor. 582ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * 2. Iterate all base directories and establish the following information: 583ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * a. The highest directory id so that we can assign unused id's to the extended directories. 584ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * b. The index of the last non-remote directory. This is where we will insert extended 585ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * directories. 586ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * 3. Iterate the extended directories and for each one, assign an ID and insert it in the 587ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad * proper location. 588ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad */ 589ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad @Override 590ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad public void changeDirectories(Cursor cursor) { 591ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad super.changeDirectories(cursor); 592ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (getDirectorySearchMode() == DirectoryListLoader.SEARCH_MODE_NONE) { 593ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad return; 594ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 595ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final int numExtendedDirectories = mExtendedDirectories.size(); 596ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (getPartitionCount() == cursor.getCount() + numExtendedDirectories) { 597ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // already added all directories; 598ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad return; 599ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 600ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // 601ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad mFirstExtendedDirectoryId = Long.MAX_VALUE; 602ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (numExtendedDirectories > 0) { 603ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // The Directory.LOCAL_INVISIBLE is not in the cursor but we can't reuse it's 604ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // "special" ID. 605ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad long maxId = Directory.LOCAL_INVISIBLE; 606ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad int insertIndex = 0; 607ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad for (int i = 0, n = getPartitionCount(); i < n; i++) { 608ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final DirectoryPartition partition = (DirectoryPartition) getPartition(i); 609ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final long id = partition.getDirectoryId(); 610ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (id > maxId) { 611ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad maxId = id; 612ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 613bf0104458b0c59762f0fc9df8c9012fca33220abRicky Wai if (!DirectoryCompat.isRemoteDirectoryId(id)) { 614ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // assuming remote directories come after local, we will end up with the index 615ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // where we should insert extended directories. This also works if there are no 616ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // remote directories at all. 617ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad insertIndex = i + 1; 618ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 619ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 620ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad // Extended directories ID's cannot collide with base directories 621ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad mFirstExtendedDirectoryId = maxId + 1; 622ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad for (int i = 0; i < numExtendedDirectories; i++) { 623ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final long id = mFirstExtendedDirectoryId + i; 624ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad final DirectoryPartition directory = mExtendedDirectories.get(i); 625ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad if (getPartitionByDirectoryId(id) == -1) { 626ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad addPartition(insertIndex, directory); 627ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad directory.setDirectoryId(id); 628ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 629ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 630ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 631ad582fa758c6a276c26c5cc52079613a653c81bfBen Gilad } 632b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert 63344192bbce136eda4305e8ffa2cafc7663b3e25d2Victor Chang @Override 634b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert protected Uri getContactUri(int partitionIndex, Cursor cursor, 635b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert int contactIdColumn, int lookUpKeyColumn) { 636b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert final DirectoryPartition directory = (DirectoryPartition) getPartition(partitionIndex); 637b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert final long directoryId = directory.getDirectoryId(); 638b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert if (!isExtendedDirectory(directoryId)) { 639b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert return super.getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn); 640b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert } 641b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert return Contacts.CONTENT_LOOKUP_URI.buildUpon() 642b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert .appendPath(Constants.LOOKUP_URI_ENCODED) 643b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert .appendQueryParameter(Directory.DISPLAY_NAME, directory.getLabel()) 644b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, 645b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert String.valueOf(directoryId)) 646a63fbce25ea8cdcd7f44a4d65e9bdf4aa81560dbYorke Lee .encodedFragment(cursor.getString(lookUpKeyColumn)) 647b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert .build(); 648b5632a6ebe19ba1627f0e850b00e0e9de0fcd3abAlon Albert } 649e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 650e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public Listener getListener() { 651e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn return mListener; 652e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 653e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn 654e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn public void setListener(Listener listener) { 655e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn mListener = listener; 656e31b0ea8b61d5744921ff7491d5dbe1a8273c05fTyler Gunn } 65763ac534dcf60e9a6c651ef2434557bec922b9a7dChiao Cheng} 658