Split Import and Export Dialogs
Bug: 28942286
Test: manually entering the settings with 0 and non-zero numbers of
contacts checking that export option appears only with non-zero contacts
Change-Id: I4a5b2714081fab1f6ed387a821e3df59d4b36eee
diff --git a/src/com/android/contacts/common/interactions/ImportDialogFragment.java b/src/com/android/contacts/common/interactions/ImportDialogFragment.java
new file mode 100644
index 0000000..0c0ce73
--- /dev/null
+++ b/src/com/android/contacts/common/interactions/ImportDialogFragment.java
@@ -0,0 +1,258 @@
+/*
+ * 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.common.interactions;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.android.contacts.common.R;
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.util.AccountSelectionUtil;
+import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.common.vcard.VCardCommonArguments;
+import com.android.contacts.editor.SelectAccountDialogFragment;
+
+import java.util.List;
+
+/**
+ * An dialog invoked to import/export contacts.
+ */
+public class ImportDialogFragment extends DialogFragment
+ implements SelectAccountDialogFragment.Listener {
+ public static final String TAG = "ImportDialogFragment";
+
+ private static final String KEY_RES_ID = "resourceId";
+ private static final String KEY_SUBSCRIPTION_ID = "subscriptionId";
+
+
+ private final String[] LOOKUP_PROJECTION = new String[] {
+ Contacts.LOOKUP_KEY
+ };
+
+ private SubscriptionManager mSubscriptionManager;
+
+ /** Preferred way to show this dialog */
+ public static void show(FragmentManager fragmentManager, Class callingActivity) {
+ final ImportDialogFragment fragment = new ImportDialogFragment();
+ Bundle args = new Bundle();
+ args.putString(VCardCommonArguments.ARG_CALLING_ACTIVITY, callingActivity.getName());
+ fragment.setArguments(args);
+ fragment.show(fragmentManager, TAG);
+ }
+
+ @Override
+ public Context getContext() {
+ return getActivity();
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Wrap our context to inflate list items using the correct theme
+ final Resources res = getActivity().getResources();
+ final LayoutInflater dialogInflater = (LayoutInflater)getActivity()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ final String callingActivity = getArguments().getString(
+ VCardCommonArguments.ARG_CALLING_ACTIVITY);
+
+ // Adapter that shows a list of string resources
+ final ArrayAdapter<AdapterEntry> adapter = new ArrayAdapter<AdapterEntry>(getActivity(),
+ R.layout.select_dialog_item) {
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final TextView result = (TextView)(convertView != null ? convertView :
+ dialogInflater.inflate(R.layout.select_dialog_item, parent, false));
+
+ result.setText(getItem(position).mLabel);
+ return result;
+ }
+ };
+
+ final TelephonyManager manager =
+ (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
+ if (res.getBoolean(R.bool.config_allow_import_from_vcf_file)) {
+ adapter.add(new AdapterEntry(getString(R.string.import_from_vcf_file),
+ R.string.import_from_vcf_file));
+ }
+
+ if (CompatUtils.isMSIMCompatible()) {
+ mSubscriptionManager = SubscriptionManager.from(getActivity());
+ if (manager != null && res.getBoolean(R.bool.config_allow_sim_import)) {
+ List<SubscriptionInfo> subInfoRecords = null;
+ try {
+ subInfoRecords = mSubscriptionManager.getActiveSubscriptionInfoList();
+ } catch (SecurityException e) {
+ Log.w(TAG, "SecurityException thrown, lack permission for"
+ + " getActiveSubscriptionInfoList", e);
+ }
+ if (subInfoRecords != null) {
+ if (subInfoRecords.size() == 1) {
+ adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
+ R.string.import_from_sim, subInfoRecords.get(0).getSubscriptionId()));
+ } else {
+ for (SubscriptionInfo record : subInfoRecords) {
+ adapter.add(new AdapterEntry(getSubDescription(record),
+ R.string.import_from_sim, record.getSubscriptionId()));
+ }
+ }
+ }
+ }
+ } else {
+ if (manager != null && manager.hasIccCard()
+ && res.getBoolean(R.bool.config_allow_sim_import)) {
+ adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
+ R.string.import_from_sim, -1));
+ }
+ }
+
+
+ final DialogInterface.OnClickListener clickListener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ boolean dismissDialog;
+ final int resId = adapter.getItem(which).mChoiceResourceId;
+ if (resId == R.string.import_from_sim || resId == R.string.import_from_vcf_file) {
+ dismissDialog = handleImportRequest(resId,
+ adapter.getItem(which).mSubscriptionId);
+ } else {
+ dismissDialog = true;
+ Log.e(TAG, "Unexpected resource: "
+ + getActivity().getResources().getResourceEntryName(resId));
+ }
+ if (dismissDialog) {
+ dialog.dismiss();
+ }
+ }
+ };
+ final TextView title = (TextView) View.inflate(getActivity(), R.layout.dialog_title, null);
+ title.setText(R.string.dialog_import);
+ return new AlertDialog.Builder(getActivity())
+ .setCustomTitle(title)
+ .setSingleChoiceItems(adapter, -1, clickListener)
+ .create();
+ }
+
+ /**
+ * 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, int subscriptionId) {
+ // There are three possibilities:
+ // - more than one accounts -> ask the user
+ // - just one account -> use the account without asking the user
+ // - no account -> use phone-local storage without asking the user
+ final AccountTypeManager accountTypes = AccountTypeManager.getInstance(getActivity());
+ final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
+ final int size = accountList.size();
+ if (size > 1) {
+ // Send over to the account selector
+ final Bundle args = new Bundle();
+ args.putInt(KEY_RES_ID, resId);
+ args.putInt(KEY_SUBSCRIPTION_ID, subscriptionId);
+ 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),
+ (CompatUtils.isMSIMCompatible() ? subscriptionId : -1));
+ return true; // Close the dialog.
+ }
+
+ /**
+ * 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, extraArgs.getInt(KEY_SUBSCRIPTION_ID));
+
+ // At this point the dialog is still showing (which is why we can use getActivity() above)
+ // So close it.
+ dismiss();
+ }
+
+ @Override
+ public void onAccountSelectorCancelled() {
+ // See onAccountChosen() -- at this point the dialog is still showing. Close it.
+ dismiss();
+ }
+
+ private CharSequence getSubDescription(SubscriptionInfo record) {
+ CharSequence name = record.getDisplayName();
+ if (TextUtils.isEmpty(record.getNumber())) {
+ // Don't include the phone number in the description, since we don't know the number.
+ return getString(R.string.import_from_sim_summary_no_number, name);
+ }
+ return TextUtils.expandTemplate(
+ getString(R.string.import_from_sim_summary),
+ name,
+ PhoneNumberUtilsCompat.createTtsSpannable(record.getNumber()));
+ }
+
+ private static class AdapterEntry {
+ public final CharSequence mLabel;
+ public final int mChoiceResourceId;
+ public final int mSubscriptionId;
+
+ public AdapterEntry(CharSequence label, int resId, int subId) {
+ mLabel = label;
+ mChoiceResourceId = resId;
+ mSubscriptionId = subId;
+ }
+
+ public AdapterEntry(String label, int resId) {
+ // Store a nonsense value for mSubscriptionId. If this constructor is used,
+ // the mSubscriptionId value should not be read later.
+ this(label, resId, /* subId = */ -1);
+ }
+ }
+}