From a656094ae2da0de29a90796efe395cbb13856a63 Mon Sep 17 00:00:00 2001 From: Adnan Date: Wed, 8 Apr 2015 14:16:13 -0700 Subject: Contacts: Give progress updates and fix copy to sim if mAdnCache is empty. On a fresh boot, the adn cache within PhoneBookManager will be empty, and thus any query through MoreContactUtils helper will return no space available for sim contacts. Thus, do a blocking query for the sim uri, which will only return a cursor when EF files are loaded the from SIM. While blocking, give indeterminate progress updates. This will only query if there's a valid SIM in the SIM slot. Change-Id: I2d60ef988b9bfc917512d12ad2647bba2b2afe08 --- res/values/cm_strings.xml | 1 + .../contacts/detail/ContactLoaderFragment.java | 453 +++++++++++++-------- 2 files changed, 285 insertions(+), 169 deletions(-) diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml index 2c18c0b23..cab3cf0b4 100644 --- a/res/values/cm_strings.xml +++ b/res/values/cm_strings.xml @@ -46,6 +46,7 @@ SIM card SIM card %d + Copying contact to SIM Search contacts diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java index e5decd764..dd389f973 100644 --- a/src/com/android/contacts/detail/ContactLoaderFragment.java +++ b/src/com/android/contacts/detail/ContactLoaderFragment.java @@ -17,9 +17,13 @@ package com.android.contacts.detail; import android.app.Activity; +import android.app.Dialog; +import android.app.DialogFragment; import android.app.Fragment; +import android.app.FragmentManager; import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; +import android.app.ProgressDialog; import android.content.ActivityNotFoundException; import android.content.ContentValues; import android.content.BroadcastReceiver; @@ -27,11 +31,11 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.Loader; +import android.database.Cursor; import android.media.RingtoneManager; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.Email; @@ -51,6 +55,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.ProgressBar; import android.widget.Toast; import com.android.contacts.ContactSaveService; @@ -132,10 +137,13 @@ public class ContactLoaderFragment extends Fragment implements FragmentKeyListen private static final String KEY_CONTACT_URI = "contactUri"; private static final String LOADER_ARG_CONTACT_URI = "contactUri"; private static final String CONTACTS_COMMON_PKG_NAME = "com.android.contacts.common"; + private static final String COPY_CONTACT_FRAGMENT = "copyContactFragment"; private Context mContext; private Uri mLookupUri; private ContactLoaderFragmentListener mListener; + private CopyContactDialogFragment mCopyToCardDialogFragment; + private static CopyContactToCardTask mCopyContactToCardTask; private Contact mContactData; @@ -176,6 +184,9 @@ public class ContactLoaderFragment extends Fragment implements FragmentKeyListen public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(KEY_CONTACT_URI, mLookupUri); + if (mCopyToCardDialogFragment != null) { + getChildFragmentManager().saveFragmentInstanceState(mCopyToCardDialogFragment); + } } @Override @@ -580,197 +591,301 @@ public class ContactLoaderFragment extends Fragment implements FragmentKeyListen SimContactsConstants.SUB_INVALID); } - private Handler mHandler = null; - private void copyToCard(final int sub) { - final int MSG_COPY_DONE = 0; - final int MSG_COPY_FAILURE = 1; - final int MSG_CARD_NO_SPACE = 2; - final int MSG_NO_EMPTY_EMAIL = 3; - if (mHandler == null) { - mHandler = new Handler() { - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_COPY_DONE: - Toast.makeText(mContext, R.string.copy_done, Toast.LENGTH_SHORT) - .show(); - break; - case MSG_COPY_FAILURE: - Toast.makeText(mContext, R.string.copy_failure, Toast.LENGTH_SHORT) - .show(); - break; - case MSG_CARD_NO_SPACE: - Toast.makeText(mContext, R.string.card_no_space, Toast.LENGTH_SHORT) - .show(); - break; - case MSG_NO_EMPTY_EMAIL: - Toast.makeText(mContext, R.string.no_empty_email_in_usim, - Toast.LENGTH_SHORT).show(); - break; - } + mCopyToCardDialogFragment = CopyContactDialogFragment.newInstance(); + mCopyToCardDialogFragment.setContactData(mContactData); + mCopyToCardDialogFragment.setSubscriptionId(sub); + FragmentManager fragmentManager = getChildFragmentManager(); + if (fragmentManager.findFragmentByTag(COPY_CONTACT_FRAGMENT) == null) { + mCopyToCardDialogFragment.show(getChildFragmentManager(), COPY_CONTACT_FRAGMENT); + } + } + + public static class CopyContactDialogFragment extends DialogFragment + implements CopyContactPostExecuteListener { + private static final String TASK_IS_RUNNING = "taskIsRunning"; + private Contact mContactData; + private int mSubId; + + static CopyContactDialogFragment newInstance() { + return new CopyContactDialogFragment(); + } + + void setContactData(Contact contactData) { + mContactData = contactData; + } + + void setSubscriptionId(int subId) { + mSubId = subId; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(TASK_IS_RUNNING, + mCopyContactToCardTask.getStatus() == AsyncTask.Status.RUNNING); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + boolean wasRunning = false; + if (savedInstanceState != null) { + wasRunning = savedInstanceState.getBoolean(TASK_IS_RUNNING); + } + if (mCopyContactToCardTask == null && !wasRunning) { + if (mContactData != null) { + mCopyContactToCardTask = new CopyContactToCardTask(getActivity(), + mContactData, mSubId); + mCopyContactToCardTask.execute(); } - }; + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mCopyContactToCardTask.setCopyContactPostExecuteListener(null); } - new Thread(new Runnable() { - public void run() { - synchronized (this) { - int adnCountInSimContact = 1; - int anrCountInSimContact = 1; - int emailCountInSimContact = 0; - if (!MoreContactUtils.canSaveAnr(sub)) { - anrCountInSimContact = 0; + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + ProgressDialog progressDialog = new ProgressDialog(getActivity()); + progressDialog.setIndeterminate(true); + progressDialog.setMessage(getString(R.string.copying_contact_to_sim)); + progressDialog.setCanceledOnTouchOutside(false); + mCopyContactToCardTask.setCopyContactPostExecuteListener(this); + return progressDialog; + } + + @Override + public void onTaskFinished() { + getDialog().dismiss(); + } + } + + private interface CopyContactPostExecuteListener { + void onTaskFinished(); + } + + private static class CopyContactToCardTask extends AsyncTask { + private static final int MSG_COPY_DONE = 0; + private static final int MSG_COPY_FAILURE = 1; + private static final int MSG_CARD_NO_SPACE = 2; + private static final int MSG_NO_EMPTY_EMAIL = 3; + + private static final int SUB2 = 1; + + private int mSubId; + private Context mContext; + private Contact mContactData; + private CopyContactPostExecuteListener mCopyContactPostExecuteListener; + + CopyContactToCardTask(Context context, Contact contactData, int subId) { + mContext = context; + mContactData = contactData; + mSubId = subId; + } + + void setCopyContactPostExecuteListener(CopyContactPostExecuteListener listener) { + mCopyContactPostExecuteListener = listener; + } + + @Override + protected void onPostExecute(Integer integer) { + mCopyContactPostExecuteListener.onTaskFinished(); + switch (integer) { + case MSG_COPY_DONE: + Toast.makeText(mContext, R.string.copy_done, Toast.LENGTH_SHORT) + .show(); + break; + case MSG_COPY_FAILURE: + Toast.makeText(mContext, R.string.copy_failure, Toast.LENGTH_SHORT) + .show(); + break; + case MSG_CARD_NO_SPACE: + Toast.makeText(mContext, R.string.card_no_space, Toast.LENGTH_SHORT) + .show(); + break; + case MSG_NO_EMPTY_EMAIL: + Toast.makeText(mContext, R.string.no_empty_email_in_usim, + Toast.LENGTH_SHORT).show(); + break; + } + } + + @Override + protected Integer doInBackground(String... strings) { + int adnCountInSimContact = 1; + int anrCountInSimContact = 1; + int emailCountInSimContact = 0; + + Cursor cr = null; + try { + if (MSimTelephonyManager.getDefault().isMultiSimEnabled()) { + Uri uri; + if (mSubId == SUB2) { + uri = Uri.parse("content://iccmsim/adn_sub2"); } else { - anrCountInSimContact = MoreContactUtils.getOneSimAnrCount(sub); - } - if (MoreContactUtils.canSaveEmail(sub)) { - emailCountInSimContact = MoreContactUtils.getOneSimEmailCount(sub); - } - int totalEmptyAdn = MoreContactUtils.getSimFreeCount(mContext, sub); - int totalEmptyAnr = MoreContactUtils.getSpareAnrCount(sub); - int totalEmptyEmail = MoreContactUtils.getSpareEmailCount(sub); - - Message msg = Message.obtain(); - if (totalEmptyAdn <= 0) { - msg.what = MSG_CARD_NO_SPACE; - mHandler.sendMessage(msg); - return; + uri = Uri.parse("content://iccmsim/adn"); } + cr = mContext.getContentResolver().query( + uri, null, null, null, null); + } else { + cr = mContext.getContentResolver().query( + Uri.parse("content://icc/adn"), null, null, null, null); + } + } catch (NullPointerException e) { + Log.e(TAG, "Exception: " + e); + } finally { + if (cr != null) { + cr.close(); + } + } - //to indiacate how many number in one ADN can saved to SIM card, - //1 means can only save one number,2 means can save anr - int numEntitySize = adnCountInSimContact + anrCountInSimContact; + if (!MoreContactUtils.canSaveAnr(mSubId)) { + anrCountInSimContact = 0; + } else { + anrCountInSimContact = MoreContactUtils.getOneSimAnrCount(mSubId); + } + if (MoreContactUtils.canSaveEmail(mSubId)) { + emailCountInSimContact = MoreContactUtils.getOneSimEmailCount(mSubId); + } + int totalEmptyAdn = MoreContactUtils.getSimFreeCount(mContext, mSubId); + int totalEmptyAnr = MoreContactUtils.getSpareAnrCount(mSubId); + int totalEmptyEmail = MoreContactUtils.getSpareEmailCount(mSubId); - //empty number is equals to the sum of adn and anr - int emptyNumTotal = totalEmptyAdn + totalEmptyAnr; + if (totalEmptyAdn <= 0) { + return MSG_CARD_NO_SPACE; + } - // Get name string - String strName = mContactData.getDisplayName(); + //to indicate how many number in one ADN can saved to SIM card, + //1 means can only save one number,2 means can save anr + int numEntitySize = adnCountInSimContact + anrCountInSimContact; - ArrayList arrayNumber = new ArrayList(); - ArrayList arrayEmail = new ArrayList(); + //empty number is equals to the sum of adn and anr + int emptyNumTotal = totalEmptyAdn + totalEmptyAnr; - for (RawContact rawContact : mContactData.getRawContacts()) { - for (DataItem dataItem : rawContact.getDataItems()) { - if (dataItem.getMimeType() == null) { - continue; - } - if (dataItem instanceof PhoneDataItem) { - // Get phone string - PhoneDataItem phoneNum = (PhoneDataItem) dataItem; - final String number = phoneNum.getNumber(); - if (!TextUtils.isEmpty(number) && emptyNumTotal-- > 0) { - arrayNumber.add(number); - } - } else if (dataItem instanceof EmailDataItem) { - // Get email string - EmailDataItem emailData = (EmailDataItem) dataItem; - final String address = emailData.getData(); - if (!TextUtils.isEmpty(address) && totalEmptyEmail-- > 0) { - arrayEmail.add(address); - } - } - } - } + // Get name string + String strName = mContactData.getDisplayName(); - //calculate how many ADN needed according to the number name,phone,email, - //and uses the max of them - int nameCount = (strName != null && !strName.equals("")) ? 1 : 0; - int groupNumCount = (arrayNumber.size() % numEntitySize) != 0 ? (arrayNumber - .size() / numEntitySize + 1) : (arrayNumber.size() / numEntitySize); - int groupEmailCount = emailCountInSimContact == 0 ? 0 - : ((arrayEmail.size() % emailCountInSimContact) != 0 ? (arrayEmail - .size() / emailCountInSimContact + 1) - : (arrayEmail.size() / emailCountInSimContact)); - - int groupCount = Math.max(groupEmailCount, Math.max(nameCount, groupNumCount)); - - ArrayList results = new ArrayList(); - for (int i = 0; i < groupCount; i++) { - results.add(new UsimEntity()); - } + ArrayList arrayNumber = new ArrayList(); + ArrayList arrayEmail = new ArrayList(); - UsimEntity value; - //get the phone number for each ADN from arrayNumber,put them in UsimEntity - for (int i = 0; i < groupNumCount; i++) { - value = results.get(i); - ArrayList numberItem = new ArrayList(); - for (int j = 0; j < numEntitySize; j++) { - if ((i * numEntitySize + j) < arrayNumber.size()) { - numberItem.add(arrayNumber.get(i * numEntitySize + j)); - } + for (RawContact rawContact : mContactData.getRawContacts()) { + for (DataItem dataItem : rawContact.getDataItems()) { + if (dataItem.getMimeType() == null) { + continue; + } + if (dataItem instanceof PhoneDataItem) { + // Get phone string + PhoneDataItem phoneNum = (PhoneDataItem) dataItem; + final String number = phoneNum.getNumber(); + if (!TextUtils.isEmpty(number) && emptyNumTotal-- > 0) { + arrayNumber.add(number); + } + } else if (dataItem instanceof EmailDataItem) { + // Get email string + EmailDataItem emailData = (EmailDataItem) dataItem; + final String address = emailData.getData(); + if (!TextUtils.isEmpty(address) && totalEmptyEmail-- > 0) { + arrayEmail.add(address); } - value.putNumberList(numberItem); } + } + } - for (int i = 0; i < groupEmailCount; i++) { - value = results.get(i); - ArrayList emailItem = new ArrayList(); - for (int j = 0; j < emailCountInSimContact; j++) { - if ((i * emailCountInSimContact + j) < arrayEmail.size()) { - emailItem.add(arrayEmail.get(i * emailCountInSimContact + j)); - } - } - value.putEmailList(emailItem); + //calculate how many ADN needed according to the number name,phone,email, + //and uses the max of them + int nameCount = (strName != null && !strName.equals("")) ? 1 : 0; + int groupNumCount = (arrayNumber.size() % numEntitySize) != 0 ? (arrayNumber + .size() / numEntitySize + 1) : (arrayNumber.size() / numEntitySize); + int groupEmailCount = emailCountInSimContact == 0 ? 0 + : ((arrayEmail.size() % emailCountInSimContact) != 0 ? (arrayEmail + .size() / emailCountInSimContact + 1) + : (arrayEmail.size() / emailCountInSimContact)); + + int groupCount = Math.max(groupEmailCount, Math.max(nameCount, groupNumCount)); + + ArrayList results = new ArrayList(); + for (int i = 0; i < groupCount; i++) { + results.add(new UsimEntity()); + } + + UsimEntity value; + //get the phone number for each ADN from arrayNumber,put them in UsimEntity + for (int i = 0; i < groupNumCount; i++) { + value = results.get(i); + ArrayList numberItem = new ArrayList(); + for (int j = 0; j < numEntitySize; j++) { + if ((i * numEntitySize + j) < arrayNumber.size()) { + numberItem.add(arrayNumber.get(i * numEntitySize + j)); } + } + value.putNumberList(numberItem); + } - ArrayList emptyList = new ArrayList(); - Uri itemUri = null; - if (totalEmptyEmail < 0 && MoreContactUtils.canSaveEmail(sub)) { - Message e_msg = Message.obtain(); - e_msg.what = MSG_NO_EMPTY_EMAIL; - mHandler.sendMessage(e_msg); + for (int i = 0; i < groupEmailCount; i++) { + value = results.get(i); + ArrayList emailItem = new ArrayList(); + for (int j = 0; j < emailCountInSimContact; j++) { + if ((i * emailCountInSimContact + j) < arrayEmail.size()) { + emailItem.add(arrayEmail.get(i * emailCountInSimContact + j)); } + } + value.putEmailList(emailItem); + } - //get phone number from UsimEntity,then insert to SIM card - for (int i = 0; i < groupCount; i++) { - value = results.get(i); - if (value.containsNumber()) { - arrayNumber = (ArrayList) value.getNumberList(); - } else { - arrayNumber = emptyList; - } + ArrayList emptyList = new ArrayList(); + Uri itemUri = null; + if (totalEmptyEmail < 0 && MoreContactUtils.canSaveEmail(mSubId)) { + return MSG_NO_EMPTY_EMAIL; + } - if (value.containsEmail()) { - arrayEmail = (ArrayList) value.getEmailList(); - } else { - arrayEmail = emptyList; - } - String strNum = arrayNumber.size() > 0 ? arrayNumber.get(0) : null; - StringBuilder strAnrNum = new StringBuilder(); - for (int j = 1; j < arrayNumber.size(); j++) { - String s = arrayNumber.get(j); - if (s.length() > MoreContactUtils.MAX_LENGTH_NUMBER_IN_SIM) { - s = s.substring( - 0, MoreContactUtils.MAX_LENGTH_NUMBER_IN_SIM); - } - strAnrNum.append(s); - strAnrNum.append(","); - } - StringBuilder strEmail = new StringBuilder(); - for (int j = 0; j < arrayEmail.size(); j++) { - String s = arrayEmail.get(j); - if (s.length() > MoreContactUtils.MAX_LENGTH_EMAIL_IN_SIM) { - s = s.substring( - 0, MoreContactUtils.MAX_LENGTH_EMAIL_IN_SIM); - } - strEmail.append(s); - strEmail.append(","); - } - itemUri = MoreContactUtils.insertToCard(mContext, strName, strNum, - strEmail.toString(), strAnrNum.toString(), sub); + //get phone number from UsimEntity,then insert to SIM card + for (int i = 0; i < groupCount; i++) { + value = results.get(i); + if (value.containsNumber()) { + arrayNumber = (ArrayList) value.getNumberList(); + } else { + arrayNumber = emptyList; + } + + if (value.containsEmail()) { + arrayEmail = (ArrayList) value.getEmailList(); + } else { + arrayEmail = emptyList; + } + String strNum = arrayNumber.size() > 0 ? arrayNumber.get(0) : null; + StringBuilder strAnrNum = new StringBuilder(); + for (int j = 1; j < arrayNumber.size(); j++) { + String s = arrayNumber.get(j); + if (s.length() > MoreContactUtils.MAX_LENGTH_NUMBER_IN_SIM) { + s = s.substring( + 0, MoreContactUtils.MAX_LENGTH_NUMBER_IN_SIM); } - if (itemUri != null) { - msg.what = MSG_COPY_DONE; - mHandler.sendMessage(msg); - } else { - msg.what = MSG_COPY_FAILURE; - mHandler.sendMessage(msg); + strAnrNum.append(s); + strAnrNum.append(","); + } + StringBuilder strEmail = new StringBuilder(); + for (int j = 0; j < arrayEmail.size(); j++) { + String s = arrayEmail.get(j); + if (s.length() > MoreContactUtils.MAX_LENGTH_EMAIL_IN_SIM) { + s = s.substring( + 0, MoreContactUtils.MAX_LENGTH_EMAIL_IN_SIM); } + strEmail.append(s); + strEmail.append(","); } + itemUri = MoreContactUtils.insertToCard(mContext, strName, strNum, + strEmail.toString(), strAnrNum.toString(), mSubId); } - }).start(); - + if (itemUri != null) { + return MSG_COPY_DONE; + } else { + return MSG_COPY_FAILURE; + } + } } /** @@ -912,7 +1027,7 @@ public class ContactLoaderFragment extends Fragment implements FragmentKeyListen } //supply phone number and email which could stored in one ADN - class UsimEntity { + static class UsimEntity { private ArrayList mNumberList = new ArrayList(); private ArrayList mEmailList = new ArrayList(); -- cgit v1.2.3