Home | History | Annotate | Download | only in chips
      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 
     17 package com.android.ex.chips;
     18 
     19 import com.android.ex.chips.BaseRecipientAdapter.EmailQuery;
     20 
     21 import android.content.Context;
     22 import android.database.Cursor;
     23 import android.provider.ContactsContract.CommonDataKinds.Email;
     24 import android.text.util.Rfc822Token;
     25 import android.text.util.Rfc822Tokenizer;
     26 import android.util.Log;
     27 import android.view.LayoutInflater;
     28 import android.view.View;
     29 import android.view.ViewGroup;
     30 import android.widget.CursorAdapter;
     31 import android.widget.ImageView;
     32 import android.widget.TextView;
     33 
     34 import java.util.HashMap;
     35 
     36 public 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].toLowerCase());
     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