diff options
| author | srowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57> | 2008-03-28 19:54:29 +0300 |
|---|---|---|
| committer | srowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57> | 2008-03-28 19:54:29 +0300 |
| commit | 414eca942699ef8b3d6e33e829a0c19ac053d093 (patch) | |
| tree | 6dbc35cbdb4275ee917d79ed8c062cc41cc977e9 | |
| parent | 267bd51f5cf4be4be3fd5647871be4477312dc7d (diff) | |
| download | zxing-android-embedded-414eca942699ef8b3d6e33e829a0c19ac053d093.tar.xz | |
Updates to build on M5
git-svn-id: http://zxing.googlecode.com/svn/trunk/android@320 59b500cc-1b3d-0410-9834-0bbf25fbcc57
| -rw-r--r-- | AndroidManifest.xml | 23 | ||||
| -rw-r--r-- | build.xml | 26 | ||||
| -rw-r--r-- | src/com/google/zxing/client/android/BarcodeReaderCaptureActivity.java | 62 | ||||
| -rw-r--r-- | src/com/google/zxing/client/android/CameraManager.java | 54 | ||||
| -rw-r--r-- | src/com/google/zxing/client/android/CameraSurfaceView.java | 11 | ||||
| -rwxr-xr-x | src/com/google/zxing/client/android/ResultHandler.java | 56 | ||||
| -rw-r--r-- | src/com/tomgibara/android/camera/BitmapCamera.java | 63 | ||||
| -rw-r--r-- | src/com/tomgibara/android/camera/CameraSource.java | 64 | ||||
| -rw-r--r-- | src/com/tomgibara/android/camera/README | 2 |
9 files changed, 255 insertions, 106 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 8f925eb8..3d614d8f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,11 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2008 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.zxing.client.android"> <application android:icon="@drawable/icon"> - <activity class=".BarcodeReaderCaptureActivity" android:label="@string/app_name"> + <activity android:name=".BarcodeReaderCaptureActivity" android:label="@string/app_name"> <intent-filter> - <action android:value="android.intent.action.MAIN"/> - <category android:value="android.intent.category.LAUNCHER"/> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> @@ -1,5 +1,4 @@ -<?xml version="1.0" ?> - +<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (C) 2008 Google Inc. @@ -22,6 +21,7 @@ <property file="../build.properties"/> <property name="sdk-folder" value="${android-home}"/> <property name="android-tools" value="${sdk-folder}/tools"/> + <property name="android-framework" value="${android-tools}/lib/framework.aidl"/> <!-- The intermediates directory --> <!-- Eclipse uses "bin" for its own output, so we do the same. --> @@ -51,8 +51,9 @@ <property name="aapt" value="${android-tools}/aapt"/> <property name="aidl" value="${android-tools}/aidl"/> <property name="dx" value="${android-tools}/dx"/> + <property name="adb" value="${android-tools}/adb" /> + <property name="android-jar" value="${sdk-folder}/android.jar" /> <property name="zip" value="zip"/> - <property name="android-jar" value="${sdk-folder}/android.jar"/> <!-- Rules --> @@ -119,6 +120,8 @@ <!-- Generate java classes from .aidl files. --> <target name="aidl" depends="dirs"> <apply executable="${aidl}" failonerror="true"> + <arg value="-p${android-framework}"/> + <arg value="-I${srcdir}"/> <fileset dir="${srcdir}"> <include name="**/*.aidl"/> </fileset> @@ -185,7 +188,7 @@ <arg value="--output=${intermediate-dex}"/> <arg value="--locals=${locals}"/> <arg value="--positions=${positions}"/> - <arg path="${outdir-classes}"/> + <arg path="${basedir}/${outdir-classes}"/> </exec> </target> @@ -245,7 +248,11 @@ only when the assets dir exists. --> update="true"/> </target> - <!-- Put the project's .dex files into the output package file. --> + <!-- Put the project's .dex files into the output package file. + Use the "zip" command, available on most un*x/Linux/MacOS systems, + to create the new package (Ant 1.7 has an internal 'zip' command, + however Ant 1.6.5 lacks it and is still widely installed.) + --> <target name="package-dex" depends="dex, package-res"> <echo>Packaging dex...</echo> <exec executable="${zip}" failonerror="true"> @@ -258,6 +265,15 @@ only when the assets dir exists. --> <!-- Create the package file for this project from the sources. --> <target name="package" depends="package-dex"/> + <!-- Install package on the default emulator --> + <target name="install"> + <echo>Sending package to default emulator...</echo> + <exec executable="${adb}" failonerror="true"> + <arg value="install" /> + <arg value="${out-package}" /> + </exec> + </target> + <target name="clean"> <delete dir="${outdir}"/> </target> diff --git a/src/com/google/zxing/client/android/BarcodeReaderCaptureActivity.java b/src/com/google/zxing/client/android/BarcodeReaderCaptureActivity.java index 31966552..a682c438 100644 --- a/src/com/google/zxing/client/android/BarcodeReaderCaptureActivity.java +++ b/src/com/google/zxing/client/android/BarcodeReaderCaptureActivity.java @@ -19,14 +19,12 @@ package com.google.zxing.client.android; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.graphics.PixelFormat; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.KeyEvent; import android.view.Menu; import android.view.Window; -import android.view.WindowManager.LayoutParams; import com.google.zxing.Result; import com.google.zxing.ResultPoint; import com.google.zxing.client.result.ParsedReaderResult; @@ -52,12 +50,6 @@ public final class BarcodeReaderCaptureActivity extends Activity { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_NO_TITLE); - // Make sure to create a TRANSLUCENT window. This is required for SurfaceView to work. - // Eventually this'll be done by the system automatically. - getWindow().setAttributes(new LayoutParams(LayoutParams.APPLICATION_TYPE, - LayoutParams.NO_STATUS_BAR_FLAG)); - getWindow().setFormat(PixelFormat.TRANSLUCENT); - cameraManager = new CameraManager(getApplication()); surfaceView = new CameraSurfaceView(getApplication(), cameraManager); setContentView(surfaceView); @@ -70,14 +62,6 @@ public final class BarcodeReaderCaptureActivity extends Activity { } @Override - protected boolean isFullscreenOpaque() { - // Our main window is set to translucent, but we know that we will - // fill it with opaque data. Tell the system that so it can perform - // some important optimizations. - return true; - } - - @Override protected void onResume() { super.onResume(); cameraManager.openDriver(); @@ -120,9 +104,12 @@ public final class BarcodeReaderCaptureActivity extends Activity { switch (item.getId()) { case ABOUT_ID: Context context = getApplication(); - showAlert(context.getString(R.string.title_about), - context.getString(R.string.msg_about), - context.getString(R.string.button_ok), null, true, null); + showAlert( + context.getString(R.string.title_about), + 0, + context.getString(R.string.msg_about), + context.getString(R.string.button_ok), + true); break; } return super.onOptionsItemSelected(item); @@ -137,9 +124,12 @@ public final class BarcodeReaderCaptureActivity extends Activity { break; case R.id.decoding_failed_message: Context context = getApplication(); - showAlert(context.getString(R.string.title_no_barcode_detected), - context.getString(R.string.msg_no_barcode_detected), - context.getString(R.string.button_ok), null, true, null); + showAlert( + context.getString(R.string.title_no_barcode_detected), + 0, + context.getString(R.string.msg_no_barcode_detected), + context.getString(R.string.button_ok), + true); break; } } @@ -149,7 +139,6 @@ public final class BarcodeReaderCaptureActivity extends Activity { workerThread.requestPreviewLoop(); } - // TODO(dswitkin): These deprecated showAlert calls need to be updated. private void handleDecode(Result rawResult) { ResultPoint[] points = rawResult.getResultPoints(); if (points != null && points.length > 0) { @@ -162,17 +151,26 @@ public final class BarcodeReaderCaptureActivity extends Activity { 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); - showAlert(context.getString(getDialogTitleID(readerResult.getType())), - readerResult.getDisplayResult(), context.getString(R.string.button_yes), - yesMessage, context.getString(R.string.button_no), noMessage, true, noMessage); + showAlert( + context.getString(getDialogTitleID(readerResult.getType())), + 0, + readerResult.getDisplayResult(), + context.getString(R.string.button_yes), + handler, + context.getString(R.string.button_no), + null, + true, + null + ); + } else { // Just show information to user - Message okMessage = handler.obtainMessage(R.string.button_ok); - showAlert(context.getString(R.string.title_barcode_detected), - readerResult.getDisplayResult(), context.getString(R.string.button_ok), okMessage, null, - null, true, okMessage); + showAlert( + context.getString(R.string.title_barcode_detected), + 0, + readerResult.getDisplayResult(), + context.getString(R.string.button_ok), + true); } } diff --git a/src/com/google/zxing/client/android/CameraManager.java b/src/com/google/zxing/client/android/CameraManager.java index 0cd3782f..6bcf7487 100644 --- a/src/com/google/zxing/client/android/CameraManager.java +++ b/src/com/google/zxing/client/android/CameraManager.java @@ -18,6 +18,7 @@ package com.google.zxing.client.android; import android.content.Context; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.Rect; @@ -26,6 +27,8 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; import com.google.zxing.ResultPoint; +import com.tomgibara.android.camera.BitmapCamera; +import com.tomgibara.android.camera.CameraSource; /** * This object wraps the CameraDevice and expects to be the only one talking to it. The @@ -45,7 +48,10 @@ final class CameraManager { private Point screenResolution; private Rect framingRect; private final Bitmap bitmap; - private CameraDevice camera; + // TODO switch back to CameraDevice later + // private CameraDevice camera; + private CameraSource cameraSource; + // end TODO private final CameraDevice.CaptureParams params; private boolean previewMode; @@ -54,34 +60,51 @@ final class CameraManager { calculateStillResolution(); getScreenResolution(); bitmap = Bitmap.createBitmap(stillResolution.x, stillResolution.y, false); - camera = CameraDevice.open(); + // TODO switch back to CameraDevice later + // camera = CameraDevice.open(); + Bitmap fakeBitmap = BitmapFactory.decodeFile("/tmp/barcode.jpg"); + if (fakeBitmap == null) { + throw new RuntimeException("/tmp/barcode.jpg was not found"); + } + cameraSource = new BitmapCamera(fakeBitmap, stillResolution.x, stillResolution.y); + // end TODO params = new CameraDevice.CaptureParams(); previewMode = false; setPreviewMode(true); } public void openDriver() { - if (camera == null) { - camera = CameraDevice.open(); - } + // TODO switch back to CameraDevice later + // if (camera == null) { + // camera = CameraDevice.open(); + // } + // end TODO } public void closeDriver() { - if (camera != null) { - camera.close(); - camera = null; - } + // TODO switch back to CameraDevice later + // if (camera != null) { + // camera.close(); + // camera = null; + // } + // end TODO } public void capturePreview(Canvas canvas) { setPreviewMode(true); - camera.capture(canvas); + // TODO switch back to CameraDevice later + // camera.capture(canvas); + cameraSource.capture(canvas); + // end TODO } public Bitmap captureStill() { setPreviewMode(false); Canvas canvas = new Canvas(bitmap); - camera.capture(canvas); + // TODO switch back to CameraDevice later + // camera.capture(canvas); + cameraSource.capture(canvas); + // end TODO return bitmap; } @@ -124,8 +147,7 @@ final class CameraManager { } /** - * Images for the live preview are taken at low resolution in RGB. The final stills for the - * decoding step are taken in YUV, since we only need the luminance channel. Other code depends + * Images for the live preview are taken at low resolution in RGB. Other code depends * on the ability to call this method for free if the correct mode is already set. * * @param on Setting on true will engage preview mode, setting it false will request still mode. @@ -164,7 +186,9 @@ final class CameraManager { " srcHeight " + params.srcHeight + " leftPixel " + params.leftPixel + " topPixel " + params.topPixel + " outputWidth " + params.outputWidth + " outputHeight " + params.outputHeight); - camera.setCaptureParams(params); + // TODO switch back to CameraDevice later + // camera.setCaptureParams(params); + // end TODO previewMode = on; } } @@ -231,7 +255,7 @@ final class CameraManager { // Temporary: the minimum focus distance in inches. private static float getMinimumFocusDistance() { - return 12.0f; + return 6.0f; } private Point getScreenResolution() { diff --git a/src/com/google/zxing/client/android/CameraSurfaceView.java b/src/com/google/zxing/client/android/CameraSurfaceView.java index 0ab8d2b7..569dd309 100644 --- a/src/com/google/zxing/client/android/CameraSurfaceView.java +++ b/src/com/google/zxing/client/android/CameraSurfaceView.java @@ -45,19 +45,14 @@ final class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callb // Install a SurfaceHolder.Callback so we get notified when the underlying surface is created // and destroyed. surfaceHolder = getHolder(); - surfaceHolder.setCallback(this); + surfaceHolder.addCallback(this); hasSurface = false; scannerAlpha = 0; surfaceHolder.setSizeFromLayout(); } - public boolean surfaceCreated(SurfaceHolder holder) { + public void surfaceCreated(SurfaceHolder holder) { hasSurface = true; - - // Tell the system that we filled the surface in this call. This is a lie to prevent the system - // from filling the surface for us automatically. THIS IS REQUIRED because otherwise we'll - // access the Surface object from 2 different threads which is not allowed. - return true; } public void surfaceDestroyed(SurfaceHolder holder) { @@ -150,6 +145,6 @@ final class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callb surfaceHolder.unlockCanvasAndPost(canvas); } - } + } } diff --git a/src/com/google/zxing/client/android/ResultHandler.java b/src/com/google/zxing/client/android/ResultHandler.java index cfe4df60..190cb73e 100755 --- a/src/com/google/zxing/client/android/ResultHandler.java +++ b/src/com/google/zxing/client/android/ResultHandler.java @@ -16,10 +16,9 @@ package com.google.zxing.client.android; +import android.content.DialogInterface; import android.content.Intent; -import android.net.ContentURI; -import android.os.Handler; -import android.os.Message; +import android.net.Uri; import android.provider.Contacts; import com.google.zxing.client.result.AddressBookAUParsedResult; import com.google.zxing.client.result.AddressBookDoCoMoParsedResult; @@ -34,8 +33,6 @@ import com.google.zxing.client.result.UPCParsedResult; import com.google.zxing.client.result.URIParsedResult; import com.google.zxing.client.result.URLTOParsedResult; -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. @@ -43,7 +40,7 @@ import java.net.URISyntaxException; * @author srowen@google.com (Sean Owen) * @author dswitkin@google.com (Daniel Switkin) */ -final class ResultHandler extends Handler { +final class ResultHandler implements DialogInterface.OnClickListener { private final Intent intent; private final BarcodeReaderCaptureActivity captureActivity; @@ -74,63 +71,38 @@ final class ResultHandler extends Handler { putExtra(intent, Contacts.Intents.Insert.POSTAL, addressResult.getAddress()); } else if (type.equals(ParsedReaderResultType.BOOKMARK)) { // For now, we can only open the browser, and not actually add a bookmark - try { - intent = new Intent(Intent.VIEW_ACTION, new ContentURI(((BookmarkDoCoMoParsedResult) result).getURI())); - } catch (URISyntaxException e) { - } + intent = new Intent(Intent.VIEW_ACTION, Uri.parse(((BookmarkDoCoMoParsedResult) result).getURI())); } else if (type.equals(ParsedReaderResultType.URLTO)) { - try { - intent = new Intent(Intent.VIEW_ACTION, new ContentURI(((URLTOParsedResult) result).getURI())); - } catch (URISyntaxException e) { - } + intent = new Intent(Intent.VIEW_ACTION, Uri.parse(((URLTOParsedResult) result).getURI())); } else if (type.equals(ParsedReaderResultType.EMAIL)) { EmailDoCoMoParsedResult emailResult = (EmailDoCoMoParsedResult) result; - try { - intent = new Intent(Intent.SENDTO_ACTION, new ContentURI(emailResult.getTo())); - } catch (URISyntaxException e) { - } + intent = new Intent(Intent.SENDTO_ACTION, Uri.parse(emailResult.getTo())); putExtra(intent, "subject", emailResult.getSubject()); putExtra(intent, "body", emailResult.getBody()); } else if (type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) { EmailAddressParsedResult emailResult = (EmailAddressParsedResult) result; - try { - intent = new Intent(Intent.SENDTO_ACTION, new ContentURI(emailResult.getEmailAddress())); - } catch (URISyntaxException e) { - } + intent = new Intent(Intent.SENDTO_ACTION, Uri.parse(emailResult.getEmailAddress())); } else if (type.equals(ParsedReaderResultType.TEL)) { TelParsedResult telResult = (TelParsedResult) result; - try { - intent = new Intent(Intent.DIAL_ACTION, new ContentURI("tel:" + telResult.getNumber())); - } catch (URISyntaxException e) { - } + intent = new Intent(Intent.DIAL_ACTION, Uri.parse("tel:" + telResult.getNumber())); } else if (type.equals(ParsedReaderResultType.GEO)) { GeoParsedResult geoResult = (GeoParsedResult) result; - try { - intent = new Intent(Intent.VIEW_ACTION, new ContentURI(geoResult.getGeoURI())); - } catch (URISyntaxException e) { - } + intent = new Intent(Intent.VIEW_ACTION, Uri.parse(geoResult.getGeoURI())); } else if (type.equals(ParsedReaderResultType.UPC)) { UPCParsedResult upcResult = (UPCParsedResult) result; - try { - ContentURI uri = new ContentURI("http://www.upcdatabase.com/item.asp?upc=" + upcResult.getUPC()); - intent = new Intent(Intent.VIEW_ACTION, uri); - } catch (URISyntaxException e) { - } + Uri uri = Uri.parse("http://www.upcdatabase.com/item.asp?upc=" + upcResult.getUPC()); + intent = new Intent(Intent.VIEW_ACTION, uri); } else if (type.equals(ParsedReaderResultType.URI)) { URIParsedResult uriResult = (URIParsedResult) result; - try { - intent = new Intent(Intent.VIEW_ACTION, new ContentURI(uriResult.getURI())); - } catch (URISyntaxException e) { - } + intent = new Intent(Intent.VIEW_ACTION, Uri.parse(uriResult.getURI())); } else if (type.equals(ParsedReaderResultType.ANDROID_INTENT)) { intent = ((AndroidIntentParsedResult) result).getIntent(); } return intent; } - @Override - public void handleMessage(Message message) { - if (message.what == R.string.button_yes) { + public void onClick(DialogInterface dialogInterface, int i) { + if (i == DialogInterface.BUTTON1) { if (intent != null) { captureActivity.startActivity(intent); } diff --git a/src/com/tomgibara/android/camera/BitmapCamera.java b/src/com/tomgibara/android/camera/BitmapCamera.java new file mode 100644 index 00000000..0d8cba80 --- /dev/null +++ b/src/com/tomgibara/android/camera/BitmapCamera.java @@ -0,0 +1,63 @@ +package com.tomgibara.android.camera;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+
+// This is public-domain code generously supplied to the developer community
+// by Tom Gibara, at http://www.tomgibara.com/android/camera-source
+
+/**
+ * A CameraSource implementation that repeatedly captures a single bitmap.
+ *
+ * @author Tom
+ *
+ */
+
+public class BitmapCamera implements CameraSource {
+
+ private final Bitmap bitmap;
+ private final Rect bounds;
+ private final Paint paint = new Paint();
+
+ public BitmapCamera(Bitmap bitmap, int width, int height) {
+ this.bitmap = bitmap;
+ bounds = new Rect(0, 0, width, height);
+
+ paint.setFilterBitmap(true);
+ paint.setAntiAlias(true);
+ }
+
+ @Override
+ public int getWidth() {
+ return bounds.right;
+ }
+
+ @Override
+ public int getHeight() {
+ return bounds.bottom;
+ }
+
+ @Override
+ public boolean open() {
+ return true;
+ }
+
+ @Override
+ public boolean capture(Canvas canvas) {
+ if (
+ bounds.right == bitmap.width() &&
+ bounds.bottom == bitmap.height()) {
+ canvas.drawBitmap(bitmap, 0, 0, null);
+ } else {
+ canvas.drawBitmap(bitmap, null, bounds, paint);
+ }
+ return true;
+ }
+
+ @Override
+ public void close() {
+ /* nothing to do */
+ }
+}
diff --git a/src/com/tomgibara/android/camera/CameraSource.java b/src/com/tomgibara/android/camera/CameraSource.java new file mode 100644 index 00000000..0bd656ff --- /dev/null +++ b/src/com/tomgibara/android/camera/CameraSource.java @@ -0,0 +1,64 @@ +package com.tomgibara.android.camera;
+
+import android.graphics.Canvas;
+
+// This is public-domain code generously supplied to the developer community
+// by Tom Gibara, at http://www.tomgibara.com/android/camera-source
+
+/**
+ * Provides a simple abstraction for obtaining preview captures from a camera
+ * on the Android platform. This interface intended to be used temporarily while
+ * the Google Android SDK fails to support camera capture from desktop devices
+ * (webcams etc).
+ *
+ * @author Tom Gibara
+ */
+
+public interface CameraSource {
+
+ static final String LOG_TAG = "camera";
+
+ /**
+ * Open the camera source for subsequent use via calls to capture().
+ *
+ * @return true if the camera source was successfully opened.
+ */
+
+ boolean open();
+
+ /**
+ * Close the camera source. Calling close on a closed CameraSource is
+ * permitted but has no effect. The camera source may be reopened after
+ * being closed.
+ */
+
+ void close();
+
+ /**
+ * The width of the captured image.
+ *
+ * @return the width of the capture in pixels
+ */
+
+ int getWidth();
+
+ /**
+ * The height of the captured image.
+ *
+ * @return the height of the capture in pixels
+ */
+
+ int getHeight();
+
+ /**
+ * Attempts to render the current camera view onto the supplied canvas.
+ * The capture will be rendered into the rectangle (0,0,width,height).
+ * Outstanding transformations on the canvas may alter this.
+ *
+ * @param canvas the canvas to which the captured pixel data will be written
+ * @return true iff a frame was successfully written to the canvas
+ */
+
+ boolean capture(Canvas canvas);
+
+}
diff --git a/src/com/tomgibara/android/camera/README b/src/com/tomgibara/android/camera/README new file mode 100644 index 00000000..cd8281e7 --- /dev/null +++ b/src/com/tomgibara/android/camera/README @@ -0,0 +1,2 @@ +This is public-domain code generously supplied to the developer community +by Tom Gibara, at http://www.tomgibara.com/android/camera-source
\ No newline at end of file |
