1/* 2 * Copyright (C) 2007-2008 Esmertec AG. 3 * Copyright (C) 2007-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 18package com.android.im.app; 19 20import com.android.im.R; 21import com.android.im.provider.Imps; 22 23import android.app.ListActivity; 24import android.content.Context; 25import android.content.Intent; 26import android.database.Cursor; 27import android.database.DatabaseUtils; 28import android.net.Uri; 29import android.os.Bundle; 30import android.text.Editable; 31import android.text.TextWatcher; 32import android.util.Log; 33import android.view.View; 34import android.widget.EditText; 35import android.widget.Filter; 36import android.widget.ListView; 37import android.widget.ResourceCursorAdapter; 38 39/** 40 * Activity used to pick a contact. 41 */ 42public class ContactsPickerActivity extends ListActivity { 43 public final static String EXTRA_EXCLUDED_CONTACTS = "excludes"; 44 45 public final static String EXTRA_RESULT_USERNAME = "result"; 46 47 private ContactsAdapter mAdapter; 48 private String mExcludeClause; 49 Uri mData; 50 Filter mFilter; 51 52 private static final void log(String msg) { 53 Log.d(ImApp.LOG_TAG, "<ContactsPickerActivity> " + msg); 54 } 55 56 @Override 57 protected void onCreate(Bundle icicle) { 58 super.onCreate(icicle); 59 60 setContentView(R.layout.contacts_picker_activity); 61 if(!resolveIntent()){ 62 if(Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)) { 63 log("no data, finish"); 64 } 65 finish(); 66 return; 67 } 68 69 EditText filter = (EditText)findViewById(R.id.filter); 70 filter.addTextChangedListener(new TextWatcher() { 71 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 72 } 73 74 public void onTextChanged(CharSequence s, int start, int before, int count) { 75 mFilter.filter(s); 76 } 77 78 public void afterTextChanged(Editable s) { 79 } 80 }); 81 } 82 83 private boolean resolveIntent() { 84 Intent i = getIntent(); 85 mData = i.getData(); 86 87 if(mData == null) { 88 return false; 89 } 90 mExcludeClause = buildExcludeClause(i.getStringArrayExtra(EXTRA_EXCLUDED_CONTACTS)); 91 Cursor cursor = managedQuery(mData, ContactView.CONTACT_PROJECTION, 92 mExcludeClause, Imps.Contacts.DEFAULT_SORT_ORDER); 93 if (cursor == null) { 94 return false; 95 } 96 97 mAdapter = new ContactsAdapter(this, cursor); 98 mFilter = mAdapter.getFilter(); 99 setListAdapter(mAdapter); 100 return true; 101 } 102 103 @Override 104 protected void onListItemClick(ListView l, View v, int position, long id) { 105 Cursor cursor = (Cursor)mAdapter.getItem(position); 106 Intent data = new Intent(); 107 data.putExtra(EXTRA_RESULT_USERNAME, 108 cursor.getString(ContactView.COLUMN_CONTACT_USERNAME)); 109 setResult(RESULT_OK, data); 110 finish(); 111 } 112 113 private static String buildExcludeClause(String[] excluded) { 114 if (excluded == null || excluded.length == 0) { 115 return null; 116 } 117 118 StringBuilder clause = new StringBuilder(); 119 clause.append(Imps.Contacts.USERNAME); 120 clause.append(" NOT IN ("); 121 int len = excluded.length; 122 for (int i = 0; i < len - 1; i++) { 123 DatabaseUtils.appendValueToSql(clause, excluded[i]); 124 clause.append(','); 125 } 126 DatabaseUtils.appendValueToSql(clause, excluded[len - 1]); 127 clause.append(')'); 128 return clause.toString(); 129 } 130 131 Cursor runQuery(CharSequence constraint) { 132 String where; 133 if (constraint == null) { 134 where = mExcludeClause; 135 } else { 136 StringBuilder buf = new StringBuilder(); 137 if (mExcludeClause != null) { 138 buf.append(mExcludeClause).append(" AND "); 139 } 140 141 buf.append(Imps.Contacts.NICKNAME); 142 buf.append(" LIKE "); 143 DatabaseUtils.appendValueToSql(buf, "%" + constraint + "%"); 144 145 where = buf.toString(); 146 } 147 return managedQuery(mData, ContactView.CONTACT_PROJECTION, where, 148 Imps.Contacts.DEFAULT_SORT_ORDER); 149 } 150 151 private class ContactsAdapter extends ResourceCursorAdapter { 152 private String mConstraints; 153 154 public ContactsAdapter(Context context, Cursor c) { 155 super(context, R.layout.contact_view, c); 156 } 157 158 @Override 159 public void bindView(View view, Context context, Cursor cursor) { 160 ContactView v = (ContactView)view; 161 v.setPadding(0, 0, 0, 0); 162 v.bind(cursor, mConstraints, false); 163 } 164 165 @Override 166 public void changeCursor(Cursor cursor) { 167 if(mCursor != null && mCursor != cursor) { 168 mCursor.deactivate(); 169 } 170 super.changeCursor(cursor); 171 } 172 173 @Override 174 public Cursor runQueryOnBackgroundThread(CharSequence constraint) { 175 mConstraints = constraint.toString(); 176 177 return ContactsPickerActivity.this.runQuery(constraint); 178 } 179 } 180 181} 182