RecipientAlternatesAdapter.java revision f908b64e75e0bb38ff2806232ca57c93189156ea
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 inAddresses 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        HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>();
79        Cursor c = context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION,
80                Email.ADDRESS + " IN (" + bindString.toString() + ")", addresses, null);
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.getInt(EmailQuery.ADDRESS_TYPE),
90                                c.getString(EmailQuery.ADDRESS_LABEL),
91                                c.getLong(EmailQuery.CONTACT_ID),
92                                c.getLong(EmailQuery.DATA_ID),
93                                c.getString(EmailQuery.PHOTO_THUMBNAIL_URI)));
94                        if (Log.isLoggable(TAG, Log.DEBUG)) {
95                            Log.d(TAG, "Received reverse look up information for " + address
96                                    + " RESULTS: "
97                                    + " NAME : " + c.getString(EmailQuery.NAME)
98                                    + " CONTACT ID : " + c.getLong(EmailQuery.CONTACT_ID)
99                                    + " ADDRESS :" + c.getString(EmailQuery.ADDRESS));
100                        }
101                    } while (c.moveToNext());
102                }
103            } finally {
104                c.close();
105            }
106        }
107        return recipientEntries;
108    }
109
110    public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId,
111            OnCheckedItemChangedListener listener) {
112        super(context, context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION,
113                Email.CONTACT_ID + " =?", new String[] {
114                    String.valueOf(contactId)
115                }, null), 0);
116        mLayoutInflater = LayoutInflater.from(context);
117        mLayoutId = viewId;
118        mCurrentId = currentId;
119        mCheckedItemChangedListener = listener;
120    }
121
122    @Override
123    public long getItemId(int position) {
124        Cursor c = getCursor();
125        if (c.moveToPosition(position)) {
126            c.getLong(EmailQuery.DATA_ID);
127        }
128        return -1;
129    }
130
131    public RecipientEntry getRecipientEntry(int position) {
132        Cursor c = getCursor();
133        c.moveToPosition(position);
134        return RecipientEntry.constructTopLevelEntry(c.getString(EmailQuery.NAME),
135                c.getString(EmailQuery.ADDRESS), c.getInt(EmailQuery.ADDRESS_TYPE),
136                c.getString(EmailQuery.ADDRESS_LABEL),
137                c.getLong(EmailQuery.CONTACT_ID), c.getLong(EmailQuery.DATA_ID),
138                c.getString(EmailQuery.PHOTO_THUMBNAIL_URI));
139    }
140
141    @Override
142    public View getView(int position, View convertView, ViewGroup parent) {
143        Cursor cursor = getCursor();
144        cursor.moveToPosition(position);
145        if (convertView == null) {
146            convertView = newView();
147        }
148        if (cursor.getLong(EmailQuery.DATA_ID) == mCurrentId) {
149            mCheckedItemPosition = position;
150            if (mCheckedItemChangedListener != null) {
151                mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition);
152            }
153        }
154        bindView(convertView, convertView.getContext(), cursor);
155        return convertView;
156    }
157
158    // TODO: this is VERY similar to the BaseRecipientAdapter. Can we combine
159    // somehow?
160    @Override
161    public void bindView(View view, Context context, Cursor cursor) {
162        int position = cursor.getPosition();
163
164        TextView display = (TextView) view.findViewById(android.R.id.title);
165        ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
166        RecipientEntry entry = getRecipientEntry(position);
167        if (position == 0) {
168            display.setText(cursor.getString(EmailQuery.NAME));
169            display.setVisibility(View.VISIBLE);
170            // TODO: see if this needs to be done outside the main thread
171            // as it may be too slow to get immediately.
172            imageView.setImageURI(entry.getPhotoThumbnailUri());
173            imageView.setVisibility(View.VISIBLE);
174        } else {
175            display.setVisibility(View.GONE);
176            imageView.setVisibility(View.GONE);
177        }
178        TextView destination = (TextView) view.findViewById(android.R.id.text1);
179        destination.setText(cursor.getString(EmailQuery.ADDRESS));
180
181        TextView destinationType = (TextView) view.findViewById(android.R.id.text2);
182        if (destinationType != null) {
183            destinationType.setText(Email.getTypeLabel(context.getResources(),
184                    cursor.getInt(EmailQuery.ADDRESS_TYPE),
185                    cursor.getString(EmailQuery.ADDRESS_LABEL)).toString().toUpperCase());
186        }
187    }
188
189    @Override
190    public View newView(Context context, Cursor cursor, ViewGroup parent) {
191        return newView();
192    }
193
194    private View newView() {
195        return mLayoutInflater.inflate(mLayoutId, null);
196    }
197
198    /*package*/ static interface OnCheckedItemChangedListener {
199        public void onCheckedItemChanged(int position);
200    }
201}
202