summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk2
-rw-r--r--res/values-zh-rCN/strings.xml4
-rw-r--r--res/values-zh-rTW/strings.xml20
-rw-r--r--res/values/strings.xml4
-rw-r--r--src/com/android/contacts/common/MoreContactUtils.java406
-rw-r--r--src/com/android/contacts/common/editor/SelectAccountDialogFragment.java2
-rw-r--r--src/com/android/contacts/common/interactions/ImportExportDialogFragment.java718
-rw-r--r--src/com/android/contacts/common/util/AccountSelectionUtil.java40
-rw-r--r--src/com/android/contacts/common/vcard/SelectAccountActivity.java5
9 files changed, 1087 insertions, 114 deletions
diff --git a/Android.mk b/Android.mk
index 52e18732..a628a62a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,7 +23,7 @@ res_dirs := res $(phone_common_dir)/res
LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
-
+LOCAL_JAVA_LIBRARIES := telephony-common
LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages com.android.phone.common
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index b67f9309..bc9d5383 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!--
+<!--
~ Copyright (C) 2012 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
@@ -161,6 +161,7 @@
<string name="listCustomView" msgid="1915154113477432033">"自定义视图中的联系人"</string>
<string name="listSingleContact" msgid="8525131203887307088">"单个联系人"</string>
<string name="dialog_new_contact_account" msgid="4107520273478326011">"在以下帐户中创建联系人:"</string>
+ <string name="export_to_sim">"导出到 SIM 卡"</string>
<string name="import_from_sim" msgid="4749894687871835873">"从 SIM 卡导入"</string>
<string name="import_from_sim_summary" msgid="2306434118233541675">"从 SIM 卡“<xliff:g id="SIM_NAME">^1</xliff:g>” - <xliff:g id="SIM_NUMBER">^2</xliff:g> 导入"</string>
<string name="import_from_sim_summary_no_number" msgid="8498561004799710237">"从 SIM 卡“<xliff:g id="SIM_NAME">%1$s</xliff:g>”导入"</string>
@@ -179,6 +180,7 @@
<string name="fail_reason_too_many_vcard" product="nosdcard" msgid="8720294715223591581">"存储设备中的 vCard 文件过多。"</string>
<string name="fail_reason_too_many_vcard" product="default" msgid="3793454448838716962">"SD卡上的 vCard 文件过多。"</string>
<string name="fail_reason_io_error" msgid="7736686553669161933">"I/O 错误"</string>
+ <string name="fail_reason_import_vcard">I/O 错误,无法导入 vCard <xliff:g id="name">%s</xliff:g></string>
<string name="fail_reason_low_memory_during_import" msgid="3277485820827338116">"内存不足。该文件可能过大。"</string>
<string name="fail_reason_vcard_parse_error" msgid="514012644716565082">"由于意外原因而无法解析 vCard。"</string>
<string name="fail_reason_not_supported" msgid="388664373573337601">"不支持此格式。"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 3dc3cfd1..3e5ef1ab 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -161,6 +161,7 @@
<string name="listCustomView" msgid="1915154113477432033">"聯絡人自訂檢視"</string>
<string name="listSingleContact" msgid="8525131203887307088">"單一聯絡人"</string>
<string name="dialog_new_contact_account" msgid="4107520273478326011">"在帳戶下建立聯絡人"</string>
+ <string name="export_to_sim">"導出到 SIM 卡"</string>
<string name="import_from_sim" msgid="4749894687871835873">"從 SIM 卡匯入"</string>
<string name="import_from_sim_summary" msgid="2306434118233541675">"從 SIM 卡 <xliff:g id="SIM_NAME">^1</xliff:g> - <xliff:g id="SIM_NUMBER">^2</xliff:g> 匯入"</string>
<string name="import_from_sim_summary_no_number" msgid="8498561004799710237">"從 SIM 卡 <xliff:g id="SIM_NAME">%1$s</xliff:g> 匯入"</string>
@@ -178,6 +179,7 @@
<string name="fail_reason_too_many_vcard" product="nosdcard" msgid="8720294715223591581">"儲存裝置中的 vCard 檔案過多。"</string>
<string name="fail_reason_too_many_vcard" product="default" msgid="3793454448838716962">"SD 卡上的 vCard 檔案過多。"</string>
<string name="fail_reason_io_error" msgid="7736686553669161933">"I/O 錯誤"</string>
+ <string name="fail_reason_import_vcard">I/O 錯誤,無法匯入vCard <xliff:g id="name">%s</xliff:g></string>
<string name="fail_reason_low_memory_during_import" msgid="3277485820827338116">"記憶體不足,檔案可能過大。"</string>
<string name="fail_reason_vcard_parse_error" msgid="514012644716565082">"由於意外因素,導致無法剖析 vCard。"</string>
<string name="fail_reason_not_supported" msgid="388664373573337601">"不支援此格式。"</string>
@@ -247,6 +249,24 @@
<string name="action_menu_back_from_search" msgid="1138551123844019647">"停止搜尋"</string>
<string name="description_clear_search" msgid="3893511425518852086">"清除搜尋"</string>
<string name="settings_contact_display_options_title" msgid="1020420603072835628">"聯絡人顯示選項"</string>
+ <string name="settings_contact_display_options_description" msgid="4130259058302284077">"設定聯絡人的顯示和排序方式。"</string>
+ <string name="exporting">"正在導出"</string>
+ <string name="reading_vcard_files">讀取Vcard文件</string>
+ <string name="export_to_sim_failed">"導出失敗,<xliff:g id="insertCount">%d</xliff:g>條成功導出"</string>
+ <string name="export_sim_card_full">"SIM卡已滿,<xliff:g id="insertCount">%d</xliff:g>條成功導出"</string>
+ <string name="export_finished">"導出結束"</string>
+ <string name="export_no_phone_or_email">導出失敗, <xliff:g id="name">%s</xliff:g>沒有電話號碼或者郵箱地址</string>
+ <string name="tag_too_long">"發生錯誤,聯絡人姓名過長。"</string>
+ <string name="import_from_sim_select">"選擇SIM卡進行導入"</string>
+ <string name="no_sdcard_title" product="nosdcard">"無存儲設備"</string>
+ <string name="no_sdcard_title" product="default">"無 SD 卡"</string>
+ <string name="deleteConfirmation_title">"要刪除聯絡人嗎?"</string>
+ <string name="ContactMultiDeleteConfirmation">"將會刪除這些聯絡人。"</string>
+ <string name="slot_name">"卡"</string>
+
+ <string name="copy_done">複制成功!</string>
+ <string name="copy_failure">複制失敗!</string>
+ <string name="card_no_space">卡記錄已滿,部分信息未複制</string>
<string name="select_account_dialog_title" msgid="5509088895267310568">"帳戶"</string>
<string name="set_default_account" msgid="3865970860434642695">"一律使用這張 SIM 卡通話"</string>
<string name="select_phone_account_for_calls" msgid="933905607702811164">"選擇通話帳戶"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f5973e0b..d471f4e9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -764,6 +764,10 @@ a ren't members of any other group. [CHAR LIMIT=25] -->
<string name="export_sim_card_full">Sim Card is full, <xliff:g id="insertCount">%d</xliff:g> items are exported</string>
+ <string name="export_failed">Export failed</string>
+
+ <string name="sim_card_full">Error, Sim Card is full.</string>
+
<string name="export_finished">Export finished</string>
<string name="tag_too_long">Error, Contact name is too long.</string>
diff --git a/src/com/android/contacts/common/MoreContactUtils.java b/src/com/android/contacts/common/MoreContactUtils.java
index c6dd3329..520efd8a 100644
--- a/src/com/android/contacts/common/MoreContactUtils.java
+++ b/src/com/android/contacts/common/MoreContactUtils.java
@@ -22,21 +22,44 @@ import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import android.content.Context;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.ComponentName;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
+import android.util.Log;
import android.view.View;
import android.widget.TextView;
-import com.android.contacts.common.model.account.AccountType;
import com.android.internal.telephony.PhoneConstants;
+import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.SimAccountType;
+import com.android.internal.telephony.uicc.AdnRecord;
+import com.android.internal.telephony.uicc.IccConstants;
+import com.android.internal.telephony.IIccPhoneBook;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* Shared static contact utility methods.
@@ -44,6 +67,19 @@ import com.android.internal.telephony.PhoneConstants;
public class MoreContactUtils {
private static final String WAIT_SYMBOL_AS_STRING = String.valueOf(PhoneNumberUtils.WAIT);
+ private static final boolean DBG = true;
+ private static final String TAG = "MoreContactUtils";
+ public static final int MAX_LENGTH_NAME_IN_SIM = 14;
+ public static final int MAX_LENGTH_NAME_WITH_CHINESE_IN_SIM = 6;
+ public static final int MAX_LENGTH_NUMBER_IN_SIM = 20;
+ public static final int MAX_LENGTH_EMAIL_IN_SIM = 40;
+ private static final int NAME_POS = 0;
+ private static final int NUMBER_POS = 1;
+ private static final int EMAIL_POS = 2;
+ private static final int ANR_POS = 3;
+ private static final String PHONEBOOK = "simphonebook";
+ public static final String[] MULTI_SIM_NAME = { "perferred_name_sub1",
+ "perferred_name_sub2" };
/**
* Returns true if two data with mimetypes which represent values in contact entries are
@@ -254,9 +290,6 @@ public class MoreContactUtils {
StringBuilder simFilter = new StringBuilder("");
for (int i = 0; i < count; i++) {
- if (!TelephonyManager.getDefault().hasIccCard(i)) {
- continue;
- }
if (TelephonyManager.SIM_STATE_UNKNOWN == TelephonyManager
.getDefault().getSimState(i)) {
simFilter.append(getSimAccountName(i) + ',');
@@ -303,42 +336,385 @@ public class MoreContactUtils {
return subscription;
}
+ public static int getAnrCount(int slot) {
+ int anrCount = 0;
+ /*int[] subId = SubscriptionManager.getSubId(slot);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
+ ServiceManager.getService("simphonebook"));
+
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ anrCount = iccIpb.getAnrCountUsingSubId(subId[0]);
+ } else {
+ anrCount = iccIpb.getAnrCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }*/
+
+ return anrCount;
+ }
+
+ public static int getAdnCount(int slot) {
+ int adnCount = 250;
+ /*int[] subId = SubscriptionManager.getSubId(slot);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
+ ServiceManager.getService("simphonebook"));
+
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ adnCount = iccIpb.getAdnCountUsingSubId(subId[0]);
+ } else {
+ adnCount = iccIpb.getAdnCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }*/
+
+ return adnCount;
+ }
+
+ public static int getEmailCount(int slot) {
+ int emailCount = 0;
+ /*int[] subId = SubscriptionManager.getSubId(slot);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
+ ServiceManager.getService("simphonebook"));
+
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ emailCount = iccIpb.getEmailCountUsingSubId(subId[0]);
+ } else {
+ emailCount = iccIpb.getEmailCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }*/
+
+ return emailCount;
+ }
+
/**
* Returns the subscription's card can save anr or not.
*/
- public static boolean canSaveAnr(int subscription) {
- return false;
- //return getAnrCount(subscription) > 0 ? true : false;
+ public static boolean canSaveAnr(int slot) {
+ return getAnrCount(slot) > 0 ? true : false;
}
/**
* Returns the subscription's card can save email or not.
*/
public static boolean canSaveEmail(int subscription) {
- return false;
- //return getEmailCount(subscription) > 0 ? true : false;
+ return getEmailCount(subscription) > 0 ? true : false;
}
public static int getOneSimAnrCount(int sub) {
int count = 0;
- /*int anrCount = getAnrCount(sub);
+ int anrCount = getAnrCount(sub);
int adnCount = getAdnCount(sub);
if (adnCount > 0) {
count = anrCount % adnCount != 0 ? (anrCount / adnCount + 1)
: (anrCount / adnCount);
- }*/
+ }
return count;
}
public static int getOneSimEmailCount(int sub) {
int count = 0;
- /*int emailCount = getEmailCount(sub);
+ int emailCount = getEmailCount(sub);
int adnCount = getAdnCount(sub);
if (adnCount > 0) {
- count = emailCount % adnCount != 0 ? (emailCount
- / adnCount + 1)
+ count = emailCount % adnCount != 0 ? (emailCount / adnCount + 1)
: (emailCount / adnCount);
- }*/
+ }
return count;
}
+
+ public static boolean insertToPhone(String[] values, final ContentResolver resolver,int sub) {
+ Account account = getAcount(sub);
+ final String name = values[NAME_POS];
+ final String phoneNumber = values[NUMBER_POS];
+ final String emailAddresses = values[EMAIL_POS];
+ final String anrs = values[ANR_POS];
+
+ final String[] emailAddressArray;
+ final String[] anrArray;
+ boolean success = true;
+ if (!TextUtils.isEmpty(emailAddresses)) {
+ emailAddressArray = emailAddresses.split(",");
+ } else {
+ emailAddressArray = null;
+ }
+ if (!TextUtils.isEmpty(anrs)) {
+ anrArray = anrs.split(SimContactsConstants.ANR_SEP);
+ } else {
+ anrArray = null;
+ }
+ if (DBG) {
+ Log.d(TAG, "insertToPhone: name= " + name + ", phoneNumber= " + phoneNumber
+ + ", emails= " + emailAddresses + ", anrs= " + anrs + ", account= " + account);
+ }
+ final ArrayList<ContentProviderOperation> operationList =
+ new ArrayList<ContentProviderOperation>();
+ ContentProviderOperation.Builder builder = ContentProviderOperation
+ .newInsert(RawContacts.CONTENT_URI);
+ builder.withValue(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
+
+ if (account != null) {
+ builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
+ builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
+ }
+ operationList.add(builder.build());
+
+ // do not allow empty value insert into database.
+ if (!TextUtils.isEmpty(name)) {
+ builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+ builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
+ builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+ builder.withValue(StructuredName.DISPLAY_NAME, name);
+ operationList.add(builder.build());
+ }
+
+ if (!TextUtils.isEmpty(phoneNumber)) {
+ builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+ builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
+ builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+ builder.withValue(Phone.TYPE, Phone.TYPE_MOBILE);
+ builder.withValue(Phone.NUMBER, phoneNumber);
+ builder.withValue(Data.IS_PRIMARY, 1);
+ operationList.add(builder.build());
+ }
+
+ if (anrArray != null) {
+ for (String anr : anrArray) {
+ if (!TextUtils.isEmpty(anr)) {
+ builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+ builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
+ builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+ builder.withValue(Phone.TYPE, Phone.TYPE_HOME);
+ builder.withValue(Phone.NUMBER, anr);
+ operationList.add(builder.build());
+ }
+ }
+ }
+
+ if (emailAddressArray != null) {
+ for (String emailAddress : emailAddressArray) {
+ if (!TextUtils.isEmpty(emailAddress)) {
+ builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+ builder.withValueBackReference(Email.RAW_CONTACT_ID, 0);
+ builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+ builder.withValue(Email.TYPE, Email.TYPE_MOBILE);
+ builder.withValue(Email.ADDRESS, emailAddress);
+ operationList.add(builder.build());
+ }
+ }
+ }
+
+ try {
+ ContentProviderResult[] results =
+ resolver.applyBatch(ContactsContract.AUTHORITY, operationList);
+ for (ContentProviderResult result: results) {
+ if (result.uri == null) {
+ success = false;
+ break;
+ }
+ }
+ return success;
+ } catch (RemoteException e) {
+ Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+ return false;
+ } catch (OperationApplicationException e) {
+ Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+ return false;
+ }
+ }
+
+ public static Uri insertToCard(Context context, String name, String number, String emails,
+ String anrNumber, int subscription) {
+ // add the max count limit of Chinese code or not
+ if (!TextUtils.isEmpty(name)) {
+ final int maxLen = hasChinese(name) ? MAX_LENGTH_NAME_WITH_CHINESE_IN_SIM
+ : MAX_LENGTH_NAME_IN_SIM;
+ if (name.length() > maxLen) {
+ name = name.substring(0, maxLen);
+ }
+ }
+ Uri result;
+ ContentValues mValues = new ContentValues();
+ mValues.clear();
+ mValues.put(SimContactsConstants.STR_TAG, name);
+ if (!TextUtils.isEmpty(number)) {
+ number = PhoneNumberUtils.stripSeparators(number);
+ if (number.length() > MAX_LENGTH_NUMBER_IN_SIM) {
+ number = number.substring(0, MAX_LENGTH_NUMBER_IN_SIM);
+ }
+
+ mValues.put(SimContactsConstants.STR_NUMBER, number);
+ }
+ if (!TextUtils.isEmpty(emails)) {
+ mValues.put(SimContactsConstants.STR_EMAILS, emails);
+ }
+ if (!TextUtils.isEmpty(anrNumber)) {
+ anrNumber = anrNumber.replaceAll("[^0123456789PWN\\,\\;\\*\\#\\+\\:]", "");
+ mValues.put(SimContactsConstants.STR_ANRS, anrNumber);
+ }
+
+ SimContactsOperation mSimContactsOperation = new SimContactsOperation(context);
+ result = mSimContactsOperation.insert(mValues, subscription);
+
+ if (result != null) {
+ // we should import the contact to the sim account at the same time.
+ String[] value = new String[] {
+ name, number, emails, anrNumber
+ };
+ insertToPhone(value, context.getContentResolver(),subscription);
+ } else {
+ Log.e(TAG, "export contact: [" + name + ", " + number + ", " + emails + "] to slot "
+ + subscription + " failed");
+ }
+ return result;
+ }
+
+ public static Account getAcount(int sub) {
+ Account account = null;
+ if (TelephonyManager.getDefault().isMultiSimEnabled()) {
+ if (sub == PhoneConstants.SUB1) {
+ account = new Account(SimContactsConstants.SIM_NAME_1,
+ SimContactsConstants.ACCOUNT_TYPE_SIM);
+ } else if (sub == PhoneConstants.SUB2) {
+ account = new Account(SimContactsConstants.SIM_NAME_2,
+ SimContactsConstants.ACCOUNT_TYPE_SIM);
+ }
+ } else {
+ if (sub == PhoneConstants.SUB1) {
+ account = new Account(SimContactsConstants.SIM_NAME,
+ SimContactsConstants.ACCOUNT_TYPE_SIM);
+ }
+ }
+ if (account == null) {
+ account = new Account(SimContactsConstants.PHONE_NAME,
+ SimContactsConstants.ACCOUNT_TYPE_PHONE);
+ }
+ return account;
+ }
+
+ public static int getEnabledSimCount() {
+ int mPhoneCount = TelephonyManager.getDefault().getPhoneCount();
+ int enabledSimCount = 0;
+ for (int i = 0; i < mPhoneCount; i++) {
+ if (TelephonyManager.SIM_STATE_READY == TelephonyManager
+ .getDefault().getSimState(i)) {
+ enabledSimCount++;
+ }
+ }
+ return enabledSimCount;
+ }
+
+ public static int getSimFreeCount(Context context, int sub) {
+ String accountName = getAcount(sub).name;
+ int count = 0;
+
+ if (context == null) {
+ return 0;
+ }
+
+ Cursor queryCursor = context.getContentResolver().query(
+ RawContacts.CONTENT_URI,
+ new String[] {
+ RawContacts._ID
+ },
+ RawContacts.ACCOUNT_NAME + " = '" + accountName + "' AND " + RawContacts.DELETED
+ + " = 0", null, null);
+ if (queryCursor != null) {
+ try {
+ count = queryCursor.getCount();
+ } finally {
+ queryCursor.close();
+ }
+ }
+ return getAdnCount(sub) - count;
+ }
+
+ public static int getSpareAnrCount(int sub) {
+ int anrCount = 0;
+ /*int[] subId=SubscriptionManager.getSubId(sub);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(ServiceManager
+ .getService(PHONEBOOK));
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ anrCount = iccIpb.getSpareEmailCountUsingSubId(subId[0]);
+ } else {
+ anrCount = iccIpb.getSpareEmailCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ } catch (SecurityException ex) {
+ Log.i(TAG, ex.toString());
+ } catch (Exception ex) {
+ }
+ if (DBG) {
+ Log.d(TAG, "getSpareAnrCount(" + sub + ") = " + anrCount);
+ }*/
+ return anrCount;
+ }
+
+ public static int getSpareEmailCount(int sub) {
+ int emailCount = 0;
+ /*int[] subId=SubscriptionManager.getSubId(sub);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(ServiceManager
+ .getService(PHONEBOOK));
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ emailCount = iccIpb.getSpareEmailCountUsingSubId(subId[0]);
+ } else {
+ emailCount = iccIpb.getSpareEmailCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ } catch (SecurityException ex) {
+ Log.i(TAG, ex.toString());
+ } catch (Exception ex) {
+ }
+ if (DBG) {
+ Log.d(TAG, "getSpareEmailCount(" + sub + ") = " + emailCount);
+ }*/
+ return emailCount;
+ }
+
+ private static boolean hasChinese(String name) {
+ return name != null && name.getBytes().length > name.length();
+ }
+
+ /**
+ * Get SIM card aliases name, which defined in Settings
+ */
+ public static String getMultiSimAliasesName(Context context, int subscription) {
+ if (context == null || subscription < 0) {
+ return null;
+ }
+ String name = "";
+ if (TelephonyManager.getDefault().isMultiSimEnabled()) {
+ name = Settings.System.getString(context.getContentResolver(),
+ MULTI_SIM_NAME[subscription]);
+ }
+ if (TextUtils.isEmpty(name)) {
+ name = getSimAccountName(subscription);
+ }
+ return name;
+ }
}
diff --git a/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java
index c2ebbbfa..26fc7712 100644
--- a/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java
+++ b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java
@@ -65,7 +65,7 @@ public final class SelectAccountDialogFragment extends DialogFragment {
final SelectAccountDialogFragment instance = new SelectAccountDialogFragment();
instance.setArguments(args);
instance.setTargetFragment(targetFragment, 0);
- instance.show(fragmentManager, null);
+ instance.show(fragmentManager, SelectAccountDialogFragment.TAG);
}
@Override
diff --git a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
index 6553627f..67edac02 100644
--- a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
@@ -16,20 +16,41 @@
package com.android.contacts.common.interactions;
+import android.accounts.Account;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
+import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Resources;
+import android.content.OperationApplicationException;
import android.database.Cursor;
+import android.text.TextUtils;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.Settings;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -43,8 +64,13 @@ import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.common.MoreContactUtils;
+import com.android.contacts.common.SimContactsOperation;
+import com.android.contacts.common.SimContactsConstants;
import com.android.contacts.common.R;
import com.android.contacts.common.editor.SelectAccountDialogFragment;
+import com.android.contacts.common.list.AccountFilterActivity;
+import com.android.contacts.common.list.ContactListFilter;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.util.AccountSelectionUtil;
@@ -53,8 +79,11 @@ import com.android.contacts.common.util.ImplicitIntentsUtil;
import com.android.contacts.common.vcard.ExportVCardActivity;
import com.android.contacts.common.vcard.VCardCommonArguments;
import com.android.contacts.commonbind.analytics.AnalyticsUtil;
+import com.android.internal.telephony.PhoneConstants;
import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
/**
* An dialog invoked to import/export contacts.
@@ -67,10 +96,67 @@ public class ImportExportDialogFragment extends DialogFragment
private static final String KEY_SUBSCRIPTION_ID = "subscriptionId";
private static final String ARG_CONTACTS_ARE_AVAILABLE = "CONTACTS_ARE_AVAILABLE";
+ private static final boolean DEBUG = true;
+
+ public static final int SUBACTIVITY_EXPORT_CONTACTS = 100;
+
+ // This values must be consistent with ImportExportDialogFragment.SUBACTIVITY_EXPORT_CONTACTS.
+ // This values is set 101,That is avoid to conflict with other new subactivity.
+ public static final int SUBACTIVITY_SHARE_VISILBLE_CONTACTS = 101;
+ public static final int MAX_COUNT_ALLOW_SHARE_CONTACT = 2000;
+
private final String[] LOOKUP_PROJECTION = new String[] {
Contacts.LOOKUP_KEY
};
+ static final int PHONE_ID_COLUMN_INDEX = 0;
+ static final int PHONE_TYPE_COLUMN_INDEX = 1;
+ static final int PHONE_LABEL_COLUMN_INDEX = 2;
+ static final int PHONE_NUMBER_COLUMN_INDEX = 3;
+ static final int PHONE_DISPLAY_NAME_COLUMN_INDEX = 4;
+ static final int PHONE_CONTACT_ID_COLUMN_INDEX = 5;
+ // This value needs to start at 7. See {@link PeopleActivity}.
+ public static final int SUBACTIVITY_MULTI_PICK_CONTACT = 7;
+ //TODO: we need to refactor the export code in future release.
+ // QRD enhancement: export subscription selected by user
+ public static int mExportSub;
+ //this flag is the same as defined in MultiPickContactActivit
+ private static final String EXT_NOT_SHOW_SIM_FLAG = "not_sim_show";
+ // QRD enhancement: Toast handler for exporting concat to sim card
+ private static final int TOAST_EXPORT_FAILED = 0;
+ private static final int TOAST_EXPORT_FINISHED = 1;
+ // only for sim card is full
+ private static final int TOAST_SIM_CARD_FULL = 2;
+ // only for contact name too long
+ private static final int TOAST_CONTACT_NAME_TOO_LONG = 3;
+ // there is a case export is canceled by user
+ private static final int TOAST_EXPORT_CANCELED = 4;
+ // only for not have phone number or email address
+ private static final int TOAST_EXPORT_NO_PHONE_OR_EMAIL = 5;
+ // only for sim contacts haven't been loaded completely
+ private static final int TOAST_SIM_CARD_NOT_LOAD_COMPLETE = 6;
+ private SimContactsOperation mSimContactsOperation;
+ private ArrayAdapter<AdapterEntry> mAdapter;
+ private Activity mActivity;
+ private static boolean isExportingToSIM = false;
+ public static boolean isExportingToSIM(){
+ return isExportingToSIM;
+ }
+ private static ExportToSimThread mExportThread = null;
+ public ExportToSimThread createExportToSimThread(int subscription,
+ ArrayList<String[]> contactList, Activity mActivity) {
+ if (mExportThread == null)
+ mExportThread = new ExportToSimThread(subscription, contactList, mActivity);
+ return mExportThread;
+ }
+
+ public static void destroyExportToSimThread(){
+ mExportThread = null;
+ }
+ public void showExportToSIMProgressDialog(Activity activity){
+ mExportThread.showExportProgressDialog(activity);
+ }
+
private SubscriptionManager mSubscriptionManager;
/** Preferred way to show this dialog */
@@ -93,6 +179,7 @@ public class ImportExportDialogFragment extends DialogFragment
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Wrap our context to inflate list items using the correct theme
+ mActivity = getActivity();
final Resources res = getActivity().getResources();
final LayoutInflater dialogInflater = (LayoutInflater)getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -101,7 +188,7 @@ public class ImportExportDialogFragment extends DialogFragment
VCardCommonArguments.ARG_CALLING_ACTIVITY);
// Adapter that shows a list of string resources
- final ArrayAdapter<AdapterEntry> adapter = new ArrayAdapter<AdapterEntry>(getActivity(),
+ mAdapter = new ArrayAdapter<AdapterEntry>(getActivity(),
R.layout.select_dialog_item) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
@@ -113,69 +200,29 @@ public class ImportExportDialogFragment extends DialogFragment
}
};
- final TelephonyManager manager =
- (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
-
- mSubscriptionManager = SubscriptionManager.from(getActivity());
-
- 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 (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.manage_sim_contacts),
- R.string.manage_sim_contacts,
- subInfoRecords.get(0).getSubscriptionId()));
- adapter.add(new AdapterEntry(getString(R.string.export_to_sim),
- R.string.export_to_sim,
- subInfoRecords.get(0).getSubscriptionId()));
- } else {
- for (SubscriptionInfo record : subInfoRecords) {
- adapter.add(new AdapterEntry(getSubDescription(record, true),
- R.string.manage_sim_contacts, record.getSubscriptionId()));
- adapter.add(new AdapterEntry(getSubDescription(record, false),
- R.string.export_to_sim, record.getSubscriptionId()));
- }
- }
- }
- }
- if (res.getBoolean(R.bool.config_allow_export)) {
- if (contactsAreAvailable) {
- adapter.add(new AdapterEntry(getString(R.string.export_to_vcf_file),
- R.string.export_to_vcf_file));
- }
- }
- if (res.getBoolean(R.bool.config_allow_share_visible_contacts)) {
- if (contactsAreAvailable) {
- adapter.add(new AdapterEntry(getString(R.string.share_visible_contacts),
- R.string.share_visible_contacts));
- }
- }
+ // Manually call notifyDataSetChanged() to refresh the list.
+ mAdapter.setNotifyOnChange(false);
+ loadData(contactsAreAvailable);
final DialogInterface.OnClickListener clickListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- boolean dismissDialog;
- final int resId = adapter.getItem(which).mChoiceResourceId;
+ final int resId = mAdapter.getItem(which).mChoiceResourceId;
switch (resId) {
- case R.string.manage_sim_contacts:
+ case R.string.import_from_sim: {
+ handleImportFromSimRequest(resId);
+ break;
+ }
case R.string.import_from_vcf_file: {
- dismissDialog = handleImportRequest(resId,
- adapter.getItem(which).mSubscriptionId);
+ handleImportRequest(resId);
+ break;
+ }
+ case R.string.export_to_sim: {
+ handleExportToSimRequest(resId);
break;
}
case R.string.export_to_vcf_file: {
- dismissDialog = true;
Intent exportIntent = new Intent(getActivity(), ExportVCardActivity.class);
exportIntent.putExtra(VCardCommonArguments.ARG_CALLING_ACTIVITY,
callingActivity);
@@ -183,38 +230,79 @@ public class ImportExportDialogFragment extends DialogFragment
break;
}
case R.string.share_visible_contacts: {
- dismissDialog = true;
doShareVisibleContacts();
break;
}
- case R.string.export_to_sim: {
- dismissDialog = true;
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName("com.android.phone",
- "com.android.phone.ExportContactsToSim");
- intent.putExtra("subscription_id", adapter.getItem(which).mSubscriptionId);
- startActivity(intent);
- break;
- }
default: {
- dismissDialog = true;
Log.e(TAG, "Unexpected resource: "
+ getActivity().getResources().getResourceEntryName(resId));
}
}
- if (dismissDialog) {
- dialog.dismiss();
- }
+ dialog.dismiss();
}
};
return new AlertDialog.Builder(getActivity())
.setTitle(contactsAreAvailable
? R.string.dialog_import_export
: R.string.dialog_import)
- .setSingleChoiceItems(adapter, -1, clickListener)
+ .setSingleChoiceItems(mAdapter, -1, clickListener)
.create();
}
+ /**
+ * Loading the menu list data.
+ * @param contactsAreAvailable
+ */
+ private void loadData(boolean contactsAreAvailable) {
+ if (null == mActivity && null == mAdapter) {
+ return;
+ }
+
+ mAdapter.clear();
+ final Resources res = mActivity.getResources();
+ boolean hasIccCard = false;
+ if (TelephonyManager.getDefault().isMultiSimEnabled()) {
+ for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
+ hasIccCard = TelephonyManager.getDefault().hasIccCard(i);
+ if (hasIccCard) {
+ break;
+ }
+ }
+ } else {
+ hasIccCard = TelephonyManager.getDefault().hasIccCard();
+ }
+
+ if (hasIccCard
+ && res.getBoolean(R.bool.config_allow_sim_import)) {
+ mAdapter.add(new AdapterEntry(getString(R.string.import_from_sim),
+ R.string.import_from_sim));
+ }
+ if (res.getBoolean(R.bool.config_allow_import_from_vcf_file)) {
+ mAdapter.add(new AdapterEntry(getString(R.string.import_from_vcf_file),
+ R.string.import_from_vcf_file));
+ }
+
+ if (hasIccCard) {
+ mAdapter.add(new AdapterEntry(getString(R.string.export_to_sim),
+ R.string.export_to_sim));
+ }
+ if (res.getBoolean(R.bool.config_allow_export)) {
+ // If contacts are available and there is at least one contact in
+ // database, show "Export to SD card" menu item. Otherwise hide it
+ // because it makes no sense.
+ if (contactsAreAvailable) {
+ mAdapter.add(new AdapterEntry(getString(R.string.export_to_vcf_file),
+ R.string.export_to_vcf_file));
+ }
+ }
+ if (res.getBoolean(R.bool.config_allow_share_visible_contacts)) {
+ if (contactsAreAvailable) {
+ mAdapter.add(new AdapterEntry(getString(R.string.share_visible_contacts),
+ R.string.share_visible_contacts));
+ }
+ }
+ }
+
private void doShareVisibleContacts() {
try {
// TODO move the query into a loader and do this in a background thread
@@ -260,23 +348,22 @@ public class ImportExportDialogFragment extends DialogFragment
*
* @return {@code true} if the dialog show be closed. {@code false} otherwise.
*/
- private boolean handleImportRequest(int resId, int subscriptionId) {
+ 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
// - no account -> use phone-local storage without asking the user
- final AccountTypeManager accountTypes = AccountTypeManager.getInstance(getActivity());
+ final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mActivity);
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);
+ SelectAccountDialogFragment.show(mActivity.getFragmentManager(),
+ this, R.string.dialog_new_contact_account,
+ AccountListFilter.ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM,
+ 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
@@ -284,8 +371,8 @@ public class ImportExportDialogFragment extends DialogFragment
return false;
}
- AccountSelectionUtil.doImport(getActivity(), resId,
- (size == 1 ? accountList.get(0) : null), subscriptionId);
+ AccountSelectionUtil.doImport(mActivity, resId,
+ (size == 1 ? accountList.get(0) : null));
return true; // Close the dialog.
}
@@ -294,8 +381,7 @@ public class ImportExportDialogFragment extends DialogFragment
*/
@Override
public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
- AccountSelectionUtil.doImport(getActivity(), extraArgs.getInt(KEY_RES_ID),
- account, extraArgs.getInt(KEY_SUBSCRIPTION_ID));
+ AccountSelectionUtil.doImport(mActivity, extraArgs.getInt(KEY_RES_ID), account);
// At this point the dialog is still showing (which is why we can use getActivity() above)
// So close it.
@@ -308,6 +394,478 @@ public class ImportExportDialogFragment extends DialogFragment
dismiss();
}
+ private class ExportToSimSelectListener implements DialogInterface.OnClickListener {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which >= 0) {
+ mExportSub = which;
+ } else if (which == DialogInterface.BUTTON_POSITIVE) {
+ Intent pickPhoneIntent = new Intent(
+ SimContactsConstants.ACTION_MULTI_PICK, Contacts.CONTENT_URI);
+ // do not show the contacts in SIM card
+ pickPhoneIntent.putExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER,
+ ContactListFilter
+ .createFilterWithType(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
+ pickPhoneIntent.putExtra(EXT_NOT_SHOW_SIM_FLAG, true);
+ pickPhoneIntent.putExtra(SimContactsConstants.IS_CONTACT,true);
+ mActivity.startActivityForResult(pickPhoneIntent, SUBACTIVITY_MULTI_PICK_CONTACT);
+ }
+ }
+ }
+
+ public class ImportFromSimSelectListener implements DialogInterface.OnClickListener {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which >= 0) {
+ AccountSelectionUtil.setImportSubscription(which);
+ } else if (which == DialogInterface.BUTTON_POSITIVE) {
+ handleImportRequest(R.string.import_from_sim);
+ }
+ }
+ }
+
+ /**
+ * A thread that export contacts to sim card
+ */
+ public class ExportToSimThread extends Thread {
+ private int subscription;
+ private boolean canceled;
+ private ArrayList<String[]> contactList;
+ private ProgressDialog mExportProgressDlg;
+ private ContentValues mValues = new ContentValues();
+ Activity mPeople;
+ private int freeSimCount = 0;
+
+ public ExportToSimThread(int subscription, ArrayList<String[]> contactList,
+ Activity mActivity) {
+ super();
+ this.subscription = subscription;
+ this.contactList = contactList;
+ canceled = false;
+ mPeople = mActivity;
+ showExportProgressDialog(mPeople);
+ }
+
+ @Override
+ public void run() {
+ isExportingToSIM = true;
+ Account account = MoreContactUtils.getAcount(subscription);
+ boolean isAirplaneMode = false;
+ boolean isSimCardFull = false;
+ boolean isSimCardLoaded = true;
+ // GoogleSource.createMyContactsIfNotExist(account, getActivity());
+ // in case export is stopped, record the count of inserted successfully
+ int insertCount = 0;
+
+ mSimContactsOperation = new SimContactsOperation(mPeople);
+ Cursor cr = null;
+ // call query first, otherwise insert will fail if this insert is called
+ // without any query before
+ try{
+ int[] subId = SubscriptionManager.getSubId(subscription);
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ cr = mPeople.getContentResolver().query(
+ Uri.parse(SimContactsConstants.SIM_SUB_URI
+ + subId[0]), null, null, null, null);
+ } else {
+ cr = mPeople.getContentResolver().query(
+ Uri.parse(SimContactsConstants.SIM_URI), null,
+ null, null, null);
+ }
+ } catch (NullPointerException e) {
+ Log.e(TAG, "Exception:" + e);
+ } finally {
+ if (cr != null) {
+ cr.close();
+ }
+ }
+ freeSimCount = MoreContactUtils.getSimFreeCount(mPeople,subscription);
+ boolean canSaveAnr = MoreContactUtils.canSaveAnr(subscription);
+ boolean canSaveEmail = MoreContactUtils.canSaveEmail(subscription);
+ int emptyAnr = MoreContactUtils.getSpareAnrCount(subscription);
+ int emptyEmail = MoreContactUtils
+ .getSpareEmailCount(subscription);
+ int emptyNumber = freeSimCount + emptyAnr;
+
+ Log.d(TAG, "freeSimCount = " + freeSimCount);
+ String emails = null;
+ if (contactList != null) {
+ Iterator<String[]> iterator = contactList.iterator();
+ while (iterator.hasNext() && !canceled && !isAirplaneMode && isSimCardLoaded) {
+ String[] contactInfo = iterator.next();
+ //contacts name has been existed in contactInfo,so no need query it again
+ String name = contactInfo[4];
+ ArrayList<String> arrayNumber = new ArrayList<String>();
+ ArrayList<String> arrayEmail = new ArrayList<String>();
+
+ Uri dataUri = Uri.withAppendedPath(
+ ContentUris.withAppendedId(Contacts.CONTENT_URI,
+ Long.parseLong(contactInfo[1])),
+ Contacts.Data.CONTENT_DIRECTORY);
+ final String[] projection = new String[] {
+ Contacts._ID, Contacts.Data.MIMETYPE, Contacts.Data.DATA1,
+ };
+ Cursor c = mPeople.getContentResolver().query(dataUri, projection, null,
+ null, null);
+
+ if (c != null && c.moveToFirst()) {
+ do {
+ String mimeType = c.getString(1);
+ if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ String number = c.getString(2);
+ if (!TextUtils.isEmpty(number) && emptyNumber-- >0) {
+ arrayNumber.add(number);
+ }
+ }
+ if (canSaveEmail) {
+ if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ String email = c.getString(2);
+ if (!TextUtils.isEmpty(email) && emptyEmail-- > 0) {
+ arrayEmail.add(email);
+ }
+ }
+ }
+ } while (c.moveToNext());
+ }
+ if (c != null) {
+ c.close();
+ }
+
+ if (freeSimCount > 0 && 0 == arrayNumber.size()
+ && 0 == arrayEmail.size()) {
+ mToastHandler.sendMessage(mToastHandler.obtainMessage(
+ TOAST_EXPORT_NO_PHONE_OR_EMAIL, name));
+ continue;
+ }
+
+ int phoneCountInOneSimContact = 1;
+ int emailCountInOneSimContact = 0;
+ if (canSaveAnr) {
+ int num = MoreContactUtils.getOneSimAnrCount(subscription);
+ phoneCountInOneSimContact = num > 1 ? (num + 1) : 2;
+ }
+ if (canSaveEmail) {
+ emailCountInOneSimContact = MoreContactUtils
+ .getOneSimEmailCount(subscription);
+ }
+ int nameCount = (name != null && !name.equals("")) ? 1 : 0;
+ int groupNumCount = (arrayNumber.size() % phoneCountInOneSimContact) != 0 ?
+ (arrayNumber.size() / phoneCountInOneSimContact + 1)
+ : (arrayNumber.size() / phoneCountInOneSimContact);
+ int groupEmailCount = emailCountInOneSimContact == 0 ? 0
+ : ((arrayEmail.size() % emailCountInOneSimContact) != 0 ? (
+ arrayEmail.size() / emailCountInOneSimContact + 1)
+ : (arrayEmail.size() / emailCountInOneSimContact));
+ //recalute the group when spare anr is not enough
+ if (canSaveAnr && emptyAnr >=0 && emptyAnr <= groupNumCount) {
+ groupNumCount = arrayNumber.size() - emptyAnr;
+ }
+ int groupCount = Math.max(groupEmailCount,
+ Math.max(nameCount, groupNumCount));
+
+ Uri result = null;
+ if (DEBUG) {
+ Log.d(TAG, "GroupCount = " + groupCount);
+ }
+ for (int i = 0; i < groupCount; i++) {
+ if (freeSimCount > 0) {
+ String num = arrayNumber.size() > 0 ? arrayNumber.remove(0) : null;
+ StringBuilder anrNum = new StringBuilder();
+ StringBuilder email = new StringBuilder();
+ if (canSaveAnr) {
+ for (int j = 1; j < phoneCountInOneSimContact; j++) {
+ if (arrayNumber.size() > 0 && emptyAnr-- > 0 ) {
+ String s = arrayNumber.remove(0);
+ if (s.length() > MoreContactUtils
+ .MAX_LENGTH_NUMBER_IN_SIM) {
+ s = s.substring(0,
+ MoreContactUtils.MAX_LENGTH_NUMBER_IN_SIM);
+ }
+ anrNum.append(s);
+ anrNum.append(SimContactsConstants.ANR_SEP);
+ }
+ }
+ }
+ if (canSaveEmail) {
+ for (int j = 0; j < emailCountInOneSimContact; j++) {
+ if (arrayEmail.size() > 0) {
+ String s = arrayEmail.remove(0);
+ if (s.length() > MoreContactUtils
+ .MAX_LENGTH_EMAIL_IN_SIM) {
+ s = s.substring(0,
+ MoreContactUtils.MAX_LENGTH_EMAIL_IN_SIM);
+ }
+ email.append(s);
+ email.append(SimContactsConstants.EMAIL_SEP);
+ }
+ }
+ }
+
+ result = MoreContactUtils.insertToCard(mPeople, name, num,
+ email.toString(), anrNum.toString(), subscription);
+
+ if (null == result) {
+ // add toast handler when sim card is full
+ if ((MoreContactUtils.getAdnCount(subscription) > 0)
+ && (MoreContactUtils.getSimFreeCount(mPeople,
+ subscription) == 0)) {
+ isSimCardFull = true;
+ mToastHandler.sendMessage(mToastHandler.obtainMessage(
+ TOAST_SIM_CARD_FULL, insertCount, 0));
+ break;
+ } else {
+ isAirplaneMode = MoreContactUtils
+ .isAPMOnAndSIMPowerDown(mPeople);
+ if (isAirplaneMode) {
+ mToastHandler.sendMessage(mToastHandler.obtainMessage(
+ TOAST_EXPORT_FAILED, insertCount, 0));
+ break;
+ } else {
+ // Failed to insert to SIM card
+ int anrNumber = 0;
+ if (!TextUtils.isEmpty(anrNum)) {
+ anrNumber += anrNum.toString().split(
+ SimContactsConstants.ANR_SEP).length;
+ }
+ // reset emptyNumber and emptyAnr to the value before
+ // the insert operation
+ emptyAnr += anrNumber;
+ emptyNumber += anrNumber;
+ if (!TextUtils.isEmpty(num)) {
+ emptyNumber++;
+ }
+
+ if (!TextUtils.isEmpty(email)) {
+ // reset emptyEmail to the value before the insert
+ // operation
+ emptyEmail += email.toString().split(
+ SimContactsConstants.EMAIL_SEP).length;
+ }
+ continue;
+ }
+ }
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Exported contact [" + name + ", "
+ + contactInfo[0] + ", " + contactInfo[1]
+ + "] to sub " + subscription);
+ }
+ insertCount++;
+ freeSimCount--;
+ }
+ } else {
+ if (MoreContactUtils.getAdnCount(subscription) == 0) {
+ isSimCardLoaded = false;
+ mToastHandler.sendEmptyMessage(
+ TOAST_SIM_CARD_NOT_LOAD_COMPLETE);
+ } else {
+ isSimCardFull = true;
+ mToastHandler.sendMessage(mToastHandler.obtainMessage(
+ TOAST_SIM_CARD_FULL, insertCount, 0));
+ }
+ break;
+ }
+ }
+
+ if (isSimCardFull) {
+ break;
+ }
+ }
+ }
+ if (mExportProgressDlg != null) {
+ mExportProgressDlg.dismiss();
+ mExportProgressDlg = null;
+ }
+
+ if (!isAirplaneMode && !isSimCardFull) {
+ // if canceled, show toast indicating export is interrupted.
+ if (canceled) {
+ mToastHandler.sendMessage(mToastHandler.obtainMessage(TOAST_EXPORT_CANCELED,
+ insertCount, 0));
+ } else {
+ mToastHandler.sendEmptyMessage(TOAST_EXPORT_FINISHED);
+ }
+ }
+ isExportingToSIM = false;
+ Intent intent = new Intent(SimContactsConstants.INTENT_EXPORT_COMPLETE);
+ mPeople.sendBroadcast(intent);
+ }
+
+ private Handler mToastHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ int exportCount = 0;
+ switch (msg.what) {
+ case TOAST_EXPORT_FAILED:
+ exportCount = msg.arg1;
+ Toast.makeText(mPeople, mPeople.getString(R.string.export_to_sim_failed,
+ exportCount), Toast.LENGTH_SHORT).show();
+ break;
+ case TOAST_EXPORT_FINISHED:
+ Toast.makeText(mPeople, R.string.export_finished, Toast.LENGTH_SHORT)
+ .show();
+ break;
+
+ // add toast handler when sim card is full
+ case TOAST_SIM_CARD_FULL:
+ exportCount = msg.arg1;
+ Toast.makeText(mPeople, mPeople.getString(R.string.export_sim_card_full,
+ exportCount), Toast.LENGTH_SHORT).show();
+ break;
+
+ //add the max count limit of Chinese code or not
+ case TOAST_CONTACT_NAME_TOO_LONG:
+ Toast.makeText(mPeople, R.string.tag_too_long, Toast.LENGTH_SHORT).show();
+ break;
+
+ // add toast handler when export is canceled
+ case TOAST_EXPORT_CANCELED:
+ exportCount = msg.arg1;
+ Toast.makeText(mPeople,mPeople.getString(R.string.export_cancelled,
+ String.valueOf(exportCount)), Toast.LENGTH_SHORT).show();
+ break;
+
+ // add toast handler when no phone or email
+ case TOAST_EXPORT_NO_PHONE_OR_EMAIL:
+ String name = (String) msg.obj;
+ Toast.makeText(mPeople,
+ mPeople.getString(R.string.export_no_phone_or_email, name),
+ Toast.LENGTH_SHORT).show();
+ break;
+ case TOAST_SIM_CARD_NOT_LOAD_COMPLETE:
+ Toast.makeText(mPeople, R.string.sim_contacts_not_load,
+ Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+ };
+
+ public void showExportProgressDialog(Activity activity){
+ mPeople = activity;
+ mExportProgressDlg = new ProgressDialog(mPeople);
+ mExportProgressDlg.setTitle(R.string.export_to_sim);
+ mExportProgressDlg.setOnCancelListener(new OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ Log.d(TAG, "Cancel exporting contacts");
+ canceled = true;
+ }
+ });
+ mExportProgressDlg.setMessage(mPeople.getString(R.string.exporting));
+ mExportProgressDlg.setProgressNumberFormat(mPeople.getString(
+ R.string.reading_vcard_files));
+ mExportProgressDlg.setMax(contactList.size());
+ //mExportProgressDlg.setProgress(insertCount);
+
+ // set cancel dialog by touching outside disabled.
+ mExportProgressDlg.setCanceledOnTouchOutside(false);
+
+ // add a cancel button to let user cancel explicitly.
+ mExportProgressDlg.setButton(DialogInterface.BUTTON_NEGATIVE,
+ mPeople.getString(R.string.progressdialog_cancel),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (DEBUG) {
+ Log.d(TAG, "Cancel exporting contacts by click button");
+ }
+ canceled = true;
+ }
+ });
+
+ mExportProgressDlg.show();
+ }
+ }
+
+ public ImportFromSimSelectListener listener;
+ /**
+ * Create a {@link Dialog} that allows the user to pick from a bulk import
+ * or bulk export task across all contacts.
+ */
+ private Dialog displayImportExportDialog(int id, Bundle bundle) {
+ Dialog diag;
+ switch (id) {
+ case R.string.import_from_sim_select: {
+ listener = new ImportFromSimSelectListener();
+ showSimSelectDialog();
+ break;
+ }
+ case R.string.export_to_sim: {
+ String[] items = new String[TelephonyManager.getDefault().getPhoneCount()];
+ for (int i = 0; i < items.length; i++) {
+ items[i] = getString(R.string.export_to_sim) + ": "
+ + MoreContactUtils.getMultiSimAliasesName(mActivity, i);
+ }
+ mExportSub = PhoneConstants.SUB1;
+ ExportToSimSelectListener listener = new ExportToSimSelectListener();
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.export_to_sim)
+ .setPositiveButton(android.R.string.ok, listener)
+ .setSingleChoiceItems(items, 0, listener).create();
+ }
+ }
+ return null;
+ }
+
+ public void showSimSelectDialog() {
+ AccountSelectionUtil.setImportSubscription(PhoneConstants.SUB1);
+ // item is for sim account to show
+ String[] items = new String[TelephonyManager.getDefault().getPhoneCount()];
+ for (int i = 0; i < items.length; i++) {
+ items[i] = getString(R.string.import_from_sim) + ": "
+ + MoreContactUtils.getMultiSimAliasesName(mActivity, i);
+ }
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.import_from_sim)
+ .setPositiveButton(android.R.string.ok, listener)
+ .setSingleChoiceItems(items, 0, listener).create().show();
+ }
+
+ private void handleImportFromSimRequest(int Id) {
+ if (TelephonyManager.getDefault().isMultiSimEnabled()) {
+ if (MoreContactUtils.getEnabledSimCount() > 1) {
+ displayImportExportDialog(R.string.import_from_sim_select
+ ,null);
+ } else {
+ AccountSelectionUtil.setImportSubscription(getEnabledIccCard());
+ handleImportRequest(Id);
+ }
+ } else {
+ handleImportRequest(Id);
+ }
+ }
+
+ private void handleExportToSimRequest(int Id) {
+ if (MoreContactUtils.getEnabledSimCount() >1) {
+ //has two enalbed sim cards, prompt dialog to select one
+ displayImportExportDialog(Id, null).show();
+ } else {
+ mExportSub = getEnabledIccCard();
+ Intent pickPhoneIntent = new Intent(
+ SimContactsConstants.ACTION_MULTI_PICK, Contacts.CONTENT_URI);
+ // do not show the contacts in SIM card
+ pickPhoneIntent.putExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER,
+ ContactListFilter
+ .createFilterWithType(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS));
+ pickPhoneIntent.putExtra(EXT_NOT_SHOW_SIM_FLAG, true);
+ pickPhoneIntent.putExtra(SimContactsConstants.IS_CONTACT,true);
+ mActivity.startActivityForResult(pickPhoneIntent, SUBACTIVITY_MULTI_PICK_CONTACT);
+ }
+ }
+
+ private boolean hasEnabledIccCard(int subscription) {
+ return TelephonyManager.getDefault().hasIccCard(subscription)
+ && TelephonyManager.getDefault().getSimState(subscription)
+ == TelephonyManager.SIM_STATE_READY;
+ }
+
+ private int getEnabledIccCard() {
+ for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
+ if (hasEnabledIccCard(i)) {
+ return i;
+ }
+ }
+ return PhoneConstants.SUB1;
+ }
+
private CharSequence getSubDescription(SubscriptionInfo record, boolean isImport) {
CharSequence name = record.getDisplayName();
if (TextUtils.isEmpty(record.getNumber())) {
diff --git a/src/com/android/contacts/common/util/AccountSelectionUtil.java b/src/com/android/contacts/common/util/AccountSelectionUtil.java
index ff8397ae..79eb44a8 100644
--- a/src/com/android/contacts/common/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/common/util/AccountSelectionUtil.java
@@ -22,6 +22,8 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
@@ -31,11 +33,14 @@ import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.android.contacts.common.R;
+import com.android.contacts.common.SimContactsConstants;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.vcard.ImportVCardActivity;
+import com.android.internal.telephony.PhoneConstants;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -48,6 +53,8 @@ public class AccountSelectionUtil {
public static boolean mVCardShare = false;
public static Uri mPath;
+ // QRD enhancement: import subscription selected by user
+ private static int mImportSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
public static class AccountSelectedListener
implements DialogInterface.OnClickListener {
@@ -78,7 +85,7 @@ public class AccountSelectionUtil {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
- doImport(mContext, mResId, mAccountList.get(which), mSubscriptionId);
+ doImport(mContext, mResId, mAccountList.get(which));
}
/**
* Reset the account list for this listener, to make sure the selected
@@ -91,6 +98,10 @@ public class AccountSelectionUtil {
}
}
+ public static void setImportSubscription(int subscription) {
+ mImportSub = subscription;
+ }
+
public static Dialog getSelectAccountDialog(Context context, int resId) {
return getSelectAccountDialog(context, resId, null, null);
}
@@ -188,11 +199,11 @@ public class AccountSelectionUtil {
.create();
}
- public static void doImport(Context context, int resId, AccountWithDataSet account,
- int subscriptionId) {
+ public static void doImport(Context context, int resId,
+ AccountWithDataSet account) {
switch (resId) {
- case R.string.manage_sim_contacts: {
- doImportFromSim(context, account, subscriptionId);
+ case R.string.import_from_sim: {
+ doImportFromSim(context, account);
break;
}
case R.string.import_from_vcf_file: {
@@ -202,17 +213,18 @@ public class AccountSelectionUtil {
}
}
- public static void doImportFromSim(Context context, AccountWithDataSet account,
- int subscriptionId) {
- Intent importIntent = new Intent(Intent.ACTION_VIEW);
- importIntent.setType("vnd.android.cursor.item/sim-contact");
+ public static void doImportFromSim(Context context, AccountWithDataSet account) {
+ Intent importIntent = new Intent(SimContactsConstants.ACTION_MULTI_PICK_SIM);
if (account != null) {
- importIntent.putExtra("account_name", account.name);
- importIntent.putExtra("account_type", account.type);
- importIntent.putExtra("data_set", account.dataSet);
+ importIntent.putExtra(SimContactsConstants.ACCOUNT_NAME, account.name);
+ importIntent.putExtra(SimContactsConstants.ACCOUNT_TYPE, account.type);
+ importIntent.putExtra(SimContactsConstants.ACCOUNT_DATA, account.dataSet);
+ }
+ if (TelephonyManager.getDefault().isMultiSimEnabled()) {
+ importIntent.putExtra(PhoneConstants.SLOT_KEY, mImportSub);
+ } else {
+ importIntent.putExtra(PhoneConstants.SLOT_KEY,PhoneConstants.SUB1);
}
- importIntent.putExtra("subscription_id", (Integer) subscriptionId);
- importIntent.setClassName("com.android.phone", "com.android.phone.SimContacts");
context.startActivity(importIntent);
}
diff --git a/src/com/android/contacts/common/vcard/SelectAccountActivity.java b/src/com/android/contacts/common/vcard/SelectAccountActivity.java
index 66bfbca1..d8596378 100644
--- a/src/com/android/contacts/common/vcard/SelectAccountActivity.java
+++ b/src/com/android/contacts/common/vcard/SelectAccountActivity.java
@@ -58,7 +58,8 @@ public class SelectAccountActivity extends Activity {
// - no account -> use phone-local storage without asking the user
final int resId = R.string.import_from_vcf_file;
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true,
+ AccountTypeManager.FLAG_ALL_ACCOUNTS_WITHOUT_SIM);
if (accountList.size() == 0) {
Log.w(LOG_TAG, "Account does not exist");
finish();
@@ -106,7 +107,7 @@ public class SelectAccountActivity extends Activity {
}
return AccountSelectionUtil.getSelectAccountDialog(this, resId,
mAccountSelectionListener,
- new CancelListener());
+ new CancelListener(), false);
}
}
return super.onCreateDialog(resId, bundle);