RecipientAlternatesAdapter.java revision 76f1f2d4eb66956814254b0e4f86da7aa8261bcb
184dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira/* 284dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * Copyright (C) 2011 The Android Open Source Project 384dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * 484dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * Licensed under the Apache License, Version 2.0 (the "License"); 584dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * you may not use this file except in compliance with the License. 684dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * You may obtain a copy of the License at 784dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * 884dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 984dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * 1084dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * Unless required by applicable law or agreed to in writing, software 1184dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 1284dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1384dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * See the License for the specific language governing permissions and 1484dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * limitations under the License. 1584dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira */ 1697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 1797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereirapackage com.android.ex.chips; 1897d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 1916923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.accounts.Account; 2016923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.content.ContentResolver; 2197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.content.Context; 2297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.database.Cursor; 23a5d37c8a968edf94755215617b593d3f61738a92Makoto Onukiimport android.database.MatrixCursor; 2416923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.net.Uri; 2516923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.provider.ContactsContract; 26ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedyimport android.text.TextUtils; 271852931de1e24e77cb708f4ba010eaa269426657Mindy Pereiraimport android.text.util.Rfc822Token; 281852931de1e24e77cb708f4ba010eaa269426657Mindy Pereiraimport android.text.util.Rfc822Tokenizer; 2918987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereiraimport android.util.Log; 3097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.view.LayoutInflater; 3197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.view.View; 3297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.view.ViewGroup; 3397d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.widget.CursorAdapter; 3467ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereiraimport android.widget.ImageView; 3597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.widget.TextView; 3697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 3716923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport com.android.ex.chips.BaseRecipientAdapter.DirectoryListQuery; 3816923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport com.android.ex.chips.BaseRecipientAdapter.DirectorySearchParams; 3980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylorimport com.android.ex.chips.Queries.Query; 40a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki 4103cfe3eee5635e419ab1d70d463b2b8beac72f00Mindy Pereiraimport java.util.ArrayList; 421852931de1e24e77cb708f4ba010eaa269426657Mindy Pereiraimport java.util.HashMap; 43a5d37c8a968edf94755215617b593d3f61738a92Makoto Onukiimport java.util.HashSet; 4416923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport java.util.List; 4594fa301de71cc110671802eba8376c275b4055a4Scott Kennedyimport java.util.Map; 4694fa301de71cc110671802eba8376c275b4055a4Scott Kennedyimport java.util.Set; 471852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira 4880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor/** 4980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor * RecipientAlternatesAdapter backs the RecipientEditTextView for managing contacts 5080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor * queried by email or by phone number. 5180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor */ 5297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereirapublic class RecipientAlternatesAdapter extends CursorAdapter { 531852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira static final int MAX_LOOKUPS = 50; 5497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira private final LayoutInflater mLayoutInflater; 5597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 5697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira private final long mCurrentId; 5797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 58007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira private int mCheckedItemPosition = -1; 59007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira 605086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira private OnCheckedItemChangedListener mCheckedItemChangedListener; 615086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira 6218987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira private static final String TAG = "RecipAlternates"; 6318987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira 6480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor public static final int QUERY_TYPE_EMAIL = 0; 6580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor public static final int QUERY_TYPE_PHONE = 1; 6680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor private Query mQuery; 6780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor 6816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp public interface RecipientMatchCallback { 6994fa301de71cc110671802eba8376c275b4055a4Scott Kennedy public void matchesFound(Map<String, RecipientEntry> results); 7094fa301de71cc110671802eba8376c275b4055a4Scott Kennedy /** 7194fa301de71cc110671802eba8376c275b4055a4Scott Kennedy * Called with all addresses that could not be resolved to valid recipients. 7294fa301de71cc110671802eba8376c275b4055a4Scott Kennedy */ 73f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy public void matchesNotFound(Set<String> unfoundAddresses); 7416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 7516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp 7676f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert public static void getMatchingRecipients(Context context, BaseRecipientAdapter adapter, 7776f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert ArrayList<String> inAddresses, Account account, RecipientMatchCallback callback) { 7876f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert getMatchingRecipients(context, adapter, inAddresses, QUERY_TYPE_EMAIL, account, callback); 7980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } 8080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor 811852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira /** 821852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira * Get a HashMap of address to RecipientEntry that contains all contact 831852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira * information for a contact with the provided address, if one exists. This 841852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira * may block the UI, so run it in an async task. 851852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira * 861852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira * @param context Context. 877211747e51623ae1305053f533c09dd335e013a2Daisuke Miyakawa * @param inAddresses Array of addresses on which to perform the lookup. 8816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp * @param callback RecipientMatchCallback called when a match or matches are found. 891852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira * @return HashMap<String,RecipientEntry> 901852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira */ 9176f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert public static void getMatchingRecipients(Context context, BaseRecipientAdapter adapter, 9276f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert ArrayList<String> inAddresses, int addressType, Account account, 9376f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert RecipientMatchCallback callback) { 9480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor Queries.Query query; 9580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor if (addressType == QUERY_TYPE_EMAIL) { 9680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor query = Queries.EMAIL; 9780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } else { 9880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor query = Queries.PHONE; 9980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } 10003cfe3eee5635e419ab1d70d463b2b8beac72f00Mindy Pereira int addressesSize = Math.min(MAX_LOOKUPS, inAddresses.size()); 10116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp HashSet<String> addresses = new HashSet<String>(); 1021852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira StringBuilder bindString = new StringBuilder(); 1031852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira // Create the "?" string and set up arguments. 1041852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira for (int i = 0; i < addressesSize; i++) { 10503cfe3eee5635e419ab1d70d463b2b8beac72f00Mindy Pereira Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(inAddresses.get(i).toLowerCase()); 10616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp addresses.add(tokens.length > 0 ? tokens[0].getAddress() : inAddresses.get(i)); 1071852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira bindString.append("?"); 1081852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira if (i < addressesSize - 1) { 1091852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira bindString.append(","); 1101852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira } 1111852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira } 1121852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira 11318987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira if (Log.isLoggable(TAG, Log.DEBUG)) { 11418987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira Log.d(TAG, "Doing reverse lookup for " + addresses.toString()); 11518987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira } 11618987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira 11716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp String[] addressArray = new String[addresses.size()]; 11816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp addresses.toArray(addressArray); 11916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp HashMap<String, RecipientEntry> recipientEntries = null; 12016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp Cursor c = null; 12116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp 12216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp try { 12316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c = context.getContentResolver().query( 12416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp query.getContentUri(), 12516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp query.getProjection(), 12616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp query.getProjection()[Queries.Query.DESTINATION] + " IN (" 12716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp + bindString.toString() + ")", addressArray, null); 12816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp recipientEntries = processContactEntries(c); 12916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp callback.matchesFound(recipientEntries); 13016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } finally { 13116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp if (c != null) { 13216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.close(); 13316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 13416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 13516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp // See if any entries did not resolve; if so, we need to check other 13616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp // directories 13794fa301de71cc110671802eba8376c275b4055a4Scott Kennedy final Set<String> matchesNotFound = new HashSet<String>(); 13816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp if (recipientEntries.size() < addresses.size()) { 13916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp final List<DirectorySearchParams> paramsList; 140539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy Cursor directoryCursor = null; 141539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy try { 142539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy directoryCursor = context.getContentResolver().query(DirectoryListQuery.URI, 143539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy DirectoryListQuery.PROJECTION, null, null, null); 144771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy if (directoryCursor == null) { 145771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy paramsList = null; 146771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } else { 147771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy paramsList = BaseRecipientAdapter.setupOtherDirectories(context, 148771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy directoryCursor, account); 149771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } 150539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy } finally { 151539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy if (directoryCursor != null) { 152539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy directoryCursor.close(); 153539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy } 154539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy } 15516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp // Run a directory query for each unmatched recipient. 15616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp HashSet<String> unresolvedAddresses = new HashSet<String>(); 15716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp for (String address : addresses) { 15816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp if (!recipientEntries.containsKey(address)) { 15916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp unresolvedAddresses.add(address); 16016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 16116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 16294fa301de71cc110671802eba8376c275b4055a4Scott Kennedy 16394fa301de71cc110671802eba8376c275b4055a4Scott Kennedy matchesNotFound.addAll(unresolvedAddresses); 16494fa301de71cc110671802eba8376c275b4055a4Scott Kennedy 165771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy if (paramsList != null) { 166771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy Cursor directoryContactsCursor = null; 167771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy for (String unresolvedAddress : unresolvedAddresses) { 168771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy for (int i = 0; i < paramsList.size(); i++) { 169771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy try { 170771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy directoryContactsCursor = doQuery(unresolvedAddress, 1, 171771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy paramsList.get(i).directoryId, account, 172771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy context.getContentResolver(), query); 173771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } finally { 174771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy if (directoryContactsCursor != null 175771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy && directoryContactsCursor.getCount() == 0) { 176771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy directoryContactsCursor.close(); 177771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy directoryContactsCursor = null; 178771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } else { 179771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy break; 180771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } 18118987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira } 18216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 183771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy if (directoryContactsCursor != null) { 184771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy try { 185771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy final Map<String, RecipientEntry> entries = 186771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy processContactEntries(directoryContactsCursor); 18794fa301de71cc110671802eba8376c275b4055a4Scott Kennedy 188771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy for (final String address : entries.keySet()) { 189771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy matchesNotFound.remove(address); 190771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } 19194fa301de71cc110671802eba8376c275b4055a4Scott Kennedy 192771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy callback.matchesFound(entries); 193771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } finally { 194771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy directoryContactsCursor.close(); 195771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy } 19616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 1971852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira } 1981852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira } 1991852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira } 20094fa301de71cc110671802eba8376c275b4055a4Scott Kennedy 20176f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert // If no matches found in contact provider or the directories, try the extension 20276f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert // matcher. 20376f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert // todo (aalbert): This whole method needs to be in the adapter? 20476f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert if (adapter != null) { 20576f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert final Map<String, RecipientEntry> entries = 20676f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert adapter.getMatchingRecipients(matchesNotFound); 20776f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert if (entries != null && entries.size() > 0) { 20876f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert callback.matchesFound(entries); 20976f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert for (final String address : entries.keySet()) { 21076f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert matchesNotFound.remove(address); 21176f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert } 21276f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert } 21376f1f2d4eb66956814254b0e4f86da7aa8261bcbAlon Albert } 21494fa301de71cc110671802eba8376c275b4055a4Scott Kennedy callback.matchesNotFound(matchesNotFound); 21516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 21616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp 21716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp private static HashMap<String, RecipientEntry> processContactEntries(Cursor c) { 21816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>(); 21916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp if (c != null && c.moveToFirst()) { 22016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp do { 22116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp String address = c.getString(Queries.Query.DESTINATION); 222ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 223ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy final RecipientEntry newRecipientEntry = RecipientEntry.constructTopLevelEntry( 22416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getString(Queries.Query.NAME), 22516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getInt(Queries.Query.DISPLAY_NAME_SOURCE), 22616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getString(Queries.Query.DESTINATION), 22716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getInt(Queries.Query.DESTINATION_TYPE), 22816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getString(Queries.Query.DESTINATION_LABEL), 22916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getLong(Queries.Query.CONTACT_ID), 23016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getLong(Queries.Query.DATA_ID), 23116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp c.getString(Queries.Query.PHOTO_THUMBNAIL_URI), 232ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy true); 233ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 234ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy /* 235ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy * In certain situations, we may have two results for one address, where one of the 236ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy * results is just the email address, and the other has a name and photo, so we want 237ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy * to use the better one. 238ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy */ 239ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy final RecipientEntry recipientEntry = 240ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy getBetterRecipient(recipientEntries.get(address), newRecipientEntry); 241ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 242ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy recipientEntries.put(address, recipientEntry); 24316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp if (Log.isLoggable(TAG, Log.DEBUG)) { 24416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp Log.d(TAG, "Received reverse look up information for " + address 24516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp + " RESULTS: " 24616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp + " NAME : " + c.getString(Queries.Query.NAME) 24716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp + " CONTACT ID : " + c.getLong(Queries.Query.CONTACT_ID) 24816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp + " ADDRESS :" + c.getString(Queries.Query.DESTINATION)); 24916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 25016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } while (c.moveToNext()); 25116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 2521852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira return recipientEntries; 2531852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira } 2541852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira 255ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy /** 256ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy * Given two {@link RecipientEntry}s for the same email address, this will return the one that 257ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy * contains more complete information for display purposes. Defaults to <code>entry2</code> if 258ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy * no significant differences are found. 259ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy */ 26078f38a09c9753c0ac1838ce0bfd3a6bc1a307ff7Scott Kennedy static RecipientEntry getBetterRecipient(final RecipientEntry entry1, 261ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy final RecipientEntry entry2) { 262ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy // If only one has passed in, use it 263ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if (entry2 == null) { 264ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry1; 265ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 266ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 267ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if (entry1 == null) { 268ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry2; 269ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 270ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 271ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy // If only one has a display name, use it 272ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if (!TextUtils.isEmpty(entry1.getDisplayName()) 273ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy && TextUtils.isEmpty(entry2.getDisplayName())) { 274ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry1; 275ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 276ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 277ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if (!TextUtils.isEmpty(entry2.getDisplayName()) 278ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy && TextUtils.isEmpty(entry1.getDisplayName())) { 279ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry2; 280ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 281ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 282ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy // If only one has a display name that is not the same as the destination, use it 283ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if (!TextUtils.equals(entry1.getDisplayName(), entry1.getDestination()) 284ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy && TextUtils.equals(entry2.getDisplayName(), entry2.getDestination())) { 285ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry1; 286ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 287ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 288ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if (!TextUtils.equals(entry2.getDisplayName(), entry2.getDestination()) 289ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy && TextUtils.equals(entry1.getDisplayName(), entry1.getDestination())) { 290ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry2; 291ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 292ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 293ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy // If only one has a photo, use it 294ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if ((entry1.getPhotoThumbnailUri() != null || entry1.getPhotoBytes() != null) 295ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy && (entry2.getPhotoThumbnailUri() == null && entry2.getPhotoBytes() == null)) { 296ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry1; 297ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 298ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 299ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy if ((entry2.getPhotoThumbnailUri() != null || entry2.getPhotoBytes() != null) 300ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy && (entry1.getPhotoThumbnailUri() == null && entry1.getPhotoBytes() == null)) { 301ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry2; 302ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 303ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 304ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy // Go with the second option as a default 305ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy return entry2; 306ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy } 307ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy 30816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp private static Cursor doQuery(CharSequence constraint, int limit, Long directoryId, 30916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp Account account, ContentResolver resolver, Query query) { 31016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp final Uri.Builder builder = query 31116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp .getContentFilterUri() 31216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp .buildUpon() 31316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp .appendPath(constraint.toString()) 31416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, 31516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp String.valueOf(limit + BaseRecipientAdapter.ALLOWANCE_FOR_DUPLICATES)); 31616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp if (directoryId != null) { 31716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, 31816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp String.valueOf(directoryId)); 31916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 32016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp if (account != null) { 32116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_NAME, account.name); 32216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_TYPE, account.type); 32316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 32416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp final Cursor cursor = resolver.query(builder.build(), query.getProjection(), null, null, 32516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp null); 32616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp return cursor; 32716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp } 32816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp 329f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy public RecipientAlternatesAdapter(Context context, long contactId, long currentId, 3305086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira OnCheckedItemChangedListener listener) { 331f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy this(context, contactId, currentId, QUERY_TYPE_EMAIL, listener); 33280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } 33380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor 334f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy public RecipientAlternatesAdapter(Context context, long contactId, long currentId, 33580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor int queryMode, OnCheckedItemChangedListener listener) { 33680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor super(context, getCursorForConstruction(context, contactId, queryMode), 0); 33797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira mLayoutInflater = LayoutInflater.from(context); 33897d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira mCurrentId = currentId; 3395086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira mCheckedItemChangedListener = listener; 34080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor 34180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor if (queryMode == QUERY_TYPE_EMAIL) { 34280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor mQuery = Queries.EMAIL; 34380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } else if (queryMode == QUERY_TYPE_PHONE) { 34480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor mQuery = Queries.PHONE; 34580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } else { 34680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor mQuery = Queries.EMAIL; 34780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor Log.e(TAG, "Unsupported query type: " + queryMode); 34880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } 34980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } 35080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor 35180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor private static Cursor getCursorForConstruction(Context context, long contactId, int queryType) { 352a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki final Cursor cursor; 35380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor if (queryType == QUERY_TYPE_EMAIL) { 354a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki cursor = context.getContentResolver().query( 35580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor Queries.EMAIL.getContentUri(), 35680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor Queries.EMAIL.getProjection(), 357a62ba492f901e024b249e0138e96374b09766a36Mindy Pereira Queries.EMAIL.getProjection()[Queries.Query.CONTACT_ID] + " =?", new String[] { 35880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor String.valueOf(contactId) 35980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor }, null); 36080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } else { 361a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki cursor = context.getContentResolver().query( 36280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor Queries.PHONE.getContentUri(), 36380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor Queries.PHONE.getProjection(), 3649c17ab5f3bf0f88e3641faf98931c4f9e7d65366Tom Taylor Queries.PHONE.getProjection()[Queries.Query.CONTACT_ID] + " =?", new String[] { 36580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor String.valueOf(contactId) 36680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor }, null); 36780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor } 368a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki return removeDuplicateDestinations(cursor); 369a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki } 370a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki 371a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki /** 372a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * @return a new cursor based on the given cursor with all duplicate destinations removed. 373a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * 374a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * It's only intended to use for the alternate list, so... 375a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * - This method ignores all other fields and dedupe solely on the destination. Normally, 376a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * if a cursor contains multiple contacts and they have the same destination, we'd still want 377a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * to show both. 378a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * - This method creates a MatrixCursor, so all data will be kept in memory. We wouldn't want 379a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * to do this if the original cursor is large, but it's okay here because the alternate list 380a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki * won't be that big. 381a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki */ 382a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki // Visible for testing 383a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki /* package */ static Cursor removeDuplicateDestinations(Cursor original) { 384a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki final MatrixCursor result = new MatrixCursor( 385a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getColumnNames(), original.getCount()); 386a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki final HashSet<String> destinationsSeen = new HashSet<String>(); 387a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki 388a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.moveToPosition(-1); 389a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki while (original.moveToNext()) { 390a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki final String destination = original.getString(Query.DESTINATION); 391a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki if (destinationsSeen.contains(destination)) { 392a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki continue; 393a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki } 394a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki destinationsSeen.add(destination); 395a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki 396a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki result.addRow(new Object[] { 397a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getString(Query.NAME), 398a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getString(Query.DESTINATION), 399a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getInt(Query.DESTINATION_TYPE), 400a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getString(Query.DESTINATION_LABEL), 401a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getLong(Query.CONTACT_ID), 402a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getLong(Query.DATA_ID), 403a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getString(Query.PHOTO_THUMBNAIL_URI), 404a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki original.getInt(Query.DISPLAY_NAME_SOURCE) 405a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki }); 406a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki } 407a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki 408a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki return result; 40997d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 41097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 41197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira @Override 41297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira public long getItemId(int position) { 41397d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira Cursor c = getCursor(); 4143bb52162b7e842243d4a14e73c15b20dbd1804d7Mindy Pereira if (c.moveToPosition(position)) { 41580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor c.getLong(Queries.Query.DATA_ID); 4163bb52162b7e842243d4a14e73c15b20dbd1804d7Mindy Pereira } 4173bb52162b7e842243d4a14e73c15b20dbd1804d7Mindy Pereira return -1; 41897d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 41997d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 42097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira public RecipientEntry getRecipientEntry(int position) { 42197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira Cursor c = getCursor(); 42297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira c.moveToPosition(position); 42380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor return RecipientEntry.constructTopLevelEntry( 42480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor c.getString(Queries.Query.NAME), 42500adb32f3cea49ec82467c0e1a9e42659b556836Makoto Onuki c.getInt(Queries.Query.DISPLAY_NAME_SOURCE), 42680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor c.getString(Queries.Query.DESTINATION), 42780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor c.getInt(Queries.Query.DESTINATION_TYPE), 42880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor c.getString(Queries.Query.DESTINATION_LABEL), 42980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor c.getLong(Queries.Query.CONTACT_ID), 43080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor c.getLong(Queries.Query.DATA_ID), 431ccb8e237ec80934d1c983bb61f66b75541786ddcmindyp c.getString(Queries.Query.PHOTO_THUMBNAIL_URI), 432ccb8e237ec80934d1c983bb61f66b75541786ddcmindyp true); 43397d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 43497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 43597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira @Override 43697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira public View getView(int position, View convertView, ViewGroup parent) { 43767ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira Cursor cursor = getCursor(); 43867ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira cursor.moveToPosition(position); 43997d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira if (convertView == null) { 440007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira convertView = newView(); 441007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira } 44280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor if (cursor.getLong(Queries.Query.DATA_ID) == mCurrentId) { 443007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira mCheckedItemPosition = position; 4445086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira if (mCheckedItemChangedListener != null) { 4455086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition); 4465086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira } 44797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 44867ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira bindView(convertView, convertView.getContext(), cursor); 44997d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira return convertView; 45097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 45197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 45267ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira // TODO: this is VERY similar to the BaseRecipientAdapter. Can we combine 45367ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira // somehow? 45497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira @Override 45597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira public void bindView(View view, Context context, Cursor cursor) { 45667ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira int position = cursor.getPosition(); 45767ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira 458102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa TextView display = (TextView) view.findViewById(android.R.id.title); 45967ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira ImageView imageView = (ImageView) view.findViewById(android.R.id.icon); 46067ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira RecipientEntry entry = getRecipientEntry(position); 46167ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira if (position == 0) { 46280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor display.setText(cursor.getString(Queries.Query.NAME)); 46367ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira display.setVisibility(View.VISIBLE); 46467ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira // TODO: see if this needs to be done outside the main thread 46567ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira // as it may be too slow to get immediately. 46667ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira imageView.setImageURI(entry.getPhotoThumbnailUri()); 46767ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira imageView.setVisibility(View.VISIBLE); 46867ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira } else { 46967ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira display.setVisibility(View.GONE); 47067ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira imageView.setVisibility(View.GONE); 47167ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira } 472102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa TextView destination = (TextView) view.findViewById(android.R.id.text1); 47380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor destination.setText(cursor.getString(Queries.Query.DESTINATION)); 474102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa 475102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa TextView destinationType = (TextView) view.findViewById(android.R.id.text2); 476f908b64e75e0bb38ff2806232ca57c93189156eaMindy Pereira if (destinationType != null) { 47780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor destinationType.setText(mQuery.getTypeLabel(context.getResources(), 47880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor cursor.getInt(Queries.Query.DESTINATION_TYPE), 47980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor cursor.getString(Queries.Query.DESTINATION_LABEL)).toString().toUpperCase()); 480f908b64e75e0bb38ff2806232ca57c93189156eaMindy Pereira } 48197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 48297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 48397d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira @Override 48497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira public View newView(Context context, Cursor cursor, ViewGroup parent) { 485007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira return newView(); 486007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira } 487007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira 488007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira private View newView() { 48952c441e2c03e0f48572348953b985a4bf989c057Mindy Pereira return mLayoutInflater.inflate(R.layout.chips_recipient_dropdown_item, null); 49097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 49197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira 4925086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira /*package*/ static interface OnCheckedItemChangedListener { 4935086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira public void onCheckedItemChanged(int position); 49497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira } 49597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira} 496