Converted the Android client to use a status bar on the bottom of the screen instead...
authordswitkin <dswitkin@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 17 Apr 2008 20:09:17 +0000 (20:09 +0000)
committerdswitkin <dswitkin@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Thu, 17 Apr 2008 20:09:17 +0000 (20:09 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@365 59b500cc-1b3d-0410-9834-0bbf25fbcc57

android-m3/res/layout/main.xml
android-m3/res/values/ids.xml
android-m3/src/com/google/zxing/client/android/BarcodeReaderCaptureActivity.java
android-m3/src/com/google/zxing/client/android/CameraManager.java
android-m3/src/com/google/zxing/client/android/ResultHandler.java
android-m3/strings.xml.template

index a841f28..a711e08 100644 (file)
  See the License for the specific language governing permissions and
  limitations under the License.
  -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="fill_parent"
-              android:layout_height="fill_parent"/>
+              android:layout_height="fill_parent">
 
+  <FrameLayout id="@+id/preview_view"
+             android:layout_width="fill_parent"
+             android:layout_height="fill_parent"/>
+
+  <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:background="#00000000">
+
+    <FrameLayout
+                 android:layout_width="fill_parent"
+                 android:layout_height="fill_parent"
+                 android:layout_weight="1"
+                 android:background="#00000000"/>
+
+    <!-- FIXME(dswitkin): Temporary hack to force the height to 48 pixels-->
+    <LinearLayout id="@+id/status_view"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="48px"
+                  android:layout_weight="0"
+                  android:background="#55000000"
+                  android:baselineAligned="false"
+                  android:padding="4px">
+
+      <TextView id="@+id/status_text_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="left|center_vertical"
+                android:layout_weight="1"
+                android:text="@string/msg_default_status"
+                android:textColor="#ffffff"/>
+
+      <Button id="@+id/status_action_button"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center|fill_horizontal"
+              android:visibility="gone"/>
+
+    </LinearLayout>
+
+  </LinearLayout>
+
+</FrameLayout>
index 688fc60..8f10506 100644 (file)
@@ -15,6 +15,7 @@
  limitations under the License.
  -->
 <resources>
+  <!-- Messages IDs -->
   <item type="id" name="preview"/>
   <item type="id" name="decode"/>
   <item type="id" name="save"/>
   <item type="id" name="decode_failed"/>
   <item type="id" name="save_succeeded"/>
   <item type="id" name="save_failed"/>
+
+  <!-- Objects in the view hierarchy -->
+  <item type="id" name="preview_view"/>
+  <item type="id" name="status_action_button"/>
+  <item type="id" name="status_text_view"/>
+  <item type="id" name="status_view"/>
 </resources>
index b5453ca..eca4b1e 100644 (file)
@@ -25,8 +25,12 @@ import android.os.Handler;
 import android.os.Message;
 import android.view.KeyEvent;
 import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+import android.widget.TextView;
 import com.google.zxing.Result;
 import com.google.zxing.ResultPoint;
 import com.google.zxing.client.result.ParsedReaderResult;
@@ -44,6 +48,7 @@ public final class BarcodeReaderCaptureActivity extends Activity {
   private CameraManager cameraManager;
   private CameraSurfaceView surfaceView;
   private CameraThread cameraThread;
+  private String lastResult;
 
   private static final int ABOUT_ID = Menu.FIRST;
   private static final int HELP_ID = Menu.FIRST + 1;
@@ -59,11 +64,16 @@ public final class BarcodeReaderCaptureActivity extends Activity {
         LayoutParams.NO_STATUS_BAR_FLAG));
     getWindow().setFormat(PixelFormat.TRANSLUCENT);
 
+    setContentView(R.layout.main);
+
     cameraManager = new CameraManager(getApplication());
     surfaceView = new CameraSurfaceView(getApplication(), cameraManager);
-    setContentView(surfaceView);
-    cameraThread = new CameraThread(this, surfaceView, cameraManager, messageHandler);
-    cameraThread.start();
+    surfaceView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
+        LayoutParams.FILL_PARENT));
+
+    ViewGroup previewView = (ViewGroup) findViewById(R.id.preview_view);
+    previewView.addView(surfaceView);
+    cameraThread = null;
 
     // TODO re-enable this when issues with Matrix.setPolyToPoly() are resolved
     //GridSampler.setGridSampler(new AndroidGraphicsGridSampler());
