Merge change 26392 into eclair
* changes:
Fix long names in recent calls screen.
diff --git a/res/values/ids.xml b/res/values/ids.xml
index dbed28a..5746232 100644
--- a/res/values/ids.xml
+++ b/res/values/ids.xml
@@ -40,4 +40,9 @@
<item type="id" name="dialog_reading_vcard" />
<item type="id" name="dialog_io_exception" />
+ <!-- For ExportVCard -->
+ <item type="id" name="dialog_confirm_export_vcard" />
+ <item type="id" name="dialog_exporting_vcard" />
+ <item type="id" name="dialog_fail_to_export_with_reason" />
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f358592..c033f8c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -764,6 +764,10 @@
<!-- The failed reason: "One or more files failed to be imported. (<a list of file names>)" -->
<string name="fail_reason_failed_to_read_files">One or more files failed to be imported (%s).</string>
+ <!-- The failed reason: "Unknown error". This message should not be shown
+ but it may in some buggy condition. -->
+ <string name="fail_reason_unknown">Unknown error</string>
+
<!-- Dialog title shown when a user is asked to select VCard file -->
<string name="select_vcard_title">Select vCard file</string>
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index c897317..7661f35 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -346,7 +346,7 @@
*/
private String mQueryData;
- private Handler mHandler = new Handler();
+ private VCardExporter mVCardExporter;
private static final String CLAUSE_ONLY_VISIBLE = Contacts.IN_VISIBLE_GROUP + "=1";
private static final String CLAUSE_ONLY_PHONES = Contacts.HAS_PHONE_NUMBER + "=1";
@@ -748,6 +748,21 @@
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchManager.stopSearch();
}
+
+ // When the orientation is changed or Home button is pressed, onStop() is called.
+ // Then, we stop exporting just for safety.
+ //
+ // Technically, it is because the dialog displaying the current status of export is
+ // closed on this method call and we cannot reliably restore the dialog in the current
+ // implementation, while the thread for exporting vCard is working at that time, without
+ // showing its status to users :(
+ // Also, it is probably not a strong requirment for us to both
+ // - enable users to press Home, slide hardware keyboard during the export
+ // - and also let vCard export to keep working.
+ if (mVCardExporter != null) {
+ mVCardExporter.cancelExport();
+ mVCardExporter = null;
+ }
}
@Override
@@ -815,6 +830,30 @@
case R.string.import_from_sdcard: {
return createSelectAccountDialog(id);
}
+ case R.string.fail_reason_too_many_vcard: {
+ return new AlertDialog.Builder(this)
+ .setTitle(R.string.exporting_contact_failed_title)
+ .setMessage(getString(R.string.exporting_contact_failed_message,
+ getString(R.string.fail_reason_too_many_vcard)))
+ .setPositiveButton(android.R.string.ok, null)
+ .create();
+ }
+ case R.id.dialog_confirm_export_vcard: {
+ return mVCardExporter.getExportConfirmationDialog();
+ }
+ case R.id.dialog_exporting_vcard: {
+ return mVCardExporter.getExportingVCardDialog();
+ }
+ case R.id.dialog_fail_to_export_with_reason: {
+ return mVCardExporter.getErrorDialogWithReason();
+ }
+ case R.id.dialog_sdcard_not_found: {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this)
+ .setTitle(R.string.no_sdcard_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setMessage(R.string.no_sdcard_message)
+ .setPositiveButton(android.R.string.ok, null);
+ }
}
return super.onCreateDialog(id);
}
@@ -983,8 +1022,15 @@
}
private void doExportToSdCard() {
- VCardExporter exporter = new VCardExporter(ContactsListActivity.this, mHandler);
- exporter.startExportVCardToSdCard();
+ mVCardExporter = new VCardExporter(this);
+ mVCardExporter.startExportVCardToSdCard();
+ }
+
+ /**
+ * Used when VCardExporter finishes its exporting.
+ */
+ /* package */ void removeReferenceToVCardExporter() {
+ mVCardExporter = null;
}
@Override
diff --git a/src/com/android/contacts/VCardExporter.java b/src/com/android/contacts/VCardExporter.java
index 2e9ab2c..5f13e99 100644
--- a/src/com/android/contacts/VCardExporter.java
+++ b/src/com/android/contacts/VCardExporter.java
@@ -15,7 +15,9 @@
*/
package com.android.contacts;
+import android.app.Activity;
import android.app.AlertDialog;
+import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -47,24 +49,16 @@
private final String mVCardTypeStr;
private final Set<String> mExtensionsToConsider;
- private Context mParentContext;
- private Handler mParentHandler;
+ private ContactsListActivity mParentActivity;
private ProgressDialog mProgressDialog;
- private class ErrorMessageDisplayRunnable implements Runnable {
- private String mReason;
- public ErrorMessageDisplayRunnable(String reason) {
- mReason = reason;
- }
+ // Used temporaly when asking users to confirm the file name
+ private String mTargetFileName;
- public void run() {
- new AlertDialog.Builder(mParentContext)
- .setTitle(getString(R.string.exporting_contact_failed_title))
- .setMessage(getString(R.string.exporting_contact_failed_message, mReason))
- .setPositiveButton(android.R.string.ok, null)
- .show();
- }
- }
+ // String for storing error reason temporaly.
+ private String mErrorReason;
+
+ private ActualExportThread mActualExportThread;
private class ConfirmListener implements DialogInterface.OnClickListener {
private String mFileName;
@@ -75,8 +69,16 @@
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
- startExport(mFileName);
- } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+ mActualExportThread = new ActualExportThread(mFileName);
+ String title = getString(R.string.exporting_contact_list_title);
+ String message = getString(R.string.exporting_contact_list_message, mFileName);
+ mProgressDialog = new ProgressDialog(mParentActivity);
+ mProgressDialog.setTitle(title);
+ mProgressDialog.setMessage(message);
+ mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ mProgressDialog.setOnCancelListener(mActualExportThread);
+ mParentActivity.showDialog(R.id.dialog_exporting_vcard);
+ mActualExportThread.start();
}
}
}
@@ -89,7 +91,7 @@
public ActualExportThread(String fileName) {
mFileName = fileName;
- PowerManager powerManager = (PowerManager)mParentContext.getSystemService(
+ PowerManager powerManager = (PowerManager)mParentActivity.getSystemService(
Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(
PowerManager.SCREEN_DIM_WAKE_LOCK |
@@ -105,21 +107,21 @@
try {
outputStream = new FileOutputStream(mFileName);
} catch (FileNotFoundException e) {
- String reason = getString(R.string.fail_reason_could_not_open_file,
+ mErrorReason = getString(R.string.fail_reason_could_not_open_file,
mFileName, e.getMessage());
- mParentHandler.post(new ErrorMessageDisplayRunnable(reason));
+ mParentActivity.showDialog(R.id.dialog_fail_to_export_with_reason);
return;
}
- composer = new VCardComposer(mParentContext, mVCardTypeStr, true);
+ composer = new VCardComposer(mParentActivity, mVCardTypeStr, true);
// composer = new VCardComposer(mParentContext,
// VCardConfig.VCARD_TYPE_V30_JAPANESE_UTF8, true);
composer.addHandler(composer.new HandlerForOutputStream(outputStream));
if (!composer.init()) {
- String reason = getString(R.string.fail_reason_could_not_initialize_exporter,
+ mErrorReason = getString(R.string.fail_reason_could_not_initialize_exporter,
composer.getErrorReason());
- mParentHandler.post(new ErrorMessageDisplayRunnable(reason));
+ mParentActivity.showDialog(R.id.dialog_fail_to_export_with_reason);
return;
}
@@ -136,9 +138,9 @@
}
if (!composer.createOneEntry()) {
Log.e(LOG_TAG, "Failed to read a contact.");
- String reason = getString(R.string.fail_reason_error_occurred_during_export,
+ mErrorReason = getString(R.string.fail_reason_error_occurred_during_export,
composer.getErrorReason());
- mParentHandler.post(new ErrorMessageDisplayRunnable(reason));
+ mParentActivity.showDialog(R.id.dialog_fail_to_export_with_reason);
return;
}
mProgressDialog.incrementProgressBy(1);
@@ -149,6 +151,7 @@
}
mWakeLock.release();
mProgressDialog.dismiss();
+ mParentActivity.removeReferenceToVCardExporter();
}
}
@@ -159,18 +162,20 @@
}
}
- public void onCancel(DialogInterface dialog) {
+ public void cancel() {
mCanceled = true;
}
+
+ public void onCancel(DialogInterface dialog) {
+ cancel();
+ }
}
/**
- * @param parentContext must not be null
- * @param parentHandler must not be null
+ * @param parentActivity must not be null
*/
- public VCardExporter(Context parentContext, Handler parentHandler) {
- mParentContext = parentContext;
- mParentHandler = parentHandler;
+ public VCardExporter(ContactsListActivity parentActivity) {
+ mParentActivity = parentActivity;
mTargetDirectory = getString(R.string.config_export_dir);
mFileNamePrefix = getString(R.string.config_export_file_prefix);
mFileNameSuffix = getString(R.string.config_export_file_suffix);
@@ -191,7 +196,7 @@
}
}
- Resources resources = parentContext.getResources();
+ Resources resources = parentActivity.getResources();
mFileIndexMinimum = resources.getInteger(R.integer.config_export_file_min_index);
mFileIndexMaximum = resources.getInteger(R.integer.config_export_file_max_index);
}
@@ -207,24 +212,15 @@
targetDirectory.isDirectory() &&
targetDirectory.canRead()) &&
!targetDirectory.mkdirs()) {
- new AlertDialog.Builder(mParentContext)
- .setTitle(R.string.no_sdcard_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setMessage(R.string.no_sdcard_message)
- .setPositiveButton(android.R.string.ok, null)
- .show();
+ mParentActivity.showDialog(R.id.dialog_sdcard_not_found);
} else {
- String fileName = getAppropriateFileName(mTargetDirectory);
- if (TextUtils.isEmpty(fileName)) {
+ mTargetFileName = getAppropriateFileName(mTargetDirectory);
+ if (TextUtils.isEmpty(mTargetFileName)) {
+ mTargetFileName = null;
return;
}
- new AlertDialog.Builder(mParentContext)
- .setTitle(R.string.confirm_export_title)
- .setMessage(getString(R.string.confirm_export_message, fileName))
- .setPositiveButton(android.R.string.ok, new ConfirmListener(fileName))
- .setNegativeButton(android.R.string.cancel, null)
- .show();
+ mParentActivity.showDialog(R.id.dialog_confirm_export_vcard);
}
}
@@ -246,8 +242,9 @@
String possibleBody = String.format(bodyFormat,mFileNamePrefix, 1, mFileNameSuffix);
if (possibleBody.length() > 8 || mFileNameExtension.length() > 3) {
Log.e(LOG_TAG, "This code does not allow any long file name.");
- displayErrorMessage(getString(R.string.fail_reason_too_long_filename,
- String.format("%s.%s", possibleBody, mFileNameExtension)));
+ mErrorReason = getString(R.string.fail_reason_too_long_filename,
+ String.format("%s.%s", possibleBody, mFileNameExtension));
+ mParentActivity.showDialog(R.id.dialog_fail_to_export_with_reason);
return null;
}
}
@@ -274,42 +271,55 @@
return String.format("%s/%s.%s", destDirectory, body, mFileNameExtension);
}
}
- displayErrorMessage(getString(R.string.fail_reason_too_many_vcard));
+ mParentActivity.showDialog(R.string.fail_reason_too_many_vcard);
return null;
}
- private void startExport(String fileName) {
- ActualExportThread thread = new ActualExportThread(fileName);
- displayReadingVCardDialog(thread, fileName);
- thread.start();
+ public Dialog getExportConfirmationDialog() {
+ if (TextUtils.isEmpty(mTargetFileName)) {
+ Log.e(LOG_TAG, "Target file name is empty, which must not be!");
+ // This situation is not acceptable (probably a bug!), but we don't have no reason to
+ // show...
+ mErrorReason = null;
+ return getErrorDialogWithReason();
+ }
+
+ return new AlertDialog.Builder(mParentActivity)
+ .setTitle(R.string.confirm_export_title)
+ .setMessage(getString(R.string.confirm_export_message, mTargetFileName))
+ .setPositiveButton(android.R.string.ok, new ConfirmListener(mTargetFileName))
+ .setNegativeButton(android.R.string.cancel, null)
+ .create();
}
- private void displayReadingVCardDialog(DialogInterface.OnCancelListener listener,
- String fileName) {
- String title = getString(R.string.exporting_contact_list_title);
- String message = getString(R.string.exporting_contact_list_message, fileName);
- mProgressDialog = new ProgressDialog(mParentContext);
- mProgressDialog.setTitle(title);
- mProgressDialog.setMessage(message);
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- mProgressDialog.setOnCancelListener(listener);
- mProgressDialog.show();
+ public Dialog getExportingVCardDialog() {
+ return mProgressDialog;
}
- private void displayErrorMessage(String failureReason) {
- new AlertDialog.Builder(mParentContext)
+ public Dialog getErrorDialogWithReason() {
+ if (mErrorReason == null) {
+ Log.e(LOG_TAG, "Error reason must have been set.");
+ mErrorReason = getString(R.string.fail_reason_unknown);
+ }
+ return new AlertDialog.Builder(mParentActivity)
.setTitle(R.string.exporting_contact_failed_title)
- .setMessage(getString(R.string.exporting_contact_failed_message,
- failureReason))
+ .setMessage(getString(R.string.exporting_contact_failed_message, mErrorReason))
.setPositiveButton(android.R.string.ok, null)
- .show();
+ .create();
+ }
+
+ public void cancelExport() {
+ if (mActualExportThread != null) {
+ mActualExportThread.cancel();
+ mActualExportThread = null;
+ }
}
private String getString(int resId, Object... formatArgs) {
- return mParentContext.getString(resId, formatArgs);
+ return mParentActivity.getString(resId, formatArgs);
}
private String getString(int resId) {
- return mParentContext.getString(resId);
+ return mParentActivity.getString(resId);
}
}
\ No newline at end of file