Updates to build on M5

git-svn-id: https://zxing.googlecode.com/svn/trunk@320 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-03-28 16:54:29 +00:00
parent 0198f58150
commit 10ce9dde67
9 changed files with 255 additions and 106 deletions

View file

@ -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>

View file

@ -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>

View file

@ -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);
@ -69,14 +61,6 @@ public final class BarcodeReaderCaptureActivity extends Activity {
//GridSampler.setGridSampler(new AndroidGraphicsGridSampler());
}
@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();
@ -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);
}
}

View file

@ -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() {

View file

@ -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);
}
}
}
}

View file

@ -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);
}

View file

@ -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 */
}
}

View file

@ -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);
}

View file

@ -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