@@ -80,6 +90,7 @@ public final class BarcodeReaderCaptureActivity extends Activity {
   @Override
   protected void onResume() {
     super.onResume();
+    resetStatusView();
     cameraManager.openDriver();
     if (cameraThread == null) {
       cameraThread = new CameraThread(this, surfaceView, cameraManager, messageHandler);
@@ -154,6 +165,9 @@ public final class BarcodeReaderCaptureActivity extends Activity {
           int duration = message.arg1;
           handleDecode((Result) message.obj, duration);
           break;
+        case R.id.restart_preview:
+          restartPreview();
+          break;
       }
     }
   };
@@ -163,35 +177,47 @@ public final class BarcodeReaderCaptureActivity extends Activity {
     restart.sendToTarget();
   }
 
-  // TODO(dswitkin): These deprecated showAlert calls need to be updated.
   private void handleDecode(Result rawResult, int duration) {
-    ResultPoint[] points = rawResult.getResultPoints();
-    if (points != null && points.length > 0) {
-      surfaceView.drawResultPoints(points);
-    }
+    if (!rawResult.toString().equals(lastResult)) {
+      lastResult = rawResult.toString();
 
-    Context context = getApplication();
-    ParsedReaderResult readerResult = parseReaderResult(rawResult);
-    ResultHandler handler = new ResultHandler(this, readerResult);
-    if (handler.getIntent() != null) {
-      // Can be handled by some external app; ask if the user wants to
-      // proceed first though
-      Message yesMessage = handler.obtainMessage(R.string.button_yes);
-      Message noMessage = handler.obtainMessage(R.string.button_no);
-      String title = context.getString(getDialogTitleID(readerResult.getType())) +
-          " (" + duration + " ms)";
-      showAlert(title, readerResult.getDisplayResult(), context.getString(R.string.button_yes),
-          yesMessage, context.getString(R.string.button_no), noMessage, true, noMessage);
+      ResultPoint[] points = rawResult.getResultPoints();
+      if (points != null && points.length > 0) {
+        surfaceView.drawResultPoints(points);
+      }
+
+      TextView textView = (TextView) findViewById(R.id.status_text_view);
+      ParsedReaderResult readerResult = parseReaderResult(rawResult);
+      textView.setText(readerResult.getDisplayResult() + " (" + duration + " ms)");
+
+      Button actionButton = (Button) findViewById(R.id.status_action_button);
+      int buttonText = getActionButtonText(readerResult.getType());
+      if (buttonText != 0) {
+        actionButton.setVisibility(View.VISIBLE);
+        actionButton.setText(buttonText);
+        ResultHandler handler = new ResultHandler(this, readerResult);
+        actionButton.setOnClickListener(handler);
+        actionButton.requestFocus();
+      } else {
+        actionButton.setVisibility(View.GONE);
+      }
+
+      // Show the green finder patterns for one second, then restart the preview
+      Message message = Message.obtain(messageHandler, R.id.restart_preview);
+      messageHandler.sendMessageDelayed(message, 1000);
     } else {
-      // Just show information to user
-      Message okMessage = handler.obtainMessage(R.string.button_ok);
-      String title = context.getString(R.string.title_barcode_detected) +
-          " (" + duration + " ms)";
-      showAlert(title, readerResult.getDisplayResult(), context.getString(R.string.button_ok),
-          okMessage, null, null, true, okMessage);
+      restartPreview();
     }
   }
 
+  private void resetStatusView() {
+    TextView textView = (TextView) findViewById(R.id.status_text_view);
+    textView.setText(R.string.msg_default_status);
+    Button actionButton = (Button) findViewById(R.id.status_action_button);
+    actionButton.setVisibility(View.GONE);
+    lastResult = "";
+  }
+
   private static ParsedReaderResult parseReaderResult(Result rawResult) {
     ParsedReaderResult readerResult = ParsedReaderResult.parseReaderResult(rawResult);
     if (readerResult.getType().equals(ParsedReaderResultType.TEXT)) {
@@ -209,25 +235,27 @@ public final class BarcodeReaderCaptureActivity extends Activity {
     return readerResult;
   }
 
-  private static int getDialogTitleID(ParsedReaderResultType type) {
+  private static int getActionButtonText(ParsedReaderResultType type) {
+    int buttonText;
     if (type.equals(ParsedReaderResultType.ADDRESSBOOK)) {
-      return R.string.title_add_contact;
+      buttonText = R.string.button_add_contact;
     } else if (type.equals(ParsedReaderResultType.URI) ||
                type.equals(ParsedReaderResultType.BOOKMARK) ||
                type.equals(ParsedReaderResultType.URLTO)) {
-      return R.string.title_open_url;
+      buttonText = R.string.button_open_browser;
     } else if (type.equals(ParsedReaderResultType.EMAIL) ||
                type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) {
-      return R.string.title_compose_email;
+      buttonText = R.string.button_email;
     } else if (type.equals(ParsedReaderResultType.UPC)) {
-      return R.string.title_lookup_barcode;
+      buttonText = R.string.button_lookup_product;
     } else if (type.equals(ParsedReaderResultType.TEL)) {
-      return R.string.title_dial;
+      buttonText = R.string.button_dial;
     } else if (type.equals(ParsedReaderResultType.GEO)) {
-      return R.string.title_view_maps;
+      buttonText = R.string.button_show_map;
     } else {
-      return R.string.title_barcode_detected;
+      buttonText = 0;
     }
+    return buttonText;
   }
 
 }
\ No newline at end of file
index 8264594..1cc1138 100644 (file)
@@ -241,9 +241,13 @@ final class CameraManager {
         " nativeResolution " + nativeResolution + " stillMultiplier " + stillMultiplier);
   }
 
+  /**
+   * The goal of the preview resolution is to show a little context around the framing rectangle
+   * which is the actual captured area in still mode.
+   */
   private void calculatePreviewResolution() {
     if (previewResolution == null) {
-      int previewHeight = (int) (stillResolution.x * stillMultiplier * 1.4f);
+      int previewHeight = (int) (stillResolution.x * stillMultiplier * 1.8f);
       int previewWidth = previewHeight * screenResolution.x / screenResolution.y;
       previewWidth = ((previewWidth + 7) >> 3) << 3;
       if (previewWidth > cameraResolution.x) previewWidth = cameraResolution.x;
index 072a6de..3c5de41 100755 (executable)
@@ -18,33 +18,22 @@ package com.google.zxing.client.android;
 
 import android.content.Intent;
 import android.net.ContentURI;
-import android.os.Handler;
-import android.os.Message;
 import android.provider.Contacts;
 import android.util.Log;
-import com.google.zxing.client.result.AddressBookAUParsedResult;
-import com.google.zxing.client.result.AddressBookDoCoMoParsedResult;
-import com.google.zxing.client.result.BookmarkDoCoMoParsedResult;
-import com.google.zxing.client.result.EmailAddressParsedResult;
-import com.google.zxing.client.result.EmailDoCoMoParsedResult;
-import com.google.zxing.client.result.GeoParsedResult;
-import com.google.zxing.client.result.ParsedReaderResult;
-import com.google.zxing.client.result.ParsedReaderResultType;
-import com.google.zxing.client.result.TelParsedResult;
-import com.google.zxing.client.result.UPCParsedResult;
-import com.google.zxing.client.result.URIParsedResult;
-import com.google.zxing.client.result.URLTOParsedResult;
+import android.view.View;
+import android.widget.Button;
+import com.google.zxing.client.result.*;
 
 import java.net.URISyntaxException;
 
 /**
  * Handles the result of barcode decoding in the context of the Android platform,
- * by dispatching the proper intents and so on.
+ * by dispatching the proper intents to open other activities like GMail, Maps, etc.
  *
  * @author srowen@google.com (Sean Owen)
  * @author dswitkin@google.com (Daniel Switkin)
  */
-final class ResultHandler extends Handler {
+final class ResultHandler implements Button.OnClickListener {
 
   private static final String TAG = "ResultHandler";
 
@@ -133,14 +122,9 @@ final class ResultHandler extends Handler {
     return intent;
   }
 
-  @Override
-  public void handleMessage(Message message) {
-    if (message.what == R.string.button_yes) {
-      if (intent != null) {
-        captureActivity.startActivity(intent);
-      }
-    } else {
-      captureActivity.restartPreview();
+  public void onClick(View view) {
+    if (intent != null) {
+      captureActivity.startActivity(intent);
     }
   }
 
index f6acd89..5fd6ca5 100644 (file)
  -->
 <resources>
   <string name="app_name">Barcode Reader</string>
-  <string name="button_no">No</string>
+  <string name="button_add_contact">Add Contact</string>
+  <string name="button_dial">Dial</string>
+  <string name="button_email">Email</string>
+  <string name="button_lookup_product">Lookup Product</string>
   <string name="button_ok">OK</string>
-  <string name="button_yes">Yes</string>
+  <string name="button_open_browser">Open Browser</string>
+  <string name="button_show_map">Show Map</string>
   <string name="menu_about">About...</string>
   <string name="menu_help">Help...</string>
   <string name="msg_about">ZXing Barcode Reader v@VERSION@\nhttp://code.google.com/p/zxing</string>
   <string name="msg_help">A: Decode all barcodes\nC: Capture and save a JPEG\nP: Use the preview image for decoding\nQ: Decode only QR Codes\nS: Use a still image for decoding\nT: Toggle debug method tracing\nU: Decode only UPC/1D barcodes</string>
+  <string name="msg_default_status">Place a barcode inside the viewfinder rectangle to read it.</string>
   <string name="title_about">About</string>
-  <string name="title_add_contact">Add Contact?</string>
-  <string name="title_barcode_detected">Barcode Detected</string>
-  <string name="title_compose_email">Compose E-mail?</string>
-  <string name="title_dial">Dial Number?</string>
-  <string name="title_error">Error</string>
   <string name="title_help">Keyboard Shortcut Help</string>
-  <string name="title_lookup_barcode">Look Up Barcode Online?</string>
-  <string name="title_open_url">Open Web Page?</string>
-  <string name="title_view_maps">View In Google Maps?</string>
 </resources>