Make sure cancel is handled properly in a few cases, where app must exit after dialog
[zxing.git] / android / src / com / google / zxing / client / android / encode / EncodeActivity.java
index 3f9771f..13fbe6f 100755 (executable)
@@ -18,6 +18,7 @@ package com.google.zxing.client.android.encode;
 
 import com.google.zxing.BarcodeFormat;
 import com.google.zxing.WriterException;
+import com.google.zxing.client.android.FinishListener;
 import com.google.zxing.client.android.Intents;
 import com.google.zxing.client.android.R;
 
@@ -43,6 +44,7 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 
@@ -57,6 +59,7 @@ public final class EncodeActivity extends Activity {
   private static final String TAG = EncodeActivity.class.getSimpleName();
 
   private static final int SHARE_BARCODE_DIMENSION = 300;
+  private static final int MAX_BARCODE_FILENAME_LENGTH = 24;
 
   private QRCodeEncoder qrCodeEncoder;
   private ProgressDialog progressDialog;
@@ -81,7 +84,7 @@ public final class EncodeActivity extends Activity {
           setTitle(getString(R.string.app_name) + " - " + qrCodeEncoder.getTitle());
           qrCodeEncoder.requestBarcode(handler, smallerDimension);
           progressDialog = ProgressDialog.show(EncodeActivity.this, null,
-              getString(R.string.msg_encode_in_progress), true, true, cancelListener);
+              getString(R.string.msg_encode_in_progress), true, true, new FinishListener(EncodeActivity.this));
         } catch (IllegalArgumentException e) {
           showErrorMessage(R.string.msg_encode_contents_failed);
         }
@@ -112,18 +115,6 @@ public final class EncodeActivity extends Activity {
     }
   };
 
-  private final OnClickListener clickListener = new OnClickListener() {
-    public void onClick(DialogInterface dialog, int which) {
-      finish();
-    }
-  };
-
-  private final OnCancelListener cancelListener = new OnCancelListener() {
-    public void onCancel(DialogInterface dialog) {
-      finish();
-    }
-  };
-
   @Override
   public void onCreate(Bundle icicle) {
     super.onCreate(icicle);
@@ -153,36 +144,46 @@ public final class EncodeActivity extends Activity {
       return true;
     }
 
-
+    String contents = qrCodeEncoder.getContents();
     Bitmap bitmap;
     try {
-      bitmap = QRCodeEncoder.encodeAsBitmap(qrCodeEncoder.getContents(),
-                                            BarcodeFormat.QR_CODE,
-                                            SHARE_BARCODE_DIMENSION,
-                                            SHARE_BARCODE_DIMENSION);
+      bitmap = QRCodeEncoder.encodeAsBitmap(contents, BarcodeFormat.QR_CODE,
+          SHARE_BARCODE_DIMENSION, SHARE_BARCODE_DIMENSION);
     } catch (WriterException we) {
-      Log.w(TAG, we.toString());
+      Log.w(TAG, we);
       return true;
     }
 
-    File barcodeFile;
+    File bsRoot = new File(Environment.getExternalStorageDirectory(), "BarcodeScanner");
+    File barcodesRoot = new File(bsRoot, "Barcodes");
+    if (!barcodesRoot.exists() && !barcodesRoot.mkdirs()) {
+      Log.w(TAG, "Couldn't make dir " + barcodesRoot);
+      showErrorMessage(R.string.msg_unmount_usb);
+      return true;
+    }
+    File barcodeFile = new File(barcodesRoot, makeBarcodeFileName(contents) + ".png");
+    barcodeFile.delete();
+    FileOutputStream fos = null;
     try {
-      File bsRoot = new File(Environment.getExternalStorageDirectory(), "BarcodeScanner");
-      bsRoot.mkdir();
-      File barcodesRoot = new File(bsRoot, "barcodes");
-      barcodesRoot.mkdir();
-      barcodeFile = new File(barcodesRoot, "barcode-" + System.currentTimeMillis() + ".png");
-      barcodeFile.delete();
-      FileOutputStream fos = new FileOutputStream(barcodeFile);
+      fos = new FileOutputStream(barcodeFile);
       bitmap.compress(Bitmap.CompressFormat.PNG, 0, fos);
-      fos.close();
-    } catch (IOException ioe) {
-      Log.w(TAG, ioe.toString());
+    } catch (FileNotFoundException fnfe) {
+      Log.w(TAG, "Couldn't access file " + barcodeFile + " due to " + fnfe);
+      showErrorMessage(R.string.msg_unmount_usb);
       return true;
+    } finally {
+      if (fos != null) {
+        try {
+          fos.close();
+        } catch (IOException ioe) {
+          // do nothing
+        }
+      }
     }
 
     Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
-    intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " - " + qrCodeEncoder.getTitle());
+    intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " - " +
+        qrCodeEncoder.getTitle());
     intent.putExtra(Intent.EXTRA_TEXT, qrCodeEncoder.getContents());
     intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + barcodeFile.getAbsolutePath()));
     intent.setType("image/png");
@@ -191,6 +192,20 @@ public final class EncodeActivity extends Activity {
     return true;
   }
 
+  private static CharSequence makeBarcodeFileName(CharSequence contents) {
+    int fileNameLength = Math.min(MAX_BARCODE_FILENAME_LENGTH, contents.length());
+    StringBuilder fileName = new StringBuilder(fileNameLength);
+    for (int i = 0; i < fileNameLength; i++) {
+      char c = contents.charAt(i);
+      if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) {
+        fileName.append(c);
+      } else {
+        fileName.append('_');
+      }
+    }
+    return fileName;
+  }
+
   @Override
   protected void onResume() {
     super.onResume();
@@ -207,7 +222,8 @@ public final class EncodeActivity extends Activity {
     }
     AlertDialog.Builder builder = new AlertDialog.Builder(this);
     builder.setMessage(message);
-    builder.setPositiveButton(R.string.button_ok, clickListener);
+    builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
+    builder.setOnCancelListener(new FinishListener(this));
     builder.show();
   }
 }