blob: c247d43289f267489cf3c000fb021e15e6c66658 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.contacts.activities;
import com.android.contacts.ContactLoader;
import com.android.contacts.ContactSaveService;
import com.android.contacts.ContactsActivity;
import com.android.contacts.R;
import com.android.contacts.detail.ContactDetailFragment;
import com.android.contacts.group.GroupBrowseListFragment;
import com.android.contacts.group.GroupBrowseListFragment.OnGroupBrowserActionListener;
import com.android.contacts.group.GroupDetailFragment;
import com.android.contacts.interactions.ContactDeletionInteraction;
import com.android.contacts.interactions.ImportExportDialogFragment;
import com.android.contacts.interactions.PhoneNumberInteraction;
import com.android.contacts.list.ContactBrowseListContextMenuAdapter;
import com.android.contacts.list.ContactBrowseListFragment;
import com.android.contacts.list.ContactEntryListFragment;
import com.android.contacts.list.ContactListFilter;
import com.android.contacts.list.ContactListFilterController;
import com.android.contacts.list.ContactsIntentResolver;
import com.android.contacts.list.ContactsRequest;
import com.android.contacts.list.ContactsUnavailableFragment;
import com.android.contacts.list.CustomContactListFilterActivity;
import com.android.contacts.list.DefaultContactBrowseListFragment;
import com.android.contacts.list.DirectoryListLoader;
import com.android.contacts.list.OnContactBrowserActionListener;
import com.android.contacts.list.OnContactsUnavailableActionListener;
import com.android.contacts.list.ProviderStatusLoader;
import com.android.contacts.list.ProviderStatusLoader.ProviderStatusListener;
import com.android.contacts.list.StrequentContactListFragment;
import com.android.contacts.preference.ContactsPreferenceActivity;
import com.android.contacts.util.AccountSelectionUtil;
import com.android.contacts.util.DialogManager;
import com.android.contacts.widget.ContextMenuAdapter;
import android.accounts.Account;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Activity;
import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.ProviderStatus;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.SearchView;
import android.widget.Toast;
import java.util.ArrayList;
/**
* Displays a list to browse contacts. For xlarge screens, this also displays a detail-pane on
* the right.
*/
public class PeopleActivity extends ContactsActivity
implements View.OnCreateContextMenuListener, ActionBarAdapter.Listener,
DialogManager.DialogShowingViewActivity,
ContactListFilterController.ContactListFilterListener, ProviderStatusListener {
private static final String TAG = "PeopleActivity";
private static final int SUBACTIVITY_NEW_CONTACT = 2;
private static final int SUBACTIVITY_EDIT_CONTACT = 3;
private static final int SUBACTIVITY_CUSTOMIZE_FILTER = 4;
private static final String KEY_SEARCH_MODE = "searchMode";
private DialogManager mDialogManager = new DialogManager(this);
private ContactsIntentResolver mIntentResolver;
private ContactsRequest mRequest;
private ActionBarAdapter mActionBarAdapter;
private boolean mSearchMode;
private ContactBrowseListFragment mListFragment;
/**
* Whether we have a right-side contact or group detail pane for displaying info on that
* contact or group while browsing. Generally means "this is a tablet".
*/
private boolean mContentPaneDisplayed;
private ContactDetailFragment mContactDetailFragment;
private ContactDetailFragmentListener mContactDetailFragmentListener =
new ContactDetailFragmentListener();
private GroupDetailFragment mGroupDetailFragment;
private PhoneNumberInteraction mPhoneNumberCallInteraction;
private PhoneNumberInteraction mSendTextMessageInteraction;
private boolean mSearchInitiated;
private ContactListFilterController mContactListFilterController;
private ContactsUnavailableFragment mContactsUnavailableFragment;
private ProviderStatusLoader mProviderStatusLoader;
private int mProviderStatus = -1;
private boolean mOptionsMenuContactsAvailable;
private DefaultContactBrowseListFragment mContactsFragment;
private StrequentContactListFragment mFavoritesFragment;
private GroupBrowseListFragment mGroupsFragment;
private enum TabState {
FAVORITES, CONTACTS, GROUPS
}
private TabState mSelectedTab;
public PeopleActivity() {
mIntentResolver = new ContactsIntentResolver(this);
// TODO: Get rid of the ContactListFilterController class because there aren't any
// dropdown filters anymore. Just store the selected filter as a member variable.
mContactListFilterController = new ContactListFilterController(this);
mContactListFilterController.addListener(this);
mProviderStatusLoader = new ProviderStatusLoader(this);
}
public boolean areContactsAvailable() {
return mProviderStatus == ProviderStatus.STATUS_NORMAL;
}
@Override
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof ContactBrowseListFragment) {
mListFragment = (ContactBrowseListFragment)fragment;
mListFragment.setOnContactListActionListener(new ContactBrowserActionListener());
if (!getWindow().hasFeature(Window.FEATURE_ACTION_BAR)) {
mListFragment.setContextMenuAdapter(
new ContactBrowseListContextMenuAdapter(mListFragment));
}
} else if (fragment instanceof GroupBrowseListFragment) {
mGroupsFragment = (GroupBrowseListFragment) fragment;
mGroupsFragment.setListener(new GroupBrowserActionListener());
} else if (fragment instanceof ContactDetailFragment) {
mContactDetailFragment = (ContactDetailFragment) fragment;
mContactDetailFragment.setListener(mContactDetailFragmentListener);
mContentPaneDisplayed = true;
} else if (fragment instanceof ContactsUnavailableFragment) {
mContactsUnavailableFragment = (ContactsUnavailableFragment)fragment;
mContactsUnavailableFragment.setProviderStatusLoader(mProviderStatusLoader);
mContactsUnavailableFragment.setOnContactsUnavailableActionListener(
new ContactsUnavailableFragmentListener());
} else if (fragment instanceof GroupDetailFragment) {
mGroupDetailFragment = (GroupDetailFragment) fragment;
mContentPaneDisplayed = true;
}
}
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
configureContentView(true, savedState);
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
configureContentView(false, null);
}
private void configureContentView(boolean createContentView, Bundle savedState) {
// Extract relevant information from the intent
mRequest = mIntentResolver.resolveIntent(getIntent());
if (!mRequest.isValid()) {
setResult(RESULT_CANCELED);
finish();
return;
}
Intent redirect = mRequest.getRedirectIntent();
if (redirect != null) {
// Need to start a different activity
startActivity(redirect);
finish();
return;
}
if (createContentView) {
setContentView(R.layout.people_activity);
final FragmentManager fragmentManager = getFragmentManager();
mFavoritesFragment = (StrequentContactListFragment) fragmentManager
.findFragmentById(R.id.favorites_fragment);
mContactsFragment = (DefaultContactBrowseListFragment) fragmentManager
.findFragmentById(R.id.contacts_fragment);
mGroupsFragment = (GroupBrowseListFragment) fragmentManager
.findFragmentById(R.id.groups_fragment);
// Hide all tabs (the current tab will later be reshown once a tab is selected)
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.hide(mFavoritesFragment);
transaction.hide(mContactsFragment);
transaction.hide(mGroupsFragment);
if (mContactDetailFragment != null) {
transaction.hide(mContactDetailFragment);
}
if (mGroupDetailFragment != null) {
transaction.hide(mGroupDetailFragment);
}
transaction.commit();
}
if (mRequest.getActionCode() == ContactsRequest.ACTION_VIEW_CONTACT
&& !mContentPaneDisplayed) {
redirect = new Intent(this, ContactDetailActivity.class);
redirect.setAction(Intent.ACTION_VIEW);
redirect.setData(mRequest.getContactUri());
startActivity(redirect);
finish();
return;
}
setTitle(mRequest.getActivityTitle());
ActionBar actionBar = getActionBar();
mActionBarAdapter = new ActionBarAdapter(this, this);
mActionBarAdapter.onCreate(savedState, mRequest, getActionBar(), !mContentPaneDisplayed);
mActionBarAdapter.setContactListFilterController(mContactListFilterController);
if (createContentView) {
actionBar.removeAllTabs();
Tab favoritesTab = actionBar.newTab();
favoritesTab.setText(getString(R.string.strequentList));
favoritesTab.setTabListener(new TabChangeListener(mFavoritesFragment,
mContactDetailFragment, TabState.FAVORITES));
actionBar.addTab(favoritesTab);
Tab peopleTab = actionBar.newTab();
peopleTab.setText(getString(R.string.people));
peopleTab.setTabListener(new TabChangeListener(mContactsFragment,
mContactDetailFragment, TabState.CONTACTS));
actionBar.addTab(peopleTab);
Tab groupsTab = actionBar.newTab();
groupsTab.setText(getString(R.string.contactsGroupsLabel));
groupsTab.setTabListener(new TabChangeListener(mGroupsFragment,
mGroupDetailFragment, TabState.GROUPS));
actionBar.addTab(groupsTab);
actionBar.setDisplayShowTitleEnabled(true);
TypedArray a = obtainStyledAttributes(null, R.styleable.ActionBarHomeIcon);
boolean showHomeIcon = a.getBoolean(R.styleable.ActionBarHomeIcon_show_home_icon, true);
actionBar.setDisplayShowHomeEnabled(showHomeIcon);
invalidateOptionsMenuIfNeeded();
}
configureFragments(savedState == null);
}
/**
* Tab change listener that is instantiated once for each tab. Handles showing/hiding fragments.
* TODO: Use ViewPager so that tabs can be swiped left and right. Figure out how to use the
* support library in our app.
*/
private class TabChangeListener implements TabListener {
private final Fragment mBrowseListFragment;
/**
* Right pane fragment that is present on larger screen sizes (can be
* null for smaller screen sizes).
*/
private final Fragment mDetailFragment;
private final TabState mTabState;
public TabChangeListener(Fragment listFragment, Fragment detailFragment, TabState state) {
mBrowseListFragment = listFragment;
mDetailFragment = detailFragment;
mTabState = state;
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.hide(mBrowseListFragment);
if (mDetailFragment != null) {
ft.hide(mDetailFragment);
}
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.show(mBrowseListFragment);
if (mDetailFragment != null) {
ft.show(mDetailFragment);
}
setSelectedTab(mTabState);
invalidateOptionsMenu();
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
private void setSelectedTab(TabState tab) {
mSelectedTab = tab;
}
@Override
protected void onPause() {
if (mActionBarAdapter != null) {
mActionBarAdapter.setListener(null);
}
mOptionsMenuContactsAvailable = false;
mProviderStatus = -1;
mProviderStatusLoader.setProviderStatusListener(null);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if (mActionBarAdapter != null) {
mActionBarAdapter.setListener(this);
}
mProviderStatusLoader.setProviderStatusListener(this);
updateFragmentVisibility();
}
@Override
protected void onStart() {
mContactListFilterController.onStart();
super.onStart();
}
private void configureFragments(boolean fromRequest) {
if (fromRequest) {
ContactListFilter filter = null;
int actionCode = mRequest.getActionCode();
switch (actionCode) {
case ContactsRequest.ACTION_ALL_CONTACTS:
filter = ContactListFilter.createFilterWithType(
ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
break;
case ContactsRequest.ACTION_CONTACTS_WITH_PHONES:
filter = ContactListFilter.createFilterWithType(
ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY);
break;
// TODO: handle FREQUENT and STREQUENT according to the spec
case ContactsRequest.ACTION_FREQUENT:
case ContactsRequest.ACTION_STREQUENT:
// For now they are treated the same as STARRED
case ContactsRequest.ACTION_STARRED:
filter = ContactListFilter.createFilterWithType(
ContactListFilter.FILTER_TYPE_STARRED);
break;
}
mSearchMode = mRequest.isSearchMode();
if (filter != null) {
mContactListFilterController.setContactListFilter(filter, false);
mSearchMode = false;
} else if (mRequest.getActionCode() == ContactsRequest.ACTION_ALL_CONTACTS) {
mContactListFilterController.setContactListFilter(
ContactListFilter.createFilterWithType(
ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS), false);
}
if (mRequest.getContactUri() != null) {
mSearchMode = false;
}
mListFragment.setContactsRequest(mRequest);
configureContactListFragmentForRequest();
} else {
mSearchMode = mActionBarAdapter.isSearchMode();
}
configureContactListFragment();
configureGroupListFragment();
invalidateOptionsMenuIfNeeded();
}
@Override
public void onContactListFiltersLoaded() {
if (mListFragment == null || !mListFragment.isAdded()) {
return;
}
mListFragment.setFilter(mContactListFilterController.getFilter());
invalidateOptionsMenuIfNeeded();
}
@Override
public void onContactListFilterChanged() {
if (mListFragment == null || !mListFragment.isAdded()) {
return;
}
mListFragment.setFilter(mContactListFilterController.getFilter());
invalidateOptionsMenuIfNeeded();
}
@Override
public void onContactListFilterCustomizationRequest() {
startActivityForResult(new Intent(this, CustomContactListFilterActivity.class),
SUBACTIVITY_CUSTOMIZE_FILTER);
}
private void setupContactDetailFragment(final Uri contactLookupUri) {
mContactDetailFragment.loadUri(contactLookupUri);
invalidateOptionsMenuIfNeeded();
}
private void setupGroupDetailFragment(Uri groupUri) {
mGroupDetailFragment.loadGroup(groupUri);
invalidateOptionsMenuIfNeeded();
}
/**
* Handler for action bar actions.
*/
@Override
public void onAction(Action action) {
switch (action) {
case START_SEARCH_MODE:
// Bring the contact list fragment (and detail fragment if applicable) to the front
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.show(mContactsFragment);
if (mContactDetailFragment != null) ft.show(mContactDetailFragment);
ft.commit();
clearSearch();
break;
case STOP_SEARCH_MODE:
// Refresh the fragments because search mode was using them to display search
// results.
clearSearch();
// If the last selected tab was not the "All contacts" tab, then hide these
// fragments because we need to show favorites or groups.
if (mSelectedTab != null && !mSelectedTab.equals(TabState.CONTACTS)) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.hide(mContactsFragment);
if (mContactDetailFragment != null) transaction.hide(mContactDetailFragment);
transaction.commit();
}
break;
case CHANGE_SEARCH_QUERY:
loadSearch(mActionBarAdapter.getQueryString());
break;
default:
throw new IllegalStateException("Unkonwn ActionBarAdapter action: " + action);
}
}
private void clearSearch() {
loadSearch("");
}
private void loadSearch(String query) {
configureFragments(false /* from request */);
mListFragment.setQueryString(query, true);
}
private void configureContactListFragmentForRequest() {
Uri contactUri = mRequest.getContactUri();
if (contactUri != null) {
mListFragment.setSelectedContactUri(contactUri);
}
mListFragment.setSearchMode(mRequest.isSearchMode());
mListFragment.setQueryString(mRequest.getQueryString(), false);
if (mRequest.isDirectorySearchEnabled()) {
mListFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DEFAULT);
} else {
mListFragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
}
if (mContactListFilterController.isLoaded()) {
mListFragment.setFilter(mContactListFilterController.getFilter());
}
}
private void configureContactListFragment() {
mListFragment.setSearchMode(mSearchMode);
mListFragment.setVisibleScrollbarEnabled(!mSearchMode);
mListFragment.setVerticalScrollbarPosition(
mContentPaneDisplayed
? View.SCROLLBAR_POSITION_LEFT
: View.SCROLLBAR_POSITION_RIGHT);
mListFragment.setSelectionVisible(mContentPaneDisplayed);
mListFragment.setQuickContactEnabled(!mContentPaneDisplayed);
}
private void configureGroupListFragment() {
mGroupsFragment.setVerticalScrollbarPosition(
mContentPaneDisplayed
? View.SCROLLBAR_POSITION_LEFT
: View.SCROLLBAR_POSITION_RIGHT);
mGroupsFragment.setSelectionVisible(mContentPaneDisplayed);
}
@Override
public void onProviderStatusChange() {
updateFragmentVisibility();
}
private void updateFragmentVisibility() {
int providerStatus = mProviderStatusLoader.getProviderStatus();
if (providerStatus == mProviderStatus) {
return;
}
mProviderStatus = providerStatus;
View contactsUnavailableView = findViewById(R.id.contacts_unavailable_view);
View mainView = findViewById(R.id.main_view);
if (mProviderStatus == ProviderStatus.STATUS_NORMAL) {
contactsUnavailableView.setVisibility(View.GONE);
if (mainView != null) {
mainView.setVisibility(View.VISIBLE);
}
if (mListFragment != null) {
mListFragment.setEnabled(true);
}
} else {
if (mListFragment != null) {
mListFragment.setEnabled(false);
}
if (mContactsUnavailableFragment == null) {
mContactsUnavailableFragment = new ContactsUnavailableFragment();
mContactsUnavailableFragment.setProviderStatusLoader(mProviderStatusLoader);
mContactsUnavailableFragment.setOnContactsUnavailableActionListener(
new ContactsUnavailableFragmentListener());
getFragmentManager().beginTransaction()
.replace(R.id.contacts_unavailable_container, mContactsUnavailableFragment)
.commit();
} else {
mContactsUnavailableFragment.update();
}
contactsUnavailableView.setVisibility(View.VISIBLE);
if (mainView != null) {
mainView.setVisibility(View.INVISIBLE);
}
}
invalidateOptionsMenuIfNeeded();
}
private final class ContactBrowserActionListener implements OnContactBrowserActionListener {
@Override
public void onSelectionChange() {
if (mContentPaneDisplayed) {
setupContactDetailFragment(mListFragment.getSelectedContactUri());
}
}
@Override
public void onViewContactAction(Uri contactLookupUri) {
if (mContentPaneDisplayed) {
setupContactDetailFragment(contactLookupUri);
} else {
startActivity(new Intent(Intent.ACTION_VIEW, contactLookupUri));
}
}
@Override
public void onCreateNewContactAction() {
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
Bundle extras = getIntent().getExtras();
if (extras != null) {
intent.putExtras(extras);
}
startActivity(intent);
}
@Override
public void onEditContactAction(Uri contactLookupUri) {
Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri);
Bundle extras = getIntent().getExtras();
if (extras != null) {
intent.putExtras(extras);
}
startActivityForResult(intent, SUBACTIVITY_EDIT_CONTACT);
}
@Override
public void onAddToFavoritesAction(Uri contactUri) {
ContentValues values = new ContentValues(1);
values.put(Contacts.STARRED, 1);
getContentResolver().update(contactUri, values, null, null);
}
@Override
public void onRemoveFromFavoritesAction(Uri contactUri) {
ContentValues values = new ContentValues(1);
values.put(Contacts.STARRED, 0);
getContentResolver().update(contactUri, values, null, null);
}
@Override
public void onCallContactAction(Uri contactUri) {
getPhoneNumberCallInteraction().startInteraction(contactUri);
}
@Override
public void onSmsContactAction(Uri contactUri) {
getSendTextMessageInteraction().startInteraction(contactUri);
}
@Override
public void onDeleteContactAction(Uri contactUri) {
ContactDeletionInteraction.start(PeopleActivity.this, contactUri, false);
}
@Override
public void onFinishAction() {
onBackPressed();
}
@Override
public void onInvalidSelection() {
ContactListFilter filter;
ContactListFilter currentFilter = mListFragment.getFilter();
if (currentFilter != null
&& currentFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
filter = ContactListFilter.createFilterWithType(
ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
mListFragment.setFilter(filter);
} else {
filter = ContactListFilter.createFilterWithType(
ContactListFilter.FILTER_TYPE_SINGLE_CONTACT);
mListFragment.setFilter(filter, false);
}
mContactListFilterController.setContactListFilter(filter, true);
}
}
private class ContactDetailFragmentListener implements ContactDetailFragment.Listener {
@Override
public void onContactNotFound() {
// Nothing needs to be done here
}
@Override
public void onDetailsLoaded(ContactLoader.Result result) {
// Nothing needs to be done here
}
@Override
public void onEditRequested(Uri contactLookupUri) {
startActivityForResult(
new Intent(Intent.ACTION_EDIT, contactLookupUri), SUBACTIVITY_EDIT_CONTACT);
}
@Override
public void onItemClicked(Intent intent) {
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "No activity found for intent: " + intent);
}
}
@Override
public void onDeleteRequested(Uri contactUri) {
ContactDeletionInteraction.start(PeopleActivity.this, contactUri, false);
}
@Override
public void onCreateRawContactRequested(ArrayList<ContentValues> values, Account account) {
Toast.makeText(PeopleActivity.this, R.string.toast_making_personal_copy,
Toast.LENGTH_LONG).show();
Intent serviceIntent = ContactSaveService.createNewRawContactIntent(
PeopleActivity.this, values, account,
PeopleActivity.class, Intent.ACTION_VIEW);
startService(serviceIntent);
}
}
private class ContactsUnavailableFragmentListener
implements OnContactsUnavailableActionListener {
@Override
public void onCreateNewContactAction() {
startActivity(new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
}
@Override
public void onAddAccountAction() {
Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.putExtra(Settings.EXTRA_AUTHORITIES,
new String[] { ContactsContract.AUTHORITY });
startActivity(intent);
}
@Override
public void onImportContactsFromFileAction() {
AccountSelectionUtil.doImportFromSdCard(PeopleActivity.this, null);
}
@Override
public void onFreeInternalStorageAction() {
startActivity(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
}
}
private final class GroupBrowserActionListener implements OnGroupBrowserActionListener {
@Override
public void onViewGroupAction(Uri groupUri) {
if (mContentPaneDisplayed) {
setupGroupDetailFragment(groupUri);
} else {
Intent intent = new Intent(PeopleActivity.this, GroupDetailActivity.class);
intent.setData(groupUri);
startActivity(intent);
}
}
}
public void startActivityAndForwardResult(final Intent intent) {
intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
// Forward extras to the new activity
Bundle extras = getIntent().getExtras();
if (extras != null) {
intent.putExtras(extras);
}
startActivity(intent);
finish();
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
// No menu if contacts are unavailable
if (!areContactsAvailable()) {
return false;
}
return super.onCreatePanelMenu(featureId, menu);
}
@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
// No menu if contacts are unavailable
if (!areContactsAvailable()) {
return false;
}
return super.onPreparePanel(featureId, view, menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!areContactsAvailable()) {
return false;
}
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.actions, menu);
MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
if (searchMenuItem != null && searchMenuItem.getActionView() instanceof SearchView) {
SearchView searchView = (SearchView) searchMenuItem.getActionView();
searchView.setQueryHint(getString(R.string.hint_findContacts));
searchView.setIconifiedByDefault(false);
if (mActionBarAdapter != null) {
mActionBarAdapter.setSearchView(searchView);
}
}
return true;
}
private void invalidateOptionsMenuIfNeeded() {
if (isOptionsMenuChanged()) {
invalidateOptionsMenu();
}
}
public boolean isOptionsMenuChanged() {
if (mOptionsMenuContactsAvailable != areContactsAvailable()) {
return true;
}
if (mListFragment != null && mListFragment.isOptionsMenuChanged()) {
return true;
}
if (mContactDetailFragment != null && mContactDetailFragment.isOptionsMenuChanged()) {
return true;
}
if (mGroupDetailFragment != null && mGroupDetailFragment.isOptionsMenuChanged()) {
return true;
}
return false;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
mOptionsMenuContactsAvailable = areContactsAvailable();
if (!mOptionsMenuContactsAvailable) {
return false;
}
final MenuItem addContactMenu = menu.findItem(R.id.menu_add_contact);
final MenuItem addGroupMenu = menu.findItem(R.id.menu_add_group);
final MenuItem searchMenu = menu.findItem(R.id.menu_search);
if (mActionBarAdapter.isSearchMode()) {
addContactMenu.setVisible(false);
addGroupMenu.setVisible(false);
// If search is normally in the overflow menu, when we are in search
// mode, hide this option.
if (mActionBarAdapter.isSearchInOverflowMenu()) {
searchMenu.setVisible(false);
}
} else {
switch (mSelectedTab) {
case FAVORITES:
// TODO: Fall through until we determine what the menu items should be for
// this tab
case CONTACTS:
addContactMenu.setVisible(true);
addGroupMenu.setVisible(false);
break;
case GROUPS:
addContactMenu.setVisible(false);
addGroupMenu.setVisible(true);
break;
}
}
MenuItem settings = menu.findItem(R.id.menu_settings);
if (settings != null) {
settings.setVisible(!ContactsPreferenceActivity.isEmpty(this));
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings: {
final Intent intent = new Intent(this, ContactsPreferenceActivity.class);
startActivity(intent);
return true;
}
case R.id.menu_contacts_filter: {
final Intent intent = new Intent(this, CustomContactListFilterActivity.class);
startActivityForResult(intent, SUBACTIVITY_CUSTOMIZE_FILTER);
return true;
}
case R.id.menu_search: {
onSearchRequested();
return true;
}
case R.id.menu_add_contact: {
final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
startActivityForResult(intent, SUBACTIVITY_NEW_CONTACT);
return true;
}
case R.id.menu_add_group: {
// TODO: Hook up "new group" functionality
Toast.makeText(this, "NEW GROUP", Toast.LENGTH_SHORT).show();
return true;
}
case R.id.menu_import_export: {
ImportExportDialogFragment.show(getFragmentManager());
return true;
}
case R.id.menu_accounts: {
final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
ContactsContract.AUTHORITY
});
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(intent);
return true;
}
}
return false;
}
@Override
public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
boolean globalSearch) {
if (mListFragment != null && mListFragment.isAdded() && !globalSearch) {
mListFragment.startSearch(initialQuery);
} else {
super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
}
}
@Override
protected Dialog onCreateDialog(int id, Bundle bundle) {
if (DialogManager.isManagedId(id)) return mDialogManager.onCreateDialog(id, bundle);
Dialog dialog = getPhoneNumberCallInteraction().onCreateDialog(id, bundle);
if (dialog != null) return dialog;
dialog = getSendTextMessageInteraction().onCreateDialog(id, bundle);
if (dialog != null) return dialog;
return super.onCreateDialog(id, bundle);
}
@Override
protected void onPrepareDialog(int id, Dialog dialog, Bundle bundle) {
if (getPhoneNumberCallInteraction().onPrepareDialog(id, dialog, bundle)) {
return;
}
if (getSendTextMessageInteraction().onPrepareDialog(id, dialog, bundle)) {
return;
}
super.onPrepareDialog(id, dialog, bundle);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case SUBACTIVITY_CUSTOMIZE_FILTER: {
if (resultCode == Activity.RESULT_OK) {
mContactListFilterController.selectCustomFilter();
}
break;
}
case SUBACTIVITY_EDIT_CONTACT:
case SUBACTIVITY_NEW_CONTACT: {
if (resultCode == RESULT_OK && mContentPaneDisplayed) {
mRequest.setActionCode(ContactsRequest.ACTION_VIEW_CONTACT);
mListFragment.reloadDataAndSetSelectedUri(data.getData());
}
break;
}
// TODO: Using the new startActivityWithResultFromFragment API this should not be needed
// anymore
case ContactEntryListFragment.ACTIVITY_REQUEST_CODE_PICKER:
if (resultCode == RESULT_OK) {
mListFragment.onPickerResult(data);
}
// TODO fix or remove multipicker code
// else if (resultCode == RESULT_CANCELED && mMode == MODE_PICK_MULTIPLE_PHONES) {
// // Finish the activity if the sub activity was canceled as back key is used
// // to confirm user selection in MODE_PICK_MULTIPLE_PHONES.
// finish();
// }
// break;
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
ContextMenuAdapter menuAdapter = mListFragment.getContextMenuAdapter();
if (menuAdapter != null) {
return menuAdapter.onContextItemSelected(item);
}
return super.onContextItemSelected(item);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO move to the fragment
switch (keyCode) {
// case KeyEvent.KEYCODE_CALL: {
// if (callSelection()) {
// return true;
// }
// break;
// }
case KeyEvent.KEYCODE_DEL: {
if (deleteSelection()) {
return true;
}
break;
}
default: {
// Bring up the search UI if the user starts typing
final int unicodeChar = event.getUnicodeChar();
if (unicodeChar != 0 && !Character.isWhitespace(unicodeChar)) {
String query = new String(new int[]{ unicodeChar }, 0, 1);
if (!mActionBarAdapter.isSearchMode()) {
mActionBarAdapter.setQueryString(query);
mActionBarAdapter.setSearchMode(true);
return true;
} else if (!mRequest.isSearchMode()) {
if (!mSearchInitiated) {
mSearchInitiated = true;
startSearch(query, false, null, false);
return true;
}
}
}
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
if (mSearchMode && mActionBarAdapter != null) {
mActionBarAdapter.setSearchMode(false);
} else {
super.onBackPressed();
}
}
private boolean deleteSelection() {
// TODO move to the fragment
// if (mActionCode == ContactsRequest.ACTION_DEFAULT) {
// final int position = mListView.getSelectedItemPosition();
// if (position != ListView.INVALID_POSITION) {
// Uri contactUri = getContactUri(position);
// if (contactUri != null) {
// doContactDelete(contactUri);
// return true;
// }
// }
// }
return false;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_SEARCH_MODE, mSearchMode);
if (mActionBarAdapter != null) {
mActionBarAdapter.onSaveInstanceState(outState);
}
}
@Override
protected void onRestoreInstanceState(Bundle inState) {
super.onRestoreInstanceState(inState);
mSearchMode = inState.getBoolean(KEY_SEARCH_MODE);
if (mActionBarAdapter != null) {
mActionBarAdapter.onRestoreInstanceState(inState);
}
}
private PhoneNumberInteraction getPhoneNumberCallInteraction() {
if (mPhoneNumberCallInteraction == null) {
mPhoneNumberCallInteraction = new PhoneNumberInteraction(this, false, null);
}
return mPhoneNumberCallInteraction;
}
private PhoneNumberInteraction getSendTextMessageInteraction() {
if (mSendTextMessageInteraction == null) {
mSendTextMessageInteraction = new PhoneNumberInteraction(this, true, null);
}
return mSendTextMessageInteraction;
}
@Override
public DialogManager getDialogManager() {
return mDialogManager;
}
// Visible for testing
public ContactBrowseListFragment getListFragment() {
return mListFragment;
}
// Visible for testing
public ContactDetailFragment getDetailFragment() {
return mContactDetailFragment;
}
}