Merge "SelectAccountDialogFragment: Handle orientation changes"
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 767d366..aaeacab 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -36,6 +36,7 @@
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityDeltaList;
import com.android.contacts.model.EntityModifier;
+import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
import com.android.contacts.util.Constants;
import com.android.contacts.util.DataStatus;
import com.android.contacts.util.DateUtils;
@@ -1754,7 +1755,7 @@
}
@Override
- public void onAccountChosen(int requestCode, AccountWithDataSet account) {
+ public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
createCopy(account);
}
@@ -2049,9 +2050,9 @@
return; // Don't show a dialog.
}
- final SelectAccountDialogFragment dialog = new SelectAccountDialogFragment();
- dialog.setTargetFragment(ContactDetailFragment.this, 0);
- dialog.show(getFragmentManager(), SelectAccountDialogFragment.TAG);
+ SelectAccountDialogFragment.show(getFragmentManager(),
+ ContactDetailFragment.this, R.string.dialog_new_contact_account,
+ AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, null);
break;
}
}
diff --git a/src/com/android/contacts/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
index 3a8681a..42ac170 100644
--- a/src/com/android/contacts/editor/SelectAccountDialogFragment.java
+++ b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
@@ -16,7 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.AccountsListAdapter;
import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
@@ -25,39 +24,58 @@
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
+import android.app.FragmentManager;
import android.content.DialogInterface;
import android.os.Bundle;
/**
* Shows a dialog asking the user which account to chose.
- * The result is passed back to the Fragment that is configured by
- * {@link Fragment#setTargetFragment(Fragment, int)}, which has to implement
- * {@link SelectAccountDialogFragment.Listener}.
- * Does not perform any action by itself.
+ *
+ * The result is passed to {@code targetFragment} passed to {@link #show}.
*/
-public class SelectAccountDialogFragment extends DialogFragment {
+public final class SelectAccountDialogFragment extends DialogFragment {
public static final String TAG = "SelectAccountDialogFragment";
- // TODO: This dialog is used in the context of group editing by default, but should be generic
- // to work for contact editing as well. Save/restore the resource ID and account list filter
- // that are passed in as parameters on device rotation. Bug: 5369853
- private int mTitleResourceId = R.string.dialog_new_group_account;
- private AccountListFilter mAccountListFilter = AccountListFilter.ACCOUNTS_GROUP_WRITABLE;
+ private static final String KEY_TITLE_RES_ID = "title_res_id";
+ private static final String KEY_LIST_FILTER = "list_filter";
+ private static final String KEY_EXTRA_ARGS = "extra_args";
- public SelectAccountDialogFragment() {
+ public SelectAccountDialogFragment() { // All fragments must have a public default constructor.
}
- public SelectAccountDialogFragment(int titleResourceId, AccountListFilter accountListFilter) {
- mTitleResourceId = titleResourceId;
- mAccountListFilter = accountListFilter;
+ /**
+ * Show the dialog.
+ *
+ * @param fragmentManager {@link FragmentManager}.
+ * @param targetFragment {@link Fragment} that implements {@link Listener}.
+ * @param titleResourceId resource ID to use as the title.
+ * @param accountListFilter account filter.
+ * @param extraArgs Extra arguments, which will later be passed to
+ * {@link Listener#onAccountChosen}. {@code null} will be converted to
+ * {@link Bundle#EMPTY}.
+ */
+ public static <F extends Fragment & Listener> void show(FragmentManager fragmentManager,
+ F targetFragment, int titleResourceId,
+ AccountListFilter accountListFilter, Bundle extraArgs) {
+ final Bundle args = new Bundle();
+ args.putInt(KEY_TITLE_RES_ID, titleResourceId);
+ args.putSerializable(KEY_LIST_FILTER, accountListFilter);
+ args.putBundle(KEY_EXTRA_ARGS, (extraArgs == null) ? Bundle.EMPTY : extraArgs);
+
+ final SelectAccountDialogFragment instance = new SelectAccountDialogFragment();
+ instance.setArguments(args);
+ instance.setTargetFragment(targetFragment, 0);
+ instance.show(fragmentManager, null);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ final Bundle args = getArguments();
+ final AccountListFilter filter = (AccountListFilter) args.getSerializable(KEY_LIST_FILTER);
final AccountsListAdapter accountAdapter = new AccountsListAdapter(builder.getContext(),
- mAccountListFilter);
+ filter);
final DialogInterface.OnClickListener clickListener =
new DialogInterface.OnClickListener() {
@@ -69,7 +87,7 @@
}
};
- builder.setTitle(mTitleResourceId);
+ builder.setTitle(args.getInt(KEY_TITLE_RES_ID));
builder.setSingleChoiceItems(accountAdapter, 0, clickListener);
final AlertDialog result = builder.create();
return result;
@@ -86,19 +104,18 @@
}
/**
- * Calls {@link Listener#onAccountChosen(int, AccountWithDataSet)} if the target fragment is
- * castable to {@link Listener}. Subclasses can also overide to directly perform an operation.
+ * Calls {@link Listener#onAccountChosen} of {@code targetFragment}.
*/
- protected void onAccountSelected(AccountWithDataSet account) {
+ private void onAccountSelected(AccountWithDataSet account) {
final Fragment targetFragment = getTargetFragment();
if (targetFragment != null && targetFragment instanceof Listener) {
final Listener target = (Listener) targetFragment;
- target.onAccountChosen(getTargetRequestCode(), account);
+ target.onAccountChosen(account, getArguments().getBundle(KEY_EXTRA_ARGS));
}
}
public interface Listener {
- void onAccountChosen(int requestCode, AccountWithDataSet account);
+ void onAccountChosen(AccountWithDataSet account, Bundle extraArgs);
void onAccountSelectorCancelled();
}
}
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index 1d1237e..bb56b6e 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -332,14 +332,13 @@
}
mStatus = Status.SELECTING_ACCOUNT;
- final SelectAccountDialogFragment dialog = new SelectAccountDialogFragment(
- R.string.dialog_new_group_account, AccountListFilter.ACCOUNTS_GROUP_WRITABLE);
- dialog.setTargetFragment(this, 0);
- dialog.show(getFragmentManager(), SelectAccountDialogFragment.TAG);
+ SelectAccountDialogFragment.show(getFragmentManager(), this,
+ R.string.dialog_new_group_account, AccountListFilter.ACCOUNTS_GROUP_WRITABLE,
+ null);
}
@Override
- public void onAccountChosen(int requestCode, AccountWithDataSet account) {
+ public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
mAccountName = account.name;
mAccountType = account.type;
mDataSet = account.dataSet;
diff --git a/src/com/android/contacts/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
index e0b617c..2eedfb3 100644
--- a/src/com/android/contacts/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
@@ -21,6 +21,7 @@
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.AccountSelectionUtil;
+import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
import com.android.contacts.vcard.ExportVCardActivity;
import android.app.AlertDialog;
@@ -49,9 +50,12 @@
/**
* An dialog invoked to import/export contacts.
*/
-public class ImportExportDialogFragment extends DialogFragment {
+public class ImportExportDialogFragment extends DialogFragment
+ implements SelectAccountDialogFragment.Listener {
public static final String TAG = "ImportExportDialogFragment";
+ private static final String KEY_RES_ID = "resourceId";
+
private final String[] LOOKUP_PROJECTION = new String[] {
Contacts.LOOKUP_KEY
};
@@ -100,29 +104,34 @@
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
-
+ boolean dismissDialog;
final int resId = adapter.getItem(which);
switch (resId) {
case R.string.import_from_sim:
case R.string.import_from_sdcard: {
- handleImportRequest(resId);
+ dismissDialog = handleImportRequest(resId);
break;
}
case R.string.export_to_sdcard: {
+ dismissDialog = true;
Intent exportIntent = new Intent(getActivity(), ExportVCardActivity.class);
getActivity().startActivity(exportIntent);
break;
}
case R.string.share_visible_contacts: {
+ dismissDialog = true;
doShareVisibleContacts();
break;
}
default: {
+ dismissDialog = true;
Log.e(TAG, "Unexpected resource: "
+ getActivity().getResources().getResourceEntryName(resId));
}
}
+ if (dismissDialog) {
+ dialog.dismiss();
+ }
}
};
return new AlertDialog.Builder(getActivity())
@@ -164,7 +173,12 @@
}
}
- private void handleImportRequest(int resId) {
+ /**
+ * Handle "import from SIM" and "import from SD".
+ *
+ * @return {@code true} if the dialog show be closed. {@code false} otherwise.
+ */
+ private boolean handleImportRequest(int resId) {
// There are three possibilities:
// - more than one accounts -> ask the user
// - just one account -> use the account without asking the user
@@ -174,32 +188,39 @@
final int size = accountList.size();
if (size > 1) {
// Send over to the account selector
- ImportExportAccountSelectorDialog.show(getFragmentManager(), resId);
- return;
+ final Bundle args = new Bundle();
+ args.putInt(KEY_RES_ID, resId);
+ SelectAccountDialogFragment.show(
+ getFragmentManager(), this,
+ R.string.dialog_new_contact_account,
+ AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, args);
+
+ // In this case, because this DialogFragment is used as a target fragment to
+ // SelectAccountDialogFragment, we can't close it yet. We close the dialog when
+ // we get a callback from it.
+ return false;
}
AccountSelectionUtil.doImport(getActivity(), resId,
(size == 1 ? accountList.get(0) : null));
+ return true; // Close the dialog.
}
- /** Sub-Dialog for showing an account selector in case there are several accounts */
- public static class ImportExportAccountSelectorDialog extends SelectAccountDialogFragment {
- private static final String SELECTOR_TAG = "ImportExportAccountSelectorDialog";
- private static final String BUNDLE_RES_ID = "resourceId";
+ /**
+ * Called when an account is selected on {@link SelectAccountDialogFragment}.
+ */
+ @Override
+ public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
+ AccountSelectionUtil.doImport(getActivity(), extraArgs.getInt(KEY_RES_ID), account);
- public static void show(FragmentManager manager, int resId) {
- final ImportExportAccountSelectorDialog dialog =
- new ImportExportAccountSelectorDialog();
- final Bundle bundle = new Bundle();
- bundle.putInt(BUNDLE_RES_ID, resId);
- dialog.setArguments(bundle);
- dialog.show(manager, SELECTOR_TAG);
- }
+ // At this point the dialog is still showing (which is why we can use getActivity() above)
+ // So close it.
+ dismiss();
+ }
- @Override
- protected void onAccountSelected(AccountWithDataSet account) {
- final int resourceId = getArguments().getInt(BUNDLE_RES_ID);
- AccountSelectionUtil.doImport(getActivity(), resourceId, account);
- }
+ @Override
+ public void onAccountSelectorCancelled() {
+ // See onAccountChosen() -- at this point the dialog is still showing. Close it.
+ dismiss();
}
}