ContactSelectionActivity.java revision 5251884bbcdb92dad577d027126547527285fcce
1/* 2 * Copyright (C) 2007 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.contacts.activities; 18 19import com.android.contacts.ContactsActivity; 20import com.android.contacts.R; 21import com.android.contacts.list.ContactEntryListFragment; 22import com.android.contacts.list.ContactPickerFragment; 23import com.android.contacts.list.ContactsIntentResolver; 24import com.android.contacts.list.ContactsRequest; 25import com.android.contacts.list.DirectoryListLoader; 26import com.android.contacts.list.OnContactPickerActionListener; 27import com.android.contacts.list.OnPhoneNumberPickerActionListener; 28import com.android.contacts.list.OnPostalAddressPickerActionListener; 29import com.android.contacts.list.PhoneNumberPickerFragment; 30import com.android.contacts.list.PostalAddressPickerFragment; 31import com.android.contacts.widget.ContextMenuAdapter; 32 33import android.app.Fragment; 34import android.content.Intent; 35import android.net.Uri; 36import android.os.Bundle; 37import android.provider.ContactsContract.Contacts; 38import android.text.TextUtils; 39import android.view.MenuItem; 40import android.view.View; 41import android.view.View.OnClickListener; 42import android.widget.Button; 43import android.widget.SearchView; 44import android.widget.SearchView.OnQueryChangeListener; 45 46/** 47 * Displays a list of contacts (or phone numbers or postal addresses) for the 48 * purposes of selecting one. 49 */ 50public class ContactSelectionActivity extends ContactsActivity 51 implements View.OnCreateContextMenuListener, OnQueryChangeListener, OnClickListener { 52 private static final String TAG = "ContactSelectionActivity"; 53 54 private static final String KEY_ACTION_CODE = "actionCode"; 55 private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20; 56 57 private ContactsIntentResolver mIntentResolver; 58 protected ContactEntryListFragment<?> mListFragment; 59 60 private int mActionCode = -1; 61 62 private ContactsRequest mRequest; 63 private SearchView mSearchView; 64 65 public ContactSelectionActivity() { 66 mIntentResolver = new ContactsIntentResolver(this); 67 } 68 69 @Override 70 public void onAttachFragment(Fragment fragment) { 71 if (fragment instanceof ContactEntryListFragment<?>) { 72 mListFragment = (ContactEntryListFragment<?>) fragment; 73 setupActionListener(); 74 } 75 } 76 77 @Override 78 protected void onCreate(Bundle savedState) { 79 super.onCreate(savedState); 80 81 if (savedState != null) { 82 mActionCode = savedState.getInt(KEY_ACTION_CODE); 83 } 84 85 // Extract relevant information from the intent 86 mRequest = mIntentResolver.resolveIntent(getIntent()); 87 if (!mRequest.isValid()) { 88 setResult(RESULT_CANCELED); 89 finish(); 90 return; 91 } 92 93 Intent redirect = mRequest.getRedirectIntent(); 94 if (redirect != null) { 95 // Need to start a different activity 96 startActivity(redirect); 97 finish(); 98 return; 99 } 100 101 configureActivityTitle(); 102 103 setContentView(R.layout.contact_picker); 104 105 configureListFragment(); 106 107 mSearchView = (SearchView)findViewById(R.id.search_view); 108 mSearchView.setQueryHint(getString(R.string.hint_findContacts)); 109 mSearchView.setOnQueryChangeListener(this); 110 111 // This is a hack to prevent the search view from grabbing focus 112 // at this point. If search view were visible, it would always grabs focus 113 // because it is the first focusable widget in the window. 114 mSearchView.setVisibility(View.INVISIBLE); 115 mSearchView.post(new Runnable() { 116 117 @Override 118 public void run() { 119 mSearchView.setVisibility(View.VISIBLE); 120 } 121 }); 122 123 Button cancel = (Button) findViewById(R.id.cancel); 124 cancel.setOnClickListener(this); 125 } 126 127 @Override 128 protected void onSaveInstanceState(Bundle outState) { 129 super.onSaveInstanceState(outState); 130 outState.putInt(KEY_ACTION_CODE, mActionCode); 131 } 132 133 private void configureActivityTitle() { 134 if (mRequest.getActivityTitle() != null) { 135 setTitle(mRequest.getActivityTitle()); 136 return; 137 } 138 139 int actionCode = mRequest.getActionCode(); 140 switch (actionCode) { 141 case ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT: { 142 setTitle(R.string.contactPickerActivityTitle); 143 break; 144 } 145 146 case ContactsRequest.ACTION_PICK_CONTACT: { 147 setTitle(R.string.contactPickerActivityTitle); 148 break; 149 } 150 151 case ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT: { 152 setTitle(R.string.contactPickerActivityTitle); 153 break; 154 } 155 156 case ContactsRequest.ACTION_CREATE_SHORTCUT_CONTACT: { 157 setTitle(R.string.shortcutActivityTitle); 158 break; 159 } 160 161 case ContactsRequest.ACTION_PICK_PHONE: { 162 setTitle(R.string.contactPickerActivityTitle); 163 break; 164 } 165 166 case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: { 167 setTitle(R.string.callShortcutActivityTitle); 168 break; 169 } 170 171 case ContactsRequest.ACTION_CREATE_SHORTCUT_SMS: { 172 setTitle(R.string.messageShortcutActivityTitle); 173 break; 174 } 175 176 case ContactsRequest.ACTION_PICK_POSTAL: { 177 setTitle(R.string.contactPickerActivityTitle); 178 break; 179 } 180 } 181 } 182 183 /** 184 * Creates the fragment based on the current request. 185 */ 186 public void configureListFragment() { 187 if (mActionCode == mRequest.getActionCode()) { 188 return; 189 } 190 191 mActionCode = mRequest.getActionCode(); 192 switch (mActionCode) { 193 case ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT: { 194 ContactPickerFragment fragment = new ContactPickerFragment(); 195 fragment.setCreateContactEnabled(true); 196 fragment.setEditMode(true); 197 fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE); 198 mListFragment = fragment; 199 break; 200 } 201 202 case ContactsRequest.ACTION_PICK_CONTACT: { 203 ContactPickerFragment fragment = new ContactPickerFragment(); 204 fragment.setSearchMode(mRequest.isSearchMode()); 205 mListFragment = fragment; 206 break; 207 } 208 209 case ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT: { 210 ContactPickerFragment fragment = new ContactPickerFragment(); 211 fragment.setCreateContactEnabled(!mRequest.isSearchMode()); 212 mListFragment = fragment; 213 break; 214 } 215 216 case ContactsRequest.ACTION_CREATE_SHORTCUT_CONTACT: { 217 ContactPickerFragment fragment = new ContactPickerFragment(); 218 fragment.setSearchMode(mRequest.isSearchMode()); 219 fragment.setQueryString(mRequest.getQueryString(), false); 220 fragment.setShortcutRequested(true); 221 mListFragment = fragment; 222 break; 223 } 224 225 case ContactsRequest.ACTION_PICK_PHONE: { 226 PhoneNumberPickerFragment fragment = new PhoneNumberPickerFragment(); 227 mListFragment = fragment; 228 break; 229 } 230 231 case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: { 232 PhoneNumberPickerFragment fragment = new PhoneNumberPickerFragment(); 233 fragment.setShortcutAction(Intent.ACTION_CALL); 234 fragment.setSearchMode(mRequest.isSearchMode()); 235 236 mListFragment = fragment; 237 break; 238 } 239 240 case ContactsRequest.ACTION_CREATE_SHORTCUT_SMS: { 241 PhoneNumberPickerFragment fragment = new PhoneNumberPickerFragment(); 242 fragment.setShortcutAction(Intent.ACTION_SENDTO); 243 244 mListFragment = fragment; 245 break; 246 } 247 248 case ContactsRequest.ACTION_PICK_POSTAL: { 249 PostalAddressPickerFragment fragment = new PostalAddressPickerFragment(); 250 mListFragment = fragment; 251 break; 252 } 253 254 default: 255 throw new IllegalStateException("Invalid action code: " + mActionCode); 256 } 257 258 mListFragment.setLegacyCompatibilityMode(mRequest.isLegacyCompatibilityMode()); 259 mListFragment.setContactsRequest(mRequest); 260 mListFragment.setSearchMode(mRequest.isSearchMode()); 261 mListFragment.setQueryString(mRequest.getQueryString(), false); 262 mListFragment.setDirectoryResultLimit(DEFAULT_DIRECTORY_RESULT_LIMIT); 263 264 getFragmentManager().beginTransaction() 265 .replace(R.id.list_container, mListFragment) 266 .commit(); 267 } 268 269 public void setupActionListener() { 270 if (mListFragment instanceof ContactPickerFragment) { 271 ((ContactPickerFragment) mListFragment).setOnContactPickerActionListener( 272 new ContactPickerActionListener()); 273 } else if (mListFragment instanceof PhoneNumberPickerFragment) { 274 ((PhoneNumberPickerFragment) mListFragment).setOnPhoneNumberPickerActionListener( 275 new PhoneNumberPickerActionListener()); 276 } else if (mListFragment instanceof PostalAddressPickerFragment) { 277 ((PostalAddressPickerFragment) mListFragment).setOnPostalAddressPickerActionListener( 278 new PostalAddressPickerActionListener()); 279 } else { 280 throw new IllegalStateException("Unsupported list fragment type: " + mListFragment); 281 } 282 } 283 284 private final class ContactPickerActionListener implements OnContactPickerActionListener { 285 @Override 286 public void onCreateNewContactAction() { 287 Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); 288 startActivityAndForwardResult(intent); 289 } 290 291 @Override 292 public void onEditContactAction(Uri contactLookupUri) { 293 Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri); 294 startActivityAndForwardResult(intent); 295 } 296 297 @Override 298 public void onPickContactAction(Uri contactUri) { 299 returnPickerResult(contactUri); 300 } 301 302 @Override 303 public void onShortcutIntentCreated(Intent intent) { 304 returnPickerResult(intent); 305 } 306 } 307 308 private final class PhoneNumberPickerActionListener implements 309 OnPhoneNumberPickerActionListener { 310 @Override 311 public void onPickPhoneNumberAction(Uri dataUri) { 312 returnPickerResult(dataUri); 313 } 314 315 @Override 316 public void onShortcutIntentCreated(Intent intent) { 317 returnPickerResult(intent); 318 } 319 } 320 321 private final class PostalAddressPickerActionListener implements 322 OnPostalAddressPickerActionListener { 323 @Override 324 public void onPickPostalAddressAction(Uri dataUri) { 325 returnPickerResult(dataUri); 326 } 327 } 328 329 public void startActivityAndForwardResult(final Intent intent) { 330 intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); 331 332 // Forward extras to the new activity 333 Bundle extras = getIntent().getExtras(); 334 if (extras != null) { 335 intent.putExtras(extras); 336 } 337 startActivity(intent); 338 finish(); 339 } 340 341 @Override 342 public boolean onContextItemSelected(MenuItem item) { 343 ContextMenuAdapter menuAdapter = mListFragment.getContextMenuAdapter(); 344 if (menuAdapter != null) { 345 return menuAdapter.onContextItemSelected(item); 346 } 347 348 return super.onContextItemSelected(item); 349 } 350 351 @Override 352 public boolean onQueryTextChanged(String newText) { 353 mListFragment.setQueryString(newText, true); 354 mListFragment.setSearchMode(!TextUtils.isEmpty(newText)); 355 return false; 356 } 357 358 @Override 359 public boolean onSubmitQuery(String query) { 360 return false; 361 } 362 363 public void returnPickerResult(Uri data) { 364 Intent intent = new Intent(); 365 intent.setData(data); 366 returnPickerResult(intent); 367 } 368 369 public void returnPickerResult(Intent intent) { 370 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 371 setResult(RESULT_OK, intent); 372 finish(); 373 } 374 375 @Override 376 public void onClick(View v) { 377 if (v.getId() == R.id.cancel) { 378 setResult(RESULT_CANCELED); 379 finish(); 380 } 381 } 382} 383