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