RecipientAlternatesAdapter.java revision 9160cd5d914d6975a5e72920950bd007d05aa7ba
15f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira/* 25f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * Copyright (C) 2011 The Android Open Source Project 35f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * 45f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * Licensed under the Apache License, Version 2.0 (the "License"); 55f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * you may not use this file except in compliance with the License. 65f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * You may obtain a copy of the License at 75f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * 85f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 95f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * 105f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * Unless required by applicable law or agreed to in writing, software 115f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 125f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * See the License for the specific language governing permissions and 145f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira * limitations under the License. 155f2cc770801133c2db389ebe108063427d1cf6aaMindy Pereira */ 16699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 17699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereirapackage com.android.ex.chips; 18699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 19699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport com.android.ex.chips.BaseRecipientAdapter.EmailQuery; 20699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 21699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.content.Context; 22699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.database.Cursor; 23699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.provider.ContactsContract.CommonDataKinds.Email; 2477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereiraimport android.text.util.Rfc822Token; 2577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereiraimport android.text.util.Rfc822Tokenizer; 264f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereiraimport android.util.Log; 27699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.view.LayoutInflater; 28699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.view.View; 29699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.view.ViewGroup; 30699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.widget.CursorAdapter; 3155bb2833b29945c08b809408ff94ddf7703e911aMindy Pereiraimport android.widget.ImageView; 32699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.widget.TextView; 33699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 3477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereiraimport java.util.HashMap; 3577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira 36699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereirapublic class RecipientAlternatesAdapter extends CursorAdapter { 3777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira static final int MAX_LOOKUPS = 50; 38699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira private final LayoutInflater mLayoutInflater; 39699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 40699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira private final int mLayoutId; 41699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 42699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira private final long mCurrentId; 43699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 44156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira private int mCheckedItemPosition = -1; 45156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira 463656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira private OnCheckedItemChangedListener mCheckedItemChangedListener; 473656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira 484f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira private static final String TAG = "RecipAlternates"; 494f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira 5077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira /** 5177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira * Get a HashMap of address to RecipientEntry that contains all contact 5277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira * information for a contact with the provided address, if one exists. This 5377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira * may block the UI, so run it in an async task. 5477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira * 5577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira * @param context Context. 568c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa * @param inAddresses Array of addresses on which to perform the lookup. 5777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira * @return HashMap<String,RecipientEntry> 5877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira */ 5977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira public static HashMap<String, RecipientEntry> getMatchingRecipients(Context context, 6077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira String[] inAddresses) { 6177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira int addressesSize = Math.min(MAX_LOOKUPS, inAddresses.length); 6277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira String[] addresses = new String[addressesSize]; 6377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira StringBuilder bindString = new StringBuilder(); 6477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira // Create the "?" string and set up arguments. 6577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira for (int i = 0; i < addressesSize; i++) { 6677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(inAddresses[i]); 6777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira addresses[i] = (tokens.length > 0 ? tokens[0].getAddress() : inAddresses[i]); 6877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira bindString.append("?"); 6977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira if (i < addressesSize - 1) { 7077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira bindString.append(","); 7177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } 7277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } 7377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira 744f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira if (Log.isLoggable(TAG, Log.DEBUG)) { 754f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira Log.d(TAG, "Doing reverse lookup for " + addresses.toString()); 764f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira } 774f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira 788c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>(); 7977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira Cursor c = context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION, 8077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira Email.ADDRESS + " IN (" + bindString.toString() + ")", addresses, null); 8177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira if (c != null) { 8277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira try { 8377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira if (c.moveToFirst()) { 8477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira do { 8577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira String address = c.getString(EmailQuery.ADDRESS); 8677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira recipientEntries.put(address, RecipientEntry.constructTopLevelEntry( 8777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira c.getString(EmailQuery.NAME), 8877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira c.getString(EmailQuery.ADDRESS), 898c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa c.getInt(EmailQuery.ADDRESS_TYPE), 908c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa c.getString(EmailQuery.ADDRESS_LABEL), 9177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira c.getLong(EmailQuery.CONTACT_ID), 9277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira c.getLong(EmailQuery.DATA_ID), 9377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira c.getString(EmailQuery.PHOTO_THUMBNAIL_URI))); 944f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira if (Log.isLoggable(TAG, Log.DEBUG)) { 954f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira Log.d(TAG, "Received reverse look up information for " + address 964f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira + " RESULTS: " 974f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira + " NAME : " + c.getString(EmailQuery.NAME) 984f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira + " CONTACT ID : " + c.getLong(EmailQuery.CONTACT_ID) 994f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira + " ADDRESS :" + c.getString(EmailQuery.ADDRESS)); 1004f36b72bcfe3e9f9b9d99a5872de0522f20c7a6cMindy Pereira } 10177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } while (c.moveToNext()); 10277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } 10377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } finally { 10477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira c.close(); 10577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } 10677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } 10777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira return recipientEntries; 10877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira } 10977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira 1103656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId, 1113656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira OnCheckedItemChangedListener listener) { 112699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira super(context, context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION, 113699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira Email.CONTACT_ID + " =?", new String[] { 114699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira String.valueOf(contactId) 115699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira }, null), 0); 116699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira mLayoutInflater = LayoutInflater.from(context); 117699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira mLayoutId = viewId; 118699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira mCurrentId = currentId; 1193656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira mCheckedItemChangedListener = listener; 120699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 121699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 122699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira @Override 123699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira public long getItemId(int position) { 124699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira Cursor c = getCursor(); 1250fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira if (c.moveToPosition(position)) { 1260fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira c.getLong(EmailQuery.DATA_ID); 1270fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira } 1280fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira return -1; 129699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 130699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 131699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira public RecipientEntry getRecipientEntry(int position) { 132699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira Cursor c = getCursor(); 133699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira c.moveToPosition(position); 1348c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa return RecipientEntry.constructTopLevelEntry(c.getString(EmailQuery.NAME), 1358c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa c.getString(EmailQuery.ADDRESS), c.getInt(EmailQuery.ADDRESS_TYPE), 1368c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa c.getString(EmailQuery.ADDRESS_LABEL), 1378c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa c.getLong(EmailQuery.CONTACT_ID), c.getLong(EmailQuery.DATA_ID), 1388c03d35fec744db28a2a3230795f123c7afd50ccDaisuke Miyakawa c.getString(EmailQuery.PHOTO_THUMBNAIL_URI)); 139699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 140699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 141699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira @Override 142699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira public View getView(int position, View convertView, ViewGroup parent) { 14355bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira Cursor cursor = getCursor(); 14455bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira cursor.moveToPosition(position); 145699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira if (convertView == null) { 146156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira convertView = newView(); 147156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira } 148156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira if (cursor.getLong(EmailQuery.DATA_ID) == mCurrentId) { 149156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira mCheckedItemPosition = position; 1503656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira if (mCheckedItemChangedListener != null) { 1513656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition); 1523656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira } 153699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 15455bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira bindView(convertView, convertView.getContext(), cursor); 155699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira return convertView; 156699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 157699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 15855bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira // TODO: this is VERY similar to the BaseRecipientAdapter. Can we combine 15955bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira // somehow? 160699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira @Override 161699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira public void bindView(View view, Context context, Cursor cursor) { 16255bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira int position = cursor.getPosition(); 16355bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira 1649160cd5d914d6975a5e72920950bd007d05aa7baDaisuke Miyakawa TextView display = (TextView) view.findViewById(android.R.id.title); 16555bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira ImageView imageView = (ImageView) view.findViewById(android.R.id.icon); 16655bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira RecipientEntry entry = getRecipientEntry(position); 16755bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira if (position == 0) { 16855bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira display.setText(cursor.getString(EmailQuery.NAME)); 16955bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira display.setVisibility(View.VISIBLE); 17055bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira // TODO: see if this needs to be done outside the main thread 17155bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira // as it may be too slow to get immediately. 17255bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira imageView.setImageURI(entry.getPhotoThumbnailUri()); 17355bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira imageView.setVisibility(View.VISIBLE); 17455bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira } else { 17555bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira display.setVisibility(View.GONE); 17655bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira imageView.setVisibility(View.GONE); 17755bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira } 1789160cd5d914d6975a5e72920950bd007d05aa7baDaisuke Miyakawa TextView destination = (TextView) view.findViewById(android.R.id.text1); 179699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira destination.setText(cursor.getString(EmailQuery.ADDRESS)); 1809160cd5d914d6975a5e72920950bd007d05aa7baDaisuke Miyakawa 1819160cd5d914d6975a5e72920950bd007d05aa7baDaisuke Miyakawa TextView destinationType = (TextView) view.findViewById(android.R.id.text2); 1829160cd5d914d6975a5e72920950bd007d05aa7baDaisuke Miyakawa destinationType.setText(Email.getTypeLabel(context.getResources(), 1839160cd5d914d6975a5e72920950bd007d05aa7baDaisuke Miyakawa cursor.getInt(EmailQuery.ADDRESS_TYPE), 1849160cd5d914d6975a5e72920950bd007d05aa7baDaisuke Miyakawa cursor.getString(EmailQuery.ADDRESS_LABEL))); 185699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 186699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 187699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira @Override 188699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira public View newView(Context context, Cursor cursor, ViewGroup parent) { 189156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira return newView(); 190156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira } 191156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira 192156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira private View newView() { 193156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira return mLayoutInflater.inflate(mLayoutId, null); 194699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 195699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira 1963656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira /*package*/ static interface OnCheckedItemChangedListener { 1973656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira public void onCheckedItemChanged(int position); 198699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira } 199699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira} 200