Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2008 Esmertec AG.
      3  * Copyright (C) 2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.im.app;
     19 
     20 import static android.provider.Contacts.ContactMethods.CONTENT_EMAIL_URI;
     21 import android.app.Activity;
     22 import android.content.ContentResolver;
     23 import android.content.ContentUris;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.database.Cursor;
     27 import android.database.DatabaseUtils;
     28 import android.net.Uri;
     29 import android.os.Bundle;
     30 import android.os.IBinder;
     31 import android.os.RemoteException;
     32 import android.provider.Contacts.ContactMethods;
     33 import android.text.Editable;
     34 import android.text.TextUtils;
     35 import android.text.TextWatcher;
     36 import android.text.util.Rfc822Token;
     37 import android.text.util.Rfc822Tokenizer;
     38 import android.util.Log;
     39 import android.view.View;
     40 import android.widget.Button;
     41 import android.widget.MultiAutoCompleteTextView;
     42 import android.widget.ResourceCursorAdapter;
     43 import android.widget.SimpleCursorAdapter;
     44 import android.widget.Spinner;
     45 import android.widget.TextView;
     46 import com.android.im.IContactList;
     47 import com.android.im.IContactListManager;
     48 import com.android.im.IImConnection;
     49 import com.android.im.R;
     50 import com.android.im.engine.ImErrorInfo;
     51 import com.android.im.plugin.BrandingResourceIDs;
     52 import com.android.im.plugin.ImpsConfigNames;
     53 import com.android.im.provider.Imps;
     54 import com.android.im.service.ImServiceConstants;
     55 
     56 import java.util.List;
     57 
     58 public class AddContactActivity extends Activity {
     59 
     60     private static final String[] CONTACT_LIST_PROJECTION = {
     61         Imps.ContactList._ID,
     62         Imps.ContactList.NAME,
     63     };
     64     private static final int CONTACT_LIST_NAME_COLUMN = 1;
     65 
     66     private MultiAutoCompleteTextView mAddressList;
     67     private Spinner mListSpinner;
     68     Button mInviteButton;
     69     ImApp mApp;
     70     SimpleAlertHandler mHandler;
     71 
     72     private long mProviderId;
     73     private long mAccountId;
     74     private String mDefaultDomain;
     75 
     76     @Override
     77     protected void onCreate(Bundle savedInstanceState) {
     78         super.onCreate(savedInstanceState);
     79 
     80         mApp = ImApp.getApplication(this);
     81         mHandler = new SimpleAlertHandler(this);
     82         resolveIntent(getIntent());
     83 
     84         setContentView(R.layout.add_contact_activity);
     85 
     86         BrandingResources brandingRes = mApp.getBrandingResource(mProviderId);
     87         setTitle(brandingRes.getString(BrandingResourceIDs.STRING_ADD_CONTACT_TITLE));
     88 
     89         TextView label = (TextView) findViewById(R.id.input_contact_label);
     90         label.setText(brandingRes.getString(BrandingResourceIDs.STRING_LABEL_INPUT_CONTACT));
     91 
     92         mAddressList = (MultiAutoCompleteTextView) findViewById(R.id.email);
     93         mAddressList.setAdapter(new EmailAddressAdapter(this));
     94         mAddressList.setTokenizer(new Rfc822Tokenizer());
     95         mAddressList.addTextChangedListener(mTextWatcher);
     96 
     97         mListSpinner = (Spinner) findViewById(R.id.choose_list);
     98 
     99         Cursor c = queryContactLists();
    100         int initSelection = searchInitListPos(c, getIntent().getStringExtra(
    101                 ImServiceConstants.EXTRA_INTENT_LIST_NAME));
    102         SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
    103                 android.R.layout.simple_spinner_item,
    104                 c,
    105                 new String[] {Imps.ContactList.NAME},
    106                 new int[] {android.R.id.text1});
    107         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    108         mListSpinner.setAdapter(adapter);
    109         mListSpinner.setSelection(initSelection);
    110 
    111         mInviteButton = (Button) findViewById(R.id.invite);
    112         mInviteButton.setText(brandingRes.getString(
    113                 BrandingResourceIDs.STRING_BUTTON_ADD_CONTACT));
    114         mInviteButton.setOnClickListener(mButtonHandler);
    115         mInviteButton.setEnabled(false);
    116     }
    117 
    118     private Cursor queryContactLists() {
    119         Uri uri = Imps.ContactList.CONTENT_URI;
    120         uri = ContentUris.withAppendedId(uri, mProviderId);
    121         uri = ContentUris.withAppendedId(uri, mAccountId);
    122         Cursor c = managedQuery(uri, CONTACT_LIST_PROJECTION, null, null);
    123         return c;
    124     }
    125 
    126     private int searchInitListPos(Cursor c, String listName) {
    127         if (TextUtils.isEmpty(listName)) {
    128             return 0;
    129         }
    130         c.moveToPosition(-1);
    131         while (c.moveToNext()) {
    132             if (listName.equals(c.getString(CONTACT_LIST_NAME_COLUMN))) {
    133                 return c.getPosition();
    134             }
    135         }
    136         return 0;
    137     }
    138 
    139     private void resolveIntent(Intent intent) {
    140         mProviderId = intent.getLongExtra(
    141                 ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, -1);
    142         mAccountId = intent.getLongExtra(
    143                 ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, -1);
    144         mDefaultDomain = Imps.ProviderSettings.getStringValue(getContentResolver(),
    145                 mProviderId, ImpsConfigNames.DEFAULT_DOMAIN);
    146     }
    147 
    148     void inviteBuddies() {
    149         Rfc822Token[] recipients = Rfc822Tokenizer.tokenize(mAddressList.getText());
    150         try {
    151             IImConnection conn = mApp.getConnection(mProviderId);
    152             IContactList list = getContactList(conn);
    153             if (list == null) {
    154                 Log.e(ImApp.LOG_TAG, "<AddContactActivity> can't find given contact list:"
    155                         + getSelectedListName());
    156                 finish();
    157             } else {
    158                 boolean fail = false;
    159                 for (Rfc822Token recipient : recipients) {
    160                     String username = recipient.getAddress();
    161                     if (mDefaultDomain != null && username.indexOf('@') == -1) {
    162                         username = username + "@" + mDefaultDomain;
    163                     }
    164                     if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
    165                         log("addContact:" + username);
    166                     }
    167                     int res = list.addContact(username);
    168                     if (res != ImErrorInfo.NO_ERROR) {
    169                         fail = true;
    170                         mHandler.showAlert(R.string.error,
    171                                 ErrorResUtils.getErrorRes(getResources(), res, username));
    172                     }
    173                 }
    174                 // close the screen if there's no error.
    175                 if (!fail) {
    176                     finish();
    177                 }
    178             }
    179         } catch (RemoteException ex) {
    180             Log.e(ImApp.LOG_TAG, "<AddContactActivity> inviteBuddies: caught " + ex);
    181         }
    182     }
    183 
    184     private IContactList getContactList(IImConnection conn) {
    185         if (conn == null) {
    186             return null;
    187         }
    188 
    189         try {
    190             IContactListManager contactListMgr = conn.getContactListManager();
    191             String listName = getSelectedListName();
    192             if (!TextUtils.isEmpty(listName)) {
    193                 return contactListMgr.getContactList(listName);
    194             } else {
    195                 // Use the default list
    196                 List<IBinder> lists = contactListMgr.getContactLists();
    197                 for (IBinder binder : lists) {
    198                     IContactList list = IContactList.Stub.asInterface(binder);
    199                     if (list.isDefault()) {
    200                         return list;
    201                     }
    202                 }
    203                 // No default list, use the first one as default list
    204                 if (!lists.isEmpty()) {
    205                     return IContactList.Stub.asInterface(lists.get(0));
    206                 }
    207                 return null;
    208             }
    209         } catch (RemoteException e) {
    210             // If the service has died, there is no list for now.
    211             return null;
    212         }
    213     }
    214 
    215     private String getSelectedListName() {
    216         Cursor c = (Cursor) mListSpinner.getSelectedItem();
    217         return (c == null) ? null : c.getString(CONTACT_LIST_NAME_COLUMN);
    218     }
    219 
    220     private View.OnClickListener mButtonHandler = new View.OnClickListener() {
    221         public void onClick(View v) {
    222             mApp.callWhenServiceConnected(mHandler, new Runnable() {
    223                 public void run() {
    224                     inviteBuddies();
    225                 }
    226             });
    227         }
    228     };
    229 
    230     private TextWatcher mTextWatcher = new TextWatcher() {
    231         public void afterTextChanged(Editable s) {
    232             mInviteButton.setEnabled(s.length() != 0);
    233         }
    234 
    235         public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    236             // noop
    237         }
    238 
    239         public void onTextChanged(CharSequence s, int start, int before, int count) {
    240             // noop
    241         }
    242     };
    243 
    244     private static void log(String msg) {
    245         Log.d(ImApp.LOG_TAG, "<AddContactActivity> " + msg);
    246     }
    247 
    248     static class EmailAddressAdapter extends ResourceCursorAdapter {
    249         public static final int DATA_INDEX = 1;
    250 
    251         private static final String SORT_ORDER = "people.name, contact_methods.data";
    252         private ContentResolver mContentResolver;
    253 
    254         private static final String[] PROJECTION = {
    255             ContactMethods._ID,     // 0
    256             ContactMethods.DATA     // 1
    257         };
    258 
    259         public EmailAddressAdapter(Context context) {
    260             super(context, android.R.layout.simple_dropdown_item_1line, null);
    261             mContentResolver = context.getContentResolver();
    262         }
    263 
    264         @Override
    265         public final String convertToString(Cursor cursor) {
    266             return cursor.getString(DATA_INDEX);
    267         }
    268 
    269         @Override
    270         public final void bindView(View view, Context context, Cursor cursor) {
    271             ((TextView) view).setText(cursor.getString(DATA_INDEX));
    272         }
    273 
    274         @Override
    275         public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
    276             String where = null;
    277 
    278             if (constraint != null) {
    279                 String filter = DatabaseUtils.sqlEscapeString(constraint.toString() + '%');
    280 
    281                 StringBuilder s = new StringBuilder();
    282                 s.append("(people.name LIKE ");
    283                 s.append(filter);
    284                 s.append(") OR (contact_methods.data LIKE ");
    285                 s.append(filter);
    286                 s.append(")");
    287 
    288                 where = s.toString();
    289             }
    290 
    291             return mContentResolver.query(CONTENT_EMAIL_URI, PROJECTION, where, null, SORT_ORDER);
    292         }
    293     }
    294 }
    295