Handle saving and communicating selected tab between View/Edit activities.
EditContactActivity now accepts intents with raw_contacts instead of
contacts. In addition it reports back which raw_contact was selected on
exit.
ViewContactActivity now saves and restores which raw_contact was
currently being viewed, and uses the raw_contact reported back from
EditContactActivity. The overall effect is when moving from View->Edit
or Edit->View the selected tab doesn't change.
diff --git a/src/com/android/contacts/BaseContactCardActivity.java b/src/com/android/contacts/BaseContactCardActivity.java
index ef84e69..441aea1 100644
--- a/src/com/android/contacts/BaseContactCardActivity.java
+++ b/src/com/android/contacts/BaseContactCardActivity.java
@@ -72,6 +72,9 @@
protected static final int TAB_ACCOUNT_NAME_COLUMN_INDEX = 1;
protected static final int TAB_ACCOUNT_TYPE_COLUMN_INDEX = 2;
+ protected static final String SELECTED_RAW_CONTACT_ID_KEY = "selectedRawContact";
+ protected long mSelectedRawContactId;
+
private static final int TOKEN_TABS = 0;
@Override
@@ -101,6 +104,19 @@
asyncSetupTabs();
}
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ mSelectedRawContactId = savedInstanceState.getLong(SELECTED_RAW_CONTACT_ID_KEY);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putLong(SELECTED_RAW_CONTACT_ID_KEY, mSelectedRawContactId);
+ }
+
private void asyncSetupTabs() {
long contactId = ContentUris.parseId(mUri);
mHandler.startQueryEntities(TOKEN_TABS, null,
@@ -108,7 +124,7 @@
}
/**
- * Return the contactId associated with the tab at an index.
+ * Return the RawContact id associated with the tab at an index.
*
* @param index The index of the tab in question.
* @return The contactId associated with the tab at the specified index.
@@ -117,6 +133,22 @@
return mTabRawContactIdMap.get(index);
}
+ /**
+ * Return the tab index associated with the RawContact id.
+ *
+ * @param index The index of the tab in question.
+ * @return The contactId associated with the tab at the specified index.
+ */
+ protected int getTabIndexForRawContactId(long rawContactId) {
+ int numTabs = mTabRawContactIdMap.size();
+ for (int i=0; i < numTabs; i++) {
+ if (mTabRawContactIdMap.get(i) == rawContactId) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
/** {@inheritDoc} */
public void onQueryEntitiesComplete(int token, Object cookie, EntityIterator iterator) {
try{
@@ -170,7 +202,8 @@
ContactsSource.LEVEL_SUMMARY);
addTab(rawContactId, createTabIndicatorView(mTabWidget, source));
}
- mTabWidget.setCurrentTab(0);
+
+ selectInitialTab();
mTabWidget.setVisibility(View.VISIBLE);
mTabWidget.postInvalidate();
}
@@ -204,6 +237,18 @@
mTabWidget.removeAllTabs();
}
+ protected void selectInitialTab() {
+ int selectedTabIndex = -1;
+ if (mSelectedRawContactId > 0) {
+ selectedTabIndex = getTabIndexForRawContactId(mSelectedRawContactId);
+ }
+ if (selectedTabIndex >= 0) {
+ mTabWidget.setCurrentTab(selectedTabIndex);
+ } else {
+ selectDefaultTab();
+ }
+ }
+
/**
* Makes the default tab selection. This is called after the tabs have been
* bound for the first time, and whenever a new intent is received. Override
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index d2a01ca..33bbf1c 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -21,6 +21,8 @@
import java.io.ByteArrayInputStream;
import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+
import java.io.InputStream;
import android.net.Uri;
@@ -230,4 +232,22 @@
intent.putExtra("return-data", true);
return intent;
}
+
+ public static long queryForContactId(ContentResolver cr, long rawContactId) {
+ Cursor contactIdCursor = null;
+ long contactId = -1;
+ try {
+ contactIdCursor = cr.query(RawContacts.CONTENT_URI,
+ new String[] {RawContacts.CONTACT_ID},
+ RawContacts._ID + "=" + rawContactId, null, null);
+ if (contactIdCursor != null && contactIdCursor.moveToFirst()) {
+ contactId = contactIdCursor.getLong(0);
+ }
+ } finally {
+ if (contactIdCursor != null) {
+ contactIdCursor.close();
+ }
+ }
+ return contactId;
+ }
}
diff --git a/src/com/android/contacts/ViewContactActivity.java b/src/com/android/contacts/ViewContactActivity.java
index beaea44..2fd22b1 100644
--- a/src/com/android/contacts/ViewContactActivity.java
+++ b/src/com/android/contacts/ViewContactActivity.java
@@ -98,27 +98,29 @@
private static final String TAG = "ViewContact";
private static final String SHOW_BARCODE_INTENT = "com.google.zxing.client.android.ENCODE";
+ public static final String RAW_CONTACT_ID_EXTRA = "rawContactIdExtra";
+
private static final boolean SHOW_SEPARATORS = false;
private static final int DIALOG_CONFIRM_DELETE = 1;
- private static final int REQUEST_JOIN_AGGREGATE = 1;
+ private static final int REQUEST_JOIN_CONTACT = 1;
+ private static final int REQUEST_EDIT_CONTACT = 2;
- public static final int MENU_ITEM_DELETE = 1;
- public static final int MENU_ITEM_MAKE_DEFAULT = 2;
- public static final int MENU_ITEM_SHOW_BARCODE = 3;
- public static final int MENU_ITEM_SPLIT_AGGREGATE = 4;
- public static final int MENU_ITEM_JOIN_AGGREGATE = 5;
- public static final int MENU_ITEM_OPTIONS = 6;
+ public static final int MENU_ITEM_EDIT = 1;
+ public static final int MENU_ITEM_DELETE = 2;
+ public static final int MENU_ITEM_MAKE_DEFAULT = 3;
+ public static final int MENU_ITEM_SHOW_BARCODE = 4;
+ public static final int MENU_ITEM_SPLIT_AGGREGATE = 5;
+ public static final int MENU_ITEM_JOIN_AGGREGATE = 6;
+ public static final int MENU_ITEM_OPTIONS = 7;
private Uri mUri;
- private Uri mAggDataUri;
private ContentResolver mResolver;
private ViewAdapter mAdapter;
private int mNumPhoneNumbers = 0;
- private static final long ALL_CONTACTS_ID = -1;
- private long mRawContactId = ALL_CONTACTS_ID;
+ private static final long ALL_CONTACTS_ID = -100;
/**
* A list of distinct contact IDs included in the current contact.
@@ -182,7 +184,6 @@
mTabContentLayout.addView(mListView);
mUri = getIntent().getData();
- mAggDataUri = Uri.withAppendedPath(mUri, "data");
mResolver = getContentResolver();
// Build the list of sections. The order they're added to mSections dictates the
@@ -199,7 +200,10 @@
//TODO Read this value from a preference
mShowSmsLinksForAllPhones = true;
- mCursor = mResolver.query(mAggDataUri,
+ //Select the all tab to start.
+ mSelectedRawContactId = ALL_CONTACTS_ID;
+
+ mCursor = mResolver.query(Uri.withAppendedPath(mUri, "data"),
CONTACT_PROJECTION, null, null, null);
}
@@ -268,7 +272,7 @@
public void onTabSelectionChanged(int tabIndex, boolean clicked) {
long rawContactId = getTabRawContactId(tabIndex);
- mRawContactId = rawContactId;
+ mSelectedRawContactId = rawContactId;
dataChanged();
}
@@ -300,9 +304,8 @@
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, 0, 0, R.string.menu_editContact)
+ menu.add(0, MENU_ITEM_EDIT, 0, R.string.menu_editContact)
.setIcon(android.R.drawable.ic_menu_edit)
- .setIntent(new Intent(Intent.ACTION_EDIT, mUri))
.setAlphabeticShortcut('e');
menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_deleteContact)
.setIcon(android.R.drawable.ic_menu_delete);
@@ -381,6 +384,18 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
+ case MENU_ITEM_EDIT: {
+ long rawContactIdToEdit = mSelectedRawContactId;
+ if (rawContactIdToEdit == ALL_CONTACTS_ID) {
+ // If the "all" tab is selected, edit the next tab.
+ rawContactIdToEdit = getTabRawContactId(mTabWidget.getCurrentTab() + 1);
+ }
+ Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI,
+ rawContactIdToEdit);
+ startActivityForResult(new Intent(Intent.ACTION_EDIT, rawContactUri),
+ REQUEST_EDIT_CONTACT);
+ break;
+ }
case MENU_ITEM_DELETE: {
// Get confirmation
showDialog(DIALOG_CONFIRM_DELETE);
@@ -529,14 +544,29 @@
public void showJoinAggregateActivity() {
Intent intent = new Intent(ContactsListActivity.JOIN_AGGREGATE);
intent.putExtra(ContactsListActivity.EXTRA_AGGREGATE_ID, ContentUris.parseId(mUri));
- startActivityForResult(intent, REQUEST_JOIN_AGGREGATE);
+ startActivityForResult(intent, REQUEST_JOIN_CONTACT);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
- if (requestCode == REQUEST_JOIN_AGGREGATE && resultCode == RESULT_OK && intent != null) {
- final long aggregateId = ContentUris.parseId(intent.getData());
- joinAggregate(aggregateId);
+ switch (requestCode) {
+ case REQUEST_JOIN_CONTACT: {
+ if (resultCode == RESULT_OK && intent != null) {
+ final long aggregateId = ContentUris.parseId(intent.getData());
+ joinAggregate(aggregateId);
+ }
+ break;
+ }
+ case REQUEST_EDIT_CONTACT: {
+ if (resultCode == RESULT_OK && intent != null) {
+ long newInitialSelectedRawContactId = intent.getLongExtra(
+ RAW_CONTACT_ID_EXTRA, ALL_CONTACTS_ID);
+ if (newInitialSelectedRawContactId != mSelectedRawContactId) {
+ mSelectedRawContactId = newInitialSelectedRawContactId;
+ selectInitialTab();
+ }
+ }
+ }
}
}
@@ -700,7 +730,8 @@
}
// This performs the tab filtering
- if (mRawContactId != entry.contactId && mRawContactId != ALL_CONTACTS_ID) {
+ if (mSelectedRawContactId != entry.contactId
+ && mSelectedRawContactId != ALL_CONTACTS_ID) {
continue;
}
diff --git a/src/com/android/contacts/ui/EditContactActivity.java b/src/com/android/contacts/ui/EditContactActivity.java
index b87b0c9..a5b1a47 100644
--- a/src/com/android/contacts/ui/EditContactActivity.java
+++ b/src/com/android/contacts/ui/EditContactActivity.java
@@ -20,6 +20,7 @@
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
import com.android.contacts.ScrollingTabWidget;
+import com.android.contacts.ViewContactActivity;
import com.android.contacts.model.ContactsSource;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.HardCodedSources;
@@ -97,6 +98,11 @@
private static final String KEY_EDIT_STATE = "state";
private static final String KEY_EDITOR_STATE = "editor";
private static final String KEY_SELECTED_TAB = "tab";
+ private static final String KEY_SELECTED_TAB_ID = "tabId";
+ private static final String KEY_CONTACT_ID = "contactId";
+
+ private long mSelectedRawContactId = -1;
+ private long mContactId = -1;
private ScrollingTabWidget mTabWidget;
private ContactHeaderWidget mHeader;
@@ -213,11 +219,14 @@
final Uri data = intent.getData();
final String authority = data.getAuthority();
if (ContactsContract.AUTHORITY.equals(authority)) {
- final long contactId = ContentUris.parseId(data);
- selection = RawContacts.CONTACT_ID + "=" + contactId;
-
+ final long rawContactId = ContentUris.parseId(data);
+ target.mSelectedRawContactId = rawContactId;
+ target.mContactId = ContactsUtils.queryForContactId(target.getContentResolver(),
+ rawContactId);
+ selection = RawContacts.CONTACT_ID + "=" + target.mContactId;
} else if (Contacts.AUTHORITY.equals(authority)) {
final long rawContactId = ContentUris.parseId(data);
+ target.mSelectedRawContactId = rawContactId;
selection = RawContacts._ID + "=" + rawContactId;
}
@@ -277,6 +286,8 @@
outState.putParcelable(KEY_EDIT_STATE, mState);
// outState.putSparseParcelableArray(KEY_EDITOR_STATE, buildEditorState());
// outState.putInt(KEY_SELECTED_TAB, mTabWidget.getCurrentTab());
+ outState.putLong(KEY_SELECTED_TAB_ID, mSelectedRawContactId);
+ outState.putLong(KEY_CONTACT_ID, mContactId);
super.onSaveInstanceState(outState);
}
@@ -285,6 +296,8 @@
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// Read modifications from instance
mState = savedInstanceState.<EditState> getParcelable(KEY_EDIT_STATE);
+ mSelectedRawContactId = savedInstanceState.getLong(KEY_SELECTED_TAB_ID);
+ mContactId = savedInstanceState.getLong(KEY_CONTACT_ID);
Log.d(TAG, "onrestoreinstancestate");
@@ -306,19 +319,26 @@
*/
protected void bindTabs() {
final Sources sources = Sources.getInstance(this);
+ int selectedTab = 0;
mTabWidget.removeAllTabs();
for (EntityDelta entity : mState) {
- final String accountType = entity.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
+ ValuesDelta values = entity.getValues();
+ final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
+ final Long rawContactId = values.getAsLong(RawContacts._ID);
final ContactsSource source = sources.getInflatedSource(accountType,
ContactsSource.LEVEL_CONSTRAINTS);
+ if (rawContactId != null && rawContactId == mSelectedRawContactId) {
+ selectedTab = mTabWidget.getTabCount();
+ }
+
final View tabView = BaseContactCardActivity.createTabIndicatorView(mTabWidget, source);
mTabWidget.addTab(tabView);
}
if (mState.size() > 0) {
- mTabWidget.setCurrentTab(0);
- this.onTabSelectionChanged(0, false);
+ mTabWidget.setCurrentTab(selectedTab);
+ this.onTabSelectionChanged(selectedTab, false);
}
}
@@ -333,12 +353,8 @@
// TODO: fill header bar with newly parsed data for speed
// TODO: handle legacy case correctly instead of assuming _id
- final Uri uri = this.getIntent().getData();
-
- try {
- final long contactId = ContentUris.parseId(uri);
- mHeader.bindFromContactId(contactId);
- } catch (NumberFormatException e) {
+ if (mContactId > 0) {
+ mHeader.bindFromContactId(mContactId);
}
// mHeader.setDisplayName(displayName, phoneticName);
@@ -355,6 +371,10 @@
// Find entity and source for selected tab
final EntityDelta entity = mState.get(tabIndex);
final String accountType = entity.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
+ Long rawContactId = entity.getValues().getAsLong(RawContacts._ID);
+ if (rawContactId != null) {
+ mSelectedRawContactId = rawContactId;
+ }
final Sources sources = Sources.getInstance(this);
final ContactsSource source = sources.getInflatedSource(accountType,
@@ -561,6 +581,8 @@
// Persisting finished, or we timed out waiting on it. Either way,
// finish this activity, the background task will keep running.
+ setResult(RESULT_OK, new Intent().putExtra(ViewContactActivity.RAW_CONTACT_ID_EXTRA,
+ mSelectedRawContactId));
this.finish();
return true;
}