RecipientAlternatesAdapter.java revision 77056d7532cd26e869964a52456ef18c96f6cbd7
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;
26699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.view.LayoutInflater;
27699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.view.View;
28699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.view.ViewGroup;
29699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.widget.CursorAdapter;
3055bb2833b29945c08b809408ff94ddf7703e911aMindy Pereiraimport android.widget.ImageView;
31699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereiraimport android.widget.TextView;
32699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
3377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereiraimport java.util.HashMap;
3477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira
35699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereirapublic class RecipientAlternatesAdapter extends CursorAdapter {
3677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira    static final int MAX_LOOKUPS = 50;
37699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    private final LayoutInflater mLayoutInflater;
38699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
39699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    private final int mLayoutId;
40699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
41699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    private final long mCurrentId;
42699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
43156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira    private int mCheckedItemPosition = -1;
44156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira
453656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira    private OnCheckedItemChangedListener mCheckedItemChangedListener;
463656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira
4777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira    /**
4877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     * Get a HashMap of address to RecipientEntry that contains all contact
4977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     * information for a contact with the provided address, if one exists. This
5077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     * may block the UI, so run it in an async task.
5177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     *
5277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     * @param context Context.
5377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     * @param addresses Array of addresses on which to perform the lookup.
5477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     * @return HashMap<String,RecipientEntry>
5577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira     */
5677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira    public static HashMap<String, RecipientEntry> getMatchingRecipients(Context context,
5777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            String[] inAddresses) {
5877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        int addressesSize = Math.min(MAX_LOOKUPS, inAddresses.length);
5977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        String[] addresses = new String[addressesSize];
6077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        StringBuilder bindString = new StringBuilder();
6177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        // Create the "?" string and set up arguments.
6277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        for (int i = 0; i < addressesSize; i++) {
6377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(inAddresses[i]);
6477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            addresses[i] = (tokens.length > 0 ? tokens[0].getAddress() : inAddresses[i]);
6577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            bindString.append("?");
6677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            if (i < addressesSize - 1) {
6777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                bindString.append(",");
6877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            }
6977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        }
7077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira
7177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        Cursor c = context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION,
7277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                Email.ADDRESS + " IN (" + bindString.toString() + ")", addresses, null);
7377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>();
7477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        if (c != null) {
7577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            try {
7677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                if (c.moveToFirst()) {
7777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                    do {
7877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                        String address = c.getString(EmailQuery.ADDRESS);
7977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                        recipientEntries.put(address, RecipientEntry.constructTopLevelEntry(
8077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                                c.getString(EmailQuery.NAME),
8177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                                c.getString(EmailQuery.ADDRESS),
8277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                                c.getLong(EmailQuery.CONTACT_ID),
8377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                                c.getLong(EmailQuery.DATA_ID),
8477056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                                c.getString(EmailQuery.PHOTO_THUMBNAIL_URI)));
8577056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                    } while (c.moveToNext());
8677056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                }
8777056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            } finally {
8877056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira                c.close();
8977056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira            }
9077056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        }
9177056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira        return recipientEntries;
9277056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira    }
9377056d7532cd26e869964a52456ef18c96f6cbd7Mindy Pereira
943656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira    public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId,
953656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira            OnCheckedItemChangedListener listener) {
96699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        super(context, context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION,
97699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira                Email.CONTACT_ID + " =?", new String[] {
98699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira                    String.valueOf(contactId)
99699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira                }, null), 0);
100699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        mLayoutInflater = LayoutInflater.from(context);
101699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        mLayoutId = viewId;
102699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        mCurrentId = currentId;
1033656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira        mCheckedItemChangedListener = listener;
104699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    }
105699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
106699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    @Override
107699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    public long getItemId(int position) {
108699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        Cursor c = getCursor();
1090fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira        if (c.moveToPosition(position)) {
1100fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira            c.getLong(EmailQuery.DATA_ID);
1110fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira        }
1120fc929e5fb977fe028d7db04a3ad57e74f42e654Mindy Pereira        return -1;
113699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    }
114699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
115699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    public RecipientEntry getRecipientEntry(int position) {
116699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        Cursor c = getCursor();
117699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        c.moveToPosition(position);
118699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        return RecipientEntry.constructTopLevelEntry(c.getString(EmailQuery.NAME), c
119699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira                .getString(EmailQuery.ADDRESS), c.getLong(EmailQuery.CONTACT_ID), c
120699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira                .getLong(EmailQuery.DATA_ID), c.getString(EmailQuery.PHOTO_THUMBNAIL_URI));
121699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    }
122699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
123699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    @Override
124699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    public View getView(int position, View convertView, ViewGroup parent) {
12555bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        Cursor cursor = getCursor();
12655bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        cursor.moveToPosition(position);
127699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        if (convertView == null) {
128156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira            convertView = newView();
129156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira        }
130156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira        if (cursor.getLong(EmailQuery.DATA_ID) == mCurrentId) {
131156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira            mCheckedItemPosition = position;
1323656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira            if (mCheckedItemChangedListener != null) {
1333656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira                mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition);
1343656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira            }
135699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        }
13655bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        bindView(convertView, convertView.getContext(), cursor);
137699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        return convertView;
138699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    }
139699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
14055bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira    // TODO: this is VERY similar to the BaseRecipientAdapter. Can we combine
14155bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira    // somehow?
142699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    @Override
143699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    public void bindView(View view, Context context, Cursor cursor) {
14455bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        int position = cursor.getPosition();
14555bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira
14655bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        TextView display = (TextView) view.findViewById(android.R.id.text1);
14755bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
14855bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        RecipientEntry entry = getRecipientEntry(position);
14955bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        if (position == 0) {
15055bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            display.setText(cursor.getString(EmailQuery.NAME));
15155bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            display.setVisibility(View.VISIBLE);
15255bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            // TODO: see if this needs to be done outside the main thread
15355bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            // as it may be too slow to get immediately.
15455bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            imageView.setImageURI(entry.getPhotoThumbnailUri());
15555bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            imageView.setVisibility(View.VISIBLE);
15655bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        } else {
15755bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            display.setVisibility(View.GONE);
15855bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira            imageView.setVisibility(View.GONE);
15955bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        }
16055bb2833b29945c08b809408ff94ddf7703e911aMindy Pereira        TextView destination = (TextView) view.findViewById(android.R.id.text2);
161699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira        destination.setText(cursor.getString(EmailQuery.ADDRESS));
162699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    }
163699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
164699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    @Override
165699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    public View newView(Context context, Cursor cursor, ViewGroup parent) {
166156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira        return newView();
167156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira    }
168156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira
169156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira    private View newView() {
170156467329e276c9bc90945bea916ce3ac4849574Mindy Pereira        return mLayoutInflater.inflate(mLayoutId, null);
171699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    }
172699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira
1733656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira    /*package*/ static interface OnCheckedItemChangedListener {
1743656f7e97c58dc8443132d2d8297629b6a04cce7Mindy Pereira        public void onCheckedItemChanged(int position);
175699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira    }
176699c1e37a1bf26daab34f2117a14c6e883636077Mindy Pereira}
177