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 android.app.Fragment; 20import android.content.ActivityNotFoundException; 21import android.content.Intent; 22import android.graphics.PorterDuff; 23import android.graphics.drawable.Drawable; 24import android.net.Uri; 25import android.os.Bundle; 26import android.provider.ContactsContract.Contacts; 27import android.support.v4.content.ContextCompat; 28import android.support.v7.widget.Toolbar; 29import android.text.TextUtils; 30import android.util.Log; 31import android.view.Menu; 32import android.view.MenuInflater; 33import android.view.MenuItem; 34import android.view.View; 35import android.view.View.OnClickListener; 36import android.view.View.OnFocusChangeListener; 37import android.widget.TextView; 38import android.widget.Toast; 39 40import com.android.contacts.AppCompatContactsActivity; 41import com.android.contacts.R; 42import com.android.contacts.editor.EditorIntents; 43import com.android.contacts.list.ContactEntryListFragment; 44import com.android.contacts.list.ContactPickerFragment; 45import com.android.contacts.list.ContactsIntentResolver; 46import com.android.contacts.list.ContactsRequest; 47import com.android.contacts.list.DirectoryListLoader; 48import com.android.contacts.list.EmailAddressPickerFragment; 49import com.android.contacts.list.GroupMemberPickerFragment; 50import com.android.contacts.list.JoinContactListFragment; 51import com.android.contacts.list.LegacyPhoneNumberPickerFragment; 52import com.android.contacts.list.MultiSelectContactsListFragment; 53import com.android.contacts.list.MultiSelectContactsListFragment.OnCheckBoxListActionListener; 54import com.android.contacts.list.MultiSelectEmailAddressesListFragment; 55import com.android.contacts.list.MultiSelectPhoneNumbersListFragment; 56import com.android.contacts.list.OnContactPickerActionListener; 57import com.android.contacts.list.OnEmailAddressPickerActionListener; 58import com.android.contacts.list.OnPhoneNumberPickerActionListener; 59import com.android.contacts.list.OnPostalAddressPickerActionListener; 60import com.android.contacts.list.PhoneNumberPickerFragment; 61import com.android.contacts.list.PostalAddressPickerFragment; 62import com.android.contacts.list.UiIntentActions; 63import com.android.contacts.logging.ListEvent; 64import com.android.contacts.util.ImplicitIntentsUtil; 65import com.android.contacts.util.ViewUtil; 66 67import java.util.ArrayList; 68 69/** 70 * Displays a list of contacts (or phone numbers or postal addresses) for the 71 * purposes of selecting one. 72 */ 73public class ContactSelectionActivity extends AppCompatContactsActivity implements 74 View.OnCreateContextMenuListener, ActionBarAdapter.Listener, OnClickListener, 75 OnFocusChangeListener, OnCheckBoxListActionListener { 76 private static final String TAG = "ContactSelection"; 77 78 private static final String KEY_ACTION_CODE = "actionCode"; 79 private static final String KEY_SEARCH_MODE = "searchMode"; 80 private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20; 81 82 private ContactsIntentResolver mIntentResolver; 83 protected ContactEntryListFragment<?> mListFragment; 84 85 private int mActionCode = -1; 86 private boolean mIsSearchMode; 87 private boolean mIsSearchSupported; 88 89 private ContactsRequest mRequest; 90 91 private ActionBarAdapter mActionBarAdapter; 92 private Toolbar mToolbar; 93 94 public ContactSelectionActivity() { 95 mIntentResolver = new ContactsIntentResolver(this); 96 } 97 98 @Override 99 public void onAttachFragment(Fragment fragment) { 100 if (fragment instanceof ContactEntryListFragment<?>) { 101 mListFragment = (ContactEntryListFragment<?>) fragment; 102 setupActionListener(); 103 } 104 } 105 106 @Override 107 protected void onCreate(Bundle savedState) { 108 super.onCreate(savedState); 109 110 RequestPermissionsActivity.startPermissionActivityIfNeeded(this); 111 112 if (savedState != null) { 113 mActionCode = savedState.getInt(KEY_ACTION_CODE); 114 mIsSearchMode = savedState.getBoolean(KEY_SEARCH_MODE); 115 } 116 117 // Extract relevant information from the intent 118 mRequest = mIntentResolver.resolveIntent(getIntent()); 119 if (!mRequest.isValid()) { 120 setResult(RESULT_CANCELED); 121 finish(); 122 return; 123 } 124 125 setContentView(R.layout.contact_picker); 126 127 if (mActionCode != mRequest.getActionCode()) { 128 mActionCode = mRequest.getActionCode(); 129 configureListFragment(); 130 } 131 132 prepareSearchViewAndActionBar(savedState); 133 configureActivityTitle(); 134 } 135 136 public boolean isSelectionMode() { 137 return mActionBarAdapter.isSelectionMode(); 138 } 139 140 public boolean isSearchMode() { 141 return mActionBarAdapter.isSearchMode(); 142 } 143 144 private void prepareSearchViewAndActionBar(Bundle savedState) { 145 mToolbar = getView(R.id.toolbar); 146 setSupportActionBar(mToolbar); 147 148 // Add a shadow under the toolbar. 149 ViewUtil.addRectangularOutlineProvider(findViewById(R.id.toolbar_parent), getResources()); 150 151 mActionBarAdapter = new ActionBarAdapter(this, this, getSupportActionBar(), mToolbar, 152 R.string.enter_contact_name); 153 mActionBarAdapter.setShowHomeIcon(true); 154 mActionBarAdapter.setShowHomeAsUp(true); 155 mActionBarAdapter.initialize(savedState, mRequest); 156 157 // Postal address pickers (and legacy pickers) don't support search, so just show 158 // "HomeAsUp" button and title. 159 mIsSearchSupported = mRequest.getActionCode() != ContactsRequest.ACTION_PICK_POSTAL 160 && mRequest.getActionCode() != ContactsRequest.ACTION_PICK_EMAILS 161 && mRequest.getActionCode() != ContactsRequest.ACTION_PICK_PHONES 162 && !mRequest.isLegacyCompatibilityMode(); 163 configureSearchMode(); 164 } 165 166 private void configureSearchMode() { 167 mActionBarAdapter.setSearchMode(mIsSearchMode); 168 invalidateOptionsMenu(); 169 } 170 171 @Override 172 public boolean onOptionsItemSelected(MenuItem item) { 173 final int id = item.getItemId(); 174 if (id == android.R.id.home) {// Go back to previous screen, intending "cancel" 175 setResult(RESULT_CANCELED); 176 onBackPressed(); 177 } else if (id == R.id.menu_search) { 178 mIsSearchMode = !mIsSearchMode; 179 configureSearchMode(); 180 } else { 181 return super.onOptionsItemSelected(item); 182 } 183 return true; 184 } 185 186 @Override 187 protected void onSaveInstanceState(Bundle outState) { 188 super.onSaveInstanceState(outState); 189 outState.putInt(KEY_ACTION_CODE, mActionCode); 190 outState.putBoolean(KEY_SEARCH_MODE, mIsSearchMode); 191 if (mActionBarAdapter != null) { 192 mActionBarAdapter.onSaveInstanceState(outState); 193 } 194 } 195 196 private void configureActivityTitle() { 197 if (!TextUtils.isEmpty(mRequest.getActivityTitle())) { 198 getSupportActionBar().setTitle(mRequest.getActivityTitle()); 199 return; 200 } 201 int titleResId = -1; 202 int actionCode = mRequest.getActionCode(); 203 switch (actionCode) { 204 case ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT: { 205 titleResId = R.string.contactInsertOrEditActivityTitle; 206 break; 207 } 208 case ContactsRequest.ACTION_PICK_CONTACT: { 209 titleResId = R.string.contactPickerActivityTitle; 210 break; 211 } 212 case ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT: { 213 titleResId = R.string.contactPickerActivityTitle; 214 break; 215 } 216 case ContactsRequest.ACTION_CREATE_SHORTCUT_CONTACT: { 217 titleResId = R.string.shortcutActivityTitle; 218 break; 219 } 220 case ContactsRequest.ACTION_PICK_PHONE: { 221 titleResId = R.string.contactPickerActivityTitle; 222 break; 223 } 224 case ContactsRequest.ACTION_PICK_EMAIL: { 225 titleResId = R.string.contactPickerActivityTitle; 226 break; 227 } 228 case ContactsRequest.ACTION_PICK_PHONES: { 229 titleResId = R.string.pickerSelectContactsActivityTitle; 230 break; 231 } 232 case ContactsRequest.ACTION_PICK_EMAILS: { 233 titleResId = R.string.pickerSelectContactsActivityTitle; 234 break; 235 } 236 case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: { 237 titleResId = R.string.shortcutActivityTitle; 238 break; 239 } 240 case ContactsRequest.ACTION_CREATE_SHORTCUT_SMS: { 241 titleResId = R.string.shortcutActivityTitle; 242 break; 243 } 244 case ContactsRequest.ACTION_PICK_POSTAL: { 245 titleResId = R.string.contactPickerActivityTitle; 246 break; 247 } 248 case ContactsRequest.ACTION_PICK_JOIN: { 249 titleResId = R.string.titleJoinContactDataWith; 250 break; 251 } 252 case ContactsRequest.ACTION_PICK_GROUP_MEMBERS: { 253 titleResId = R.string.groupMemberPickerActivityTitle; 254 break; 255 } 256 } 257 if (titleResId > 0) { 258 getSupportActionBar().setTitle(titleResId); 259 } 260 } 261 262 /** 263 * Creates the fragment based on the current request. 264 */ 265 public void configureListFragment() { 266 switch (mActionCode) { 267 case ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT: { 268 ContactPickerFragment fragment = new ContactPickerFragment(); 269 fragment.setEditMode(true); 270 fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE); 271 fragment.setCreateContactEnabled(!mRequest.isSearchMode()); 272 fragment.setListType(ListEvent.ListType.PICK_CONTACT); 273 mListFragment = fragment; 274 break; 275 } 276 277 case ContactsRequest.ACTION_DEFAULT: 278 case ContactsRequest.ACTION_PICK_CONTACT: { 279 ContactPickerFragment fragment = new ContactPickerFragment(); 280 fragment.setIncludeFavorites(mRequest.shouldIncludeFavorites()); 281 fragment.setListType(ListEvent.ListType.PICK_CONTACT); 282 mListFragment = fragment; 283 break; 284 } 285 286 case ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT: { 287 ContactPickerFragment fragment = new ContactPickerFragment(); 288 fragment.setCreateContactEnabled(!mRequest.isSearchMode()); 289 fragment.setListType(ListEvent.ListType.PICK_CONTACT); 290 mListFragment = fragment; 291 break; 292 } 293 294 case ContactsRequest.ACTION_CREATE_SHORTCUT_CONTACT: { 295 ContactPickerFragment fragment = new ContactPickerFragment(); 296 fragment.setShortcutRequested(true); 297 fragment.setListType(ListEvent.ListType.PICK_CONTACT_FOR_SHORTCUT); 298 mListFragment = fragment; 299 break; 300 } 301 302 case ContactsRequest.ACTION_PICK_PHONE: { 303 PhoneNumberPickerFragment fragment = getPhoneNumberPickerFragment(mRequest); 304 fragment.setListType(ListEvent.ListType.PICK_PHONE); 305 mListFragment = fragment; 306 break; 307 } 308 309 case ContactsRequest.ACTION_PICK_EMAIL: { 310 mListFragment = new EmailAddressPickerFragment(); 311 mListFragment.setListType(ListEvent.ListType.PICK_EMAIL); 312 break; 313 } 314 315 case ContactsRequest.ACTION_PICK_PHONES: { 316 mListFragment = new MultiSelectPhoneNumbersListFragment(); 317 mListFragment.setArguments(getIntent().getExtras()); 318 break; 319 } 320 321 case ContactsRequest.ACTION_PICK_EMAILS: { 322 mListFragment = new MultiSelectEmailAddressesListFragment(); 323 mListFragment.setArguments(getIntent().getExtras()); 324 break; 325 } 326 case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: { 327 PhoneNumberPickerFragment fragment = getPhoneNumberPickerFragment(mRequest); 328 fragment.setShortcutAction(Intent.ACTION_CALL); 329 fragment.setListType(ListEvent.ListType.PICK_CONTACT_FOR_SHORTCUT); 330 mListFragment = fragment; 331 break; 332 } 333 334 case ContactsRequest.ACTION_CREATE_SHORTCUT_SMS: { 335 PhoneNumberPickerFragment fragment = getPhoneNumberPickerFragment(mRequest); 336 fragment.setShortcutAction(Intent.ACTION_SENDTO); 337 fragment.setListType(ListEvent.ListType.PICK_CONTACT_FOR_SHORTCUT); 338 mListFragment = fragment; 339 break; 340 } 341 342 case ContactsRequest.ACTION_PICK_POSTAL: { 343 PostalAddressPickerFragment fragment = new PostalAddressPickerFragment(); 344 fragment.setListType(ListEvent.ListType.PICK_POSTAL); 345 mListFragment = fragment; 346 break; 347 } 348 349 case ContactsRequest.ACTION_PICK_JOIN: { 350 JoinContactListFragment joinFragment = new JoinContactListFragment(); 351 joinFragment.setTargetContactId(getTargetContactId()); 352 joinFragment.setListType(ListEvent.ListType.PICK_JOIN); 353 mListFragment = joinFragment; 354 break; 355 } 356 357 case ContactsRequest.ACTION_PICK_GROUP_MEMBERS: { 358 final String accountName = getIntent().getStringExtra( 359 UiIntentActions.GROUP_ACCOUNT_NAME); 360 final String accountType = getIntent().getStringExtra( 361 UiIntentActions.GROUP_ACCOUNT_TYPE); 362 final String accountDataSet = getIntent().getStringExtra( 363 UiIntentActions.GROUP_ACCOUNT_DATA_SET); 364 final ArrayList<String> contactIds = getIntent().getStringArrayListExtra( 365 UiIntentActions.GROUP_CONTACT_IDS); 366 mListFragment = GroupMemberPickerFragment.newInstance( 367 accountName, accountType, accountDataSet, contactIds); 368 mListFragment.setListType(ListEvent.ListType.PICK_GROUP_MEMBERS); 369 break; 370 } 371 372 default: 373 throw new IllegalStateException("Invalid action code: " + mActionCode); 374 } 375 376 // Setting compatibility is no longer needed for PhoneNumberPickerFragment since that logic 377 // has been separated into LegacyPhoneNumberPickerFragment. But we still need to set 378 // compatibility for other fragments. 379 mListFragment.setLegacyCompatibilityMode(mRequest.isLegacyCompatibilityMode()); 380 mListFragment.setDirectoryResultLimit(DEFAULT_DIRECTORY_RESULT_LIMIT); 381 382 getFragmentManager().beginTransaction() 383 .replace(R.id.list_container, mListFragment) 384 .commitAllowingStateLoss(); 385 } 386 387 private PhoneNumberPickerFragment getPhoneNumberPickerFragment(ContactsRequest request) { 388 if (mRequest.isLegacyCompatibilityMode()) { 389 return new LegacyPhoneNumberPickerFragment(); 390 } else { 391 return new PhoneNumberPickerFragment(); 392 } 393 } 394 395 public void setupActionListener() { 396 if (mListFragment instanceof ContactPickerFragment) { 397 ((ContactPickerFragment) mListFragment).setOnContactPickerActionListener( 398 new ContactPickerActionListener()); 399 } else if (mListFragment instanceof PhoneNumberPickerFragment) { 400 ((PhoneNumberPickerFragment) mListFragment).setOnPhoneNumberPickerActionListener( 401 new PhoneNumberPickerActionListener()); 402 } else if (mListFragment instanceof PostalAddressPickerFragment) { 403 ((PostalAddressPickerFragment) mListFragment).setOnPostalAddressPickerActionListener( 404 new PostalAddressPickerActionListener()); 405 } else if (mListFragment instanceof EmailAddressPickerFragment) { 406 ((EmailAddressPickerFragment) mListFragment).setOnEmailAddressPickerActionListener( 407 new EmailAddressPickerActionListener()); 408 } else if (mListFragment instanceof MultiSelectEmailAddressesListFragment) { 409 ((MultiSelectEmailAddressesListFragment) mListFragment).setCheckBoxListListener(this); 410 } else if (mListFragment instanceof MultiSelectPhoneNumbersListFragment) { 411 ((MultiSelectPhoneNumbersListFragment) mListFragment).setCheckBoxListListener(this); 412 } else if (mListFragment instanceof JoinContactListFragment) { 413 ((JoinContactListFragment) mListFragment).setOnContactPickerActionListener( 414 new JoinContactActionListener()); 415 } else if (mListFragment instanceof GroupMemberPickerFragment) { 416 ((GroupMemberPickerFragment) mListFragment).setListener( 417 new GroupMemberPickerListener()); 418 getMultiSelectListFragment().setCheckBoxListListener(this); 419 } else { 420 throw new IllegalStateException("Unsupported list fragment type: " + mListFragment); 421 } 422 } 423 424 private MultiSelectContactsListFragment getMultiSelectListFragment() { 425 if (mListFragment instanceof MultiSelectContactsListFragment) { 426 return (MultiSelectContactsListFragment) mListFragment; 427 } 428 return null; 429 } 430 431 @Override 432 public void onAction(int action) { 433 switch (action) { 434 case ActionBarAdapter.Listener.Action.START_SEARCH_MODE: 435 mIsSearchMode = true; 436 configureSearchMode(); 437 break; 438 case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY: 439 final String queryString = mActionBarAdapter.getQueryString(); 440 mListFragment.setQueryString(queryString, /* delaySelection */ false); 441 break; 442 case ActionBarAdapter.Listener.Action.START_SELECTION_MODE: 443 if (getMultiSelectListFragment() != null) { 444 getMultiSelectListFragment().displayCheckBoxes(true); 445 } 446 invalidateOptionsMenu(); 447 break; 448 case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE: 449 mListFragment.setQueryString("", /* delaySelection */ false); 450 mActionBarAdapter.setSearchMode(false); 451 if (getMultiSelectListFragment() != null) { 452 getMultiSelectListFragment().displayCheckBoxes(false); 453 } 454 invalidateOptionsMenu(); 455 break; 456 } 457 } 458 459 @Override 460 public void onUpButtonPressed() { 461 onBackPressed(); 462 } 463 464 @Override 465 public void onStartDisplayingCheckBoxes() { 466 mActionBarAdapter.setSelectionMode(true); 467 } 468 469 @Override 470 public void onSelectedContactIdsChanged() { 471 if (mListFragment instanceof MultiSelectContactsListFragment) { 472 final int count = getMultiSelectListFragment().getSelectedContactIds().size(); 473 mActionBarAdapter.setSelectionCount(count); 474 updateAddContactsButton(count); 475 476 // Show or hide the multi select "Done" button 477 invalidateOptionsMenu(); 478 } 479 } 480 481 private void updateAddContactsButton(int count) { 482 final TextView textView = (TextView) mActionBarAdapter.getSelectionContainer() 483 .findViewById(R.id.add_contacts); 484 if (count > 0) { 485 textView.setVisibility(View.VISIBLE); 486 textView.setAllCaps(true); 487 textView.setOnClickListener(new OnClickListener() { 488 @Override 489 public void onClick(View v) { 490 final long[] contactIds = 491 getMultiSelectListFragment().getSelectedContactIdsArray(); 492 returnSelectedContacts(contactIds); 493 } 494 }); 495 } else { 496 textView.setVisibility(View.GONE); 497 } 498 } 499 500 @Override 501 public void onStopDisplayingCheckBoxes() { 502 mActionBarAdapter.setSelectionMode(false); 503 } 504 505 private final class ContactPickerActionListener implements OnContactPickerActionListener { 506 @Override 507 public void onCreateNewContactAction() { 508 startCreateNewContactActivity(); 509 } 510 511 @Override 512 public void onEditContactAction(Uri contactLookupUri) { 513 startActivityAndForwardResult(EditorIntents.createEditContactIntent( 514 ContactSelectionActivity.this, contactLookupUri, /* materialPalette =*/ null, 515 /* photoId =*/ -1)); 516 } 517 518 @Override 519 public void onPickContactAction(Uri contactUri) { 520 returnPickerResult(contactUri); 521 } 522 523 @Override 524 public void onShortcutIntentCreated(Intent intent) { 525 returnPickerResult(intent); 526 } 527 } 528 529 private final class PhoneNumberPickerActionListener implements 530 OnPhoneNumberPickerActionListener { 531 @Override 532 public void onPickDataUri(Uri dataUri, boolean isVideoCall, int callInitiationType) { 533 returnPickerResult(dataUri); 534 } 535 536 @Override 537 public void onPickPhoneNumber(String phoneNumber, boolean isVideoCall, 538 int callInitiationType) { 539 Log.w(TAG, "Unsupported call."); 540 } 541 542 @Override 543 public void onShortcutIntentCreated(Intent intent) { 544 returnPickerResult(intent); 545 } 546 547 @Override 548 public void onHomeInActionBarSelected() { 549 ContactSelectionActivity.this.onBackPressed(); 550 } 551 } 552 553 private final class JoinContactActionListener implements OnContactPickerActionListener { 554 @Override 555 public void onPickContactAction(Uri contactUri) { 556 Intent intent = new Intent(null, contactUri); 557 setResult(RESULT_OK, intent); 558 finish(); 559 } 560 561 @Override 562 public void onShortcutIntentCreated(Intent intent) { 563 } 564 565 @Override 566 public void onCreateNewContactAction() { 567 } 568 569 @Override 570 public void onEditContactAction(Uri contactLookupUri) { 571 } 572 } 573 574 private final class GroupMemberPickerListener implements GroupMemberPickerFragment.Listener { 575 576 @Override 577 public void onGroupMemberClicked(long contactId) { 578 final Intent intent = new Intent(); 579 intent.putExtra(UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, contactId); 580 returnPickerResult(intent); 581 } 582 583 @Override 584 public void onSelectGroupMembers() { 585 mActionBarAdapter.setSelectionMode(true); 586 } 587 } 588 589 private void returnSelectedContacts(long[] contactIds) { 590 final Intent intent = new Intent(); 591 intent.putExtra(UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY, contactIds); 592 returnPickerResult(intent); 593 } 594 595 private final class PostalAddressPickerActionListener implements 596 OnPostalAddressPickerActionListener { 597 @Override 598 public void onPickPostalAddressAction(Uri dataUri) { 599 returnPickerResult(dataUri); 600 } 601 } 602 603 private final class EmailAddressPickerActionListener implements 604 OnEmailAddressPickerActionListener { 605 @Override 606 public void onPickEmailAddressAction(Uri dataUri) { 607 returnPickerResult(dataUri); 608 } 609 } 610 611 public void startActivityAndForwardResult(final Intent intent) { 612 intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); 613 614 // Forward extras to the new activity 615 Bundle extras = getIntent().getExtras(); 616 if (extras != null) { 617 intent.putExtras(extras); 618 } 619 try { 620 ImplicitIntentsUtil.startActivityInApp(ContactSelectionActivity.this, intent); 621 } catch (ActivityNotFoundException e) { 622 Log.e(TAG, "startActivity() failed: " + e); 623 Toast.makeText(ContactSelectionActivity.this, R.string.missing_app, 624 Toast.LENGTH_SHORT).show(); 625 } 626 finish(); 627 } 628 629 @Override 630 public void onFocusChange(View view, boolean hasFocus) { 631 if (view.getId() == R.id.search_view) { 632 if (hasFocus) { 633 mActionBarAdapter.setFocusOnSearchView(); 634 } 635 } 636 } 637 638 public void returnPickerResult(Uri data) { 639 Intent intent = new Intent(); 640 intent.setData(data); 641 returnPickerResult(intent); 642 } 643 644 public void returnPickerResult(Intent intent) { 645 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 646 setResult(RESULT_OK, intent); 647 finish(); 648 } 649 650 @Override 651 public void onClick(View view) { 652 if (view.getId() == R.id.floating_action_button) { 653 startCreateNewContactActivity(); 654 } 655 } 656 657 private long getTargetContactId() { 658 Intent intent = getIntent(); 659 final long targetContactId = intent.getLongExtra( 660 UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, -1); 661 if (targetContactId == -1) { 662 Log.e(TAG, "Intent " + intent.getAction() + " is missing required extra: " 663 + UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY); 664 setResult(RESULT_CANCELED); 665 finish(); 666 return -1; 667 } 668 return targetContactId; 669 } 670 671 private void startCreateNewContactActivity() { 672 Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); 673 intent.putExtra(ContactEditorActivity. 674 INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true); 675 startActivityAndForwardResult(intent); 676 } 677 678 @Override 679 public boolean onCreateOptionsMenu(Menu menu) { 680 super.onCreateOptionsMenu(menu); 681 682 final MenuInflater inflater = getMenuInflater(); 683 inflater.inflate(R.menu.search_menu, menu); 684 685 final MenuItem searchItem = menu.findItem(R.id.menu_search); 686 searchItem.setVisible(!mIsSearchMode && mIsSearchSupported); 687 688 final Drawable searchIcon = searchItem.getIcon(); 689 if (searchIcon != null) { 690 searchIcon.mutate().setColorFilter(ContextCompat.getColor(this, 691 R.color.actionbar_icon_color), PorterDuff.Mode.SRC_ATOP); 692 } 693 return true; 694 } 695 696 @Override 697 public void onBackPressed() { 698 if (!isSafeToCommitTransactions()) { 699 return; 700 } 701 702 if (isSelectionMode()) { 703 mActionBarAdapter.setSelectionMode(false); 704 if (getMultiSelectListFragment() != null) { 705 getMultiSelectListFragment().displayCheckBoxes(false); 706 } 707 } else if (mIsSearchMode) { 708 mIsSearchMode = false; 709 configureSearchMode(); 710 } else { 711 super.onBackPressed(); 712 } 713 } 714} 715