RecipientAlternatesAdapter.java revision 18987c44006700a2bfe614ec1e39a29ed5b23d78
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.ex.chips;
18
19import com.android.ex.chips.BaseRecipientAdapter.EmailQuery;
20
21import android.content.Context;
22import android.database.Cursor;
23import android.provider.ContactsContract.CommonDataKinds.Email;
24import android.text.util.Rfc822Token;
25import android.text.util.Rfc822Tokenizer;
26import android.util.Log;
27import android.view.LayoutInflater;
28import android.view.View;
29import android.view.ViewGroup;
30import android.widget.CursorAdapter;
31import android.widget.ImageView;
32import android.widget.TextView;
33
34import java.util.HashMap;
35
36public class RecipientAlternatesAdapter extends CursorAdapter {
37    static final int MAX_LOOKUPS = 50;
38    private final LayoutInflater mLayoutInflater;
39
40    private final int mLayoutId;
41
42    private final long mCurrentId;
43
44    private int mCheckedItemPosition = -1;
45
46    private OnCheckedItemChangedListener mCheckedItemChangedListener;
47
48    private static final String TAG = "RecipAlternates";
49
50    /**
51     * Get a HashMap of address to RecipientEntry that contains all contact
52     * information for a contact with the provided address, if one exists. This
53     * may block the UI, so run it in an async task.
54     *
55     * @param context Context.
56     * @param addresses Array of addresses on which to perform the lookup.
57     * @return HashMap<String,RecipientEntry>
58     */
59    public static HashMap<String, RecipientEntry> getMatchingRecipients(Context context,
60            String[] inAddresses) {
61        int addressesSize = Math.min(MAX_LOOKUPS, inAddresses.length);
62        String[] addresses = new String[addressesSize];
63        StringBuilder bindString = new StringBuilder();
64        // Create the "?" string and set up arguments.
65        for (int i = 0; i < addressesSize; i++) {
66            Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(inAddresses[i]);
67            addresses[i] = (tokens.length > 0 ? tokens[0].getAddress() : inAddresses[i]);
68            bindString.append("?");
69            if (i < addressesSize - 1) {
70                bindString.append(",");
71            }
72        }
73
74        if (Log.isLoggable(TAG, Log.DEBUG)) {
75            Log.d(TAG, "Doing reverse lookup for " + addresses.toString());
76        }
77
78        Cursor c = context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION,
79                Email.ADDRESS + " IN (" + bindString.toString() + ")", addresses, null);
80        HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>();
81        if (c != null) {
82            try {
83                if (c.moveToFirst()) {
84                    do {
85                        String address = c.getString(EmailQuery.ADDRESS);
86                        recipientEntries.put(address, RecipientEntry.constructTopLevelEntry(
87                                c.getString(EmailQuery.NAME),
88                                c.getString(EmailQuery.ADDRESS),
89                                c.getLong(EmailQuery.CONTACT_ID),
90                                c.getLong(EmailQuery.DATA_ID),
91                                c.getString(EmailQuery.PHOTO_THUMBNAIL_URI)));
92                        if (Log.isLoggable(TAG, Log.DEBUG)) {
93                            Log.d(TAG, "Received reverse look up information for " + address
94                                    + " RESULTS: "
95                                    + " NAME : " + c.getString(EmailQuery.NAME)
96                                    + " CONTACT ID : " + c.getLong(EmailQuery.CONTACT_ID)
97                                    + " ADDRESS :" + c.getString(EmailQuery.ADDRESS));
98                        }
99                    } while (c.moveToNext());
100                }
101            } finally {
102                c.close();
103            }
104        }
105        return recipientEntries;
106    }
107
108    public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId,
109            OnCheckedItemChangedListener listener) {
110        super(context, context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION,
111                Email.CONTACT_ID + " =?", new String[] {
112                    String.valueOf(contactId)
113                }, null), 0);
114        mLayoutInflater = LayoutInflater.from(context);
115        mLayoutId = viewId;
116        mCurrentId = currentId;
117        mCheckedItemChangedListener = listener;
118    }
119
120    @Override
121    public long getItemId(int position) {
122        Cursor c = getCursor();
123        if (c.moveToPosition(position)) {
124            c.getLong(EmailQuery.DATA_ID);
125        }
126        return -1;
127    }
128
129    public RecipientEntry getRecipientEntry(int position) {
130        Cursor c = getCursor();
131        c.moveToPosition(position);
132        return RecipientEntry.constructTopLevelEntry(c.getString(EmailQuery.NAME), c
133                .getString(EmailQuery.ADDRESS), c.getLong(EmailQuery.CONTACT_ID), c
134                .getLong(EmailQuery.DATA_ID), c.getString(EmailQuery.PHOTO_THUMBNAIL_URI));
135    }
136
137    @Override
138    public View getView(int position, View convertView, ViewGroup parent) {
139        Cursor cursor = getCursor();
140        cursor.moveToPosition(position);
141        if (convertView == null) {
142            convertView = newView();
143        }
144        if (cursor.getLong(EmailQuery.DATA_ID) == mCurrentId) {
145            mCheckedItemPosition = position;
146            if (mCheckedItemChangedListener != null) {
147                mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition);
148            }
149        }
150        bindView(convertView, convertView.getContext(), cursor);
151        return convertView;
152    }
153
154    // TODO: this is VERY similar to the BaseRecipientAdapter. Can we combine
155    // somehow?
156    @Override
157    public void bindView(View view, Context context, Cursor cursor) {
158        int position = cursor.getPosition();
159
160        TextView display = (TextView) view.findViewById(android.R.id.text1);
161        ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
162        RecipientEntry entry = getRecipientEntry(position);
163        if (position == 0) {
164            display.setText(cursor.getString(EmailQuery.NAME));
165            display.setVisibility(View.VISIBLE);
166            // TODO: see if this needs to be done outside the main thread
167            // as it may be too slow to get immediately.
168            imageView.setImageURI(entry.getPhotoThumbnailUri());
169            imageView.setVisibility(View.VISIBLE);
170        } else {
171            display.setVisibility(View.GONE);
172            imageView.setVisibility(View.GONE);
173        }
174        TextView destination = (TextView) view.findViewById(android.R.id.text2);
175        destination.setText(cursor.getString(EmailQuery.ADDRESS));
176    }
177
178    @Override
179    public View newView(Context context, Cursor cursor, ViewGroup parent) {
180        return newView();
181    }
182
183    private View newView() {
184        return mLayoutInflater.inflate(mLayoutId, null);
185    }
186
187    /*package*/ static interface OnCheckedItemChangedListener {
188        public void onCheckedItemChanged(int position);
189    }
190}
191