mirror of
https://github.com/zxing/zxing.git
synced 2025-01-12 19:57:27 -08:00
Update ZXingTest to work on 3.x+, mostly by removing the camera capture bit for now. It can come back after android/ is updated and can be cloned again. Updated android-integration with better API and ability to specify package. Now ZXingTest uses our integration code. It's updated for Android 2.x and reports camera params in a slightly better form. Also fixed a few Android 2.x issues and related intent integration stuff left over from other recent changes.
git-svn-id: https://zxing.googlecode.com/svn/trunk@2020 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
22e0f8daa2
commit
f328cb618e
|
@ -35,11 +35,15 @@
|
|||
deprecation="true"
|
||||
includeantruntime="false">
|
||||
<classpath>
|
||||
<pathelement location="${android-home}/platforms/android-10/android.jar"/>
|
||||
<pathelement location="${android-home}/platforms/android-7/android.jar"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
<jar jarfile="android-integration.jar" basedir="build"/>
|
||||
</target>
|
||||
|
||||
<target name="export" depends="build">
|
||||
<copy file="android-integration.jar" todir="../androidtest/libs"/>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="build"/>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<groupId>com.google.android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<scope>provided</scope>
|
||||
<version>1.6_r2</version>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
|
|
@ -16,14 +16,18 @@
|
|||
|
||||
package com.google.zxing.integration.android;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -34,11 +38,11 @@ import android.util.Log;
|
|||
*
|
||||
* <h2>Initiating a barcode scan</h2>
|
||||
*
|
||||
* <p>Integration is essentially as easy as calling {@link #initiateScan(Activity)} and waiting
|
||||
* <p>To integrate, create an instance of {@code IntentIntegrator} and call {@link #initiateScan()} and wait
|
||||
* for the result in your app.</p>
|
||||
*
|
||||
* <p>It does require that the Barcode Scanner application is installed. The
|
||||
* {@link #initiateScan(Activity)} method will prompt the user to download the application, if needed.</p>
|
||||
* <p>It does require that the Barcode Scanner (or work-alike) application is installed. The
|
||||
* {@link #initiateScan()} method will prompt the user to download the application, if needed.</p>
|
||||
*
|
||||
* <p>There are a few steps to using this integration. First, your {@link Activity} must implement
|
||||
* the method {@link Activity#onActivityResult(int, int, Intent)} and include a line of code like this:</p>
|
||||
|
@ -54,23 +58,31 @@ import android.util.Log;
|
|||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This is where you will handle a scan result.
|
||||
* Second, just call this in response to a user action somewhere to begin the scan process:</p>
|
||||
* <p>This is where you will handle a scan result.</p>
|
||||
*
|
||||
* <pre>{@code IntentIntegrator.initiateScan(yourActivity);}</pre>
|
||||
* <p>Second, just call this in response to a user action somewhere to begin the scan process:</p>
|
||||
*
|
||||
* <p>You can use {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} or
|
||||
* {@link #initiateScan(Activity, int, int, int, int)} to customize the download prompt with
|
||||
* different text labels.</p>
|
||||
* <pre>{@code
|
||||
* IntentIntegrator integrator = new IntentIntegrator(yourActivity);
|
||||
* integrator.initiateScan();
|
||||
* }</pre>
|
||||
*
|
||||
* <p>Note that {@link #initiateScan(Activity)} returns an {@link AlertDialog} which is non-null if the
|
||||
* <p>Note that {@link #initiateScan()} returns an {@link AlertDialog} which is non-null if the
|
||||
* user was prompted to download the application. This lets the calling app potentially manage the dialog.
|
||||
* In particular, ideally, the app dismisses the dialog if it's still active in its {@link Activity#onPause()}
|
||||
* method.</p>
|
||||
*
|
||||
* <p>You can use {@link #setTitle(String)} to customize the title of this download prompt dialog (or, use
|
||||
* {@link #setTitleByID(int)} to set the title by string resource ID.) Likewise, the prompt message, and
|
||||
* yes/no button labels can be changed.</p>
|
||||
*
|
||||
* <p>By default, this will only allow applications that are known to respond to this intent correctly
|
||||
* do so. The apps that are allowed to response can be set with {@link #setTargetApplications(Collection)}.
|
||||
* For example, set to {@link #TARGET_BARCODE_SCANNER_ONLY} to only target the Barcode Scanner app itself.</p>
|
||||
*
|
||||
* <h2>Sharing text via barcode</h2>
|
||||
*
|
||||
* <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(Activity, CharSequence)}.</p>
|
||||
* <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(CharSequence)}.</p>
|
||||
*
|
||||
* <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
|
||||
*
|
||||
|
@ -91,130 +103,162 @@ public final class IntentIntegrator {
|
|||
public static final String DEFAULT_YES = "Yes";
|
||||
public static final String DEFAULT_NO = "No";
|
||||
|
||||
private static final String PACKAGE = "com.google.zxing.client.android";
|
||||
private static final String BS_PACKAGE = "com.google.zxing.client.android";
|
||||
|
||||
// supported barcode formats
|
||||
public static final String PRODUCT_CODE_TYPES = "UPC_A,UPC_E,EAN_8,EAN_13";
|
||||
public static final String ONE_D_CODE_TYPES = PRODUCT_CODE_TYPES + ",CODE_39,CODE_93,CODE_128";
|
||||
public static final String QR_CODE_TYPES = "QR_CODE";
|
||||
public static final String ALL_CODE_TYPES = null;
|
||||
public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
|
||||
public static final Collection<String> ONE_D_CODE_TYPES =
|
||||
list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
|
||||
"ITF", "RSS_14", "RSS_EXPANDED");
|
||||
public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
|
||||
public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
|
||||
|
||||
public static final Method PACKAGE_SETTER;
|
||||
static {
|
||||
Method temp;
|
||||
try {
|
||||
temp = Intent.class.getMethod("setPackage", String.class);
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
temp = null;
|
||||
}
|
||||
PACKAGE_SETTER = temp;
|
||||
public static final Collection<String> ALL_CODE_TYPES = null;
|
||||
|
||||
public static final Collection<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singleton(BS_PACKAGE);
|
||||
public static final Collection<String> TARGET_ALL_KNOWN = list(
|
||||
BS_PACKAGE, // Barcode Scanner
|
||||
"com.srowen.bs.android", // Barcode Scanner+
|
||||
"com.srowen.bs.android.simple" // Barcode Scanner+ Simple
|
||||
// TODO add more -- what else supports this intent?
|
||||
);
|
||||
|
||||
private final Activity activity;
|
||||
private String title;
|
||||
private String message;
|
||||
private String buttonYes;
|
||||
private String buttonNo;
|
||||
private Collection<String> targetApplications;
|
||||
|
||||
public IntentIntegrator(Activity activity) {
|
||||
this.activity = activity;
|
||||
title = DEFAULT_TITLE;
|
||||
message = DEFAULT_MESSAGE;
|
||||
buttonYes = DEFAULT_YES;
|
||||
buttonNo = DEFAULT_NO;
|
||||
targetApplications = TARGET_ALL_KNOWN;
|
||||
}
|
||||
|
||||
private IntentIntegrator() {
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void setTitleByID(int titleID) {
|
||||
title = activity.getString(titleID);
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void setMessageByID(int messageID) {
|
||||
message = activity.getString(messageID);
|
||||
}
|
||||
|
||||
public String getButtonYes() {
|
||||
return buttonYes;
|
||||
}
|
||||
|
||||
public void setButtonYes(String buttonYes) {
|
||||
this.buttonYes = buttonYes;
|
||||
}
|
||||
|
||||
public void setButtonYesByID(int buttonYesID) {
|
||||
buttonYes = activity.getString(buttonYesID);
|
||||
}
|
||||
|
||||
public String getButtonNo() {
|
||||
return buttonNo;
|
||||
}
|
||||
|
||||
public void setButtonNo(String buttonNo) {
|
||||
this.buttonNo = buttonNo;
|
||||
}
|
||||
|
||||
public void setButtonNoByID(int buttonNoID) {
|
||||
buttonNo = activity.getString(buttonNoID);
|
||||
}
|
||||
|
||||
public Collection<String> getTargetApplications() {
|
||||
return targetApplications;
|
||||
}
|
||||
|
||||
public void setTargetApplications(Collection<String> targetApplications) {
|
||||
this.targetApplications = targetApplications;
|
||||
}
|
||||
|
||||
public void setSingleTargetApplication(String targetApplication) {
|
||||
this.targetApplications = Collections.singleton(targetApplication);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} --
|
||||
* same, but uses default English labels.
|
||||
* Initiates a scan for all known barcode types.
|
||||
*/
|
||||
public static AlertDialog initiateScan(Activity activity) {
|
||||
return initiateScan(activity, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
|
||||
public AlertDialog initiateScan() {
|
||||
return initiateScan(ALL_CODE_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} --
|
||||
* same, but takes string IDs which refer
|
||||
* to the {@link Activity}'s resource bundle entries.
|
||||
* Initiates a scan only for a certain set of barcode types, given as strings corresponding
|
||||
* to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
|
||||
* like {@link #PRODUCT_CODE_TYPES} for example.
|
||||
*/
|
||||
public static AlertDialog initiateScan(Activity activity,
|
||||
int stringTitle,
|
||||
int stringMessage,
|
||||
int stringButtonYes,
|
||||
int stringButtonNo) {
|
||||
return initiateScan(activity,
|
||||
activity.getString(stringTitle),
|
||||
activity.getString(stringMessage),
|
||||
activity.getString(stringButtonYes),
|
||||
activity.getString(stringButtonNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
|
||||
* same, but scans for all supported barcode types.
|
||||
* @param stringTitle title of dialog prompting user to download Barcode Scanner
|
||||
* @param stringMessage text of dialog prompting user to download Barcode Scanner
|
||||
* @param stringButtonYes text of button user clicks when agreeing to download
|
||||
* Barcode Scanner (e.g. "Yes")
|
||||
* @param stringButtonNo text of button user clicks when declining to download
|
||||
* Barcode Scanner (e.g. "No")
|
||||
* @return an {@link AlertDialog} if the user was prompted to download the app,
|
||||
* null otherwise
|
||||
*/
|
||||
public static AlertDialog initiateScan(Activity activity,
|
||||
CharSequence stringTitle,
|
||||
CharSequence stringMessage,
|
||||
CharSequence stringButtonYes,
|
||||
CharSequence stringButtonNo) {
|
||||
|
||||
return initiateScan(activity,
|
||||
stringTitle,
|
||||
stringMessage,
|
||||
stringButtonYes,
|
||||
stringButtonNo,
|
||||
ALL_CODE_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes scanning.
|
||||
*
|
||||
* @param stringTitle title of dialog prompting user to download Barcode Scanner
|
||||
* @param stringMessage text of dialog prompting user to download Barcode Scanner
|
||||
* @param stringButtonYes text of button user clicks when agreeing to download
|
||||
* Barcode Scanner (e.g. "Yes")
|
||||
* @param stringButtonNo text of button user clicks when declining to download
|
||||
* Barcode Scanner (e.g. "No")
|
||||
* @param stringDesiredBarcodeFormats a comma separated list of codes you would
|
||||
* like to scan for.
|
||||
* @return an {@link AlertDialog} if the user was prompted to download the app,
|
||||
* null otherwise
|
||||
* @throws InterruptedException if timeout expires before a scan completes
|
||||
*/
|
||||
public static AlertDialog initiateScan(Activity activity,
|
||||
CharSequence stringTitle,
|
||||
CharSequence stringMessage,
|
||||
CharSequence stringButtonYes,
|
||||
CharSequence stringButtonNo,
|
||||
CharSequence stringDesiredBarcodeFormats) {
|
||||
Intent intentScan = new Intent(PACKAGE + ".SCAN");
|
||||
setPackage(intentScan);
|
||||
public AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
|
||||
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
|
||||
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
// check which types of codes to scan for
|
||||
if (stringDesiredBarcodeFormats != null) {
|
||||
if (desiredBarcodeFormats != null) {
|
||||
// set the desired barcode types
|
||||
intentScan.putExtra("SCAN_FORMATS", stringDesiredBarcodeFormats);
|
||||
StringBuilder joinedByComma = new StringBuilder();
|
||||
for (String format : desiredBarcodeFormats) {
|
||||
if (joinedByComma.length() > 0) {
|
||||
joinedByComma.append(',');
|
||||
}
|
||||
joinedByComma.append(format);
|
||||
}
|
||||
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
|
||||
}
|
||||
|
||||
try {
|
||||
activity.startActivityForResult(intentScan, REQUEST_CODE);
|
||||
return null;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
return showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);
|
||||
String targetAppPackage = findTargetAppPackage(intentScan);
|
||||
if (targetAppPackage == null) {
|
||||
return showDownloadDialog();
|
||||
}
|
||||
intentScan.setPackage(targetAppPackage);
|
||||
activity.startActivityForResult(intentScan, REQUEST_CODE);
|
||||
return null;
|
||||
}
|
||||
|
||||
private String findTargetAppPackage(Intent intent) {
|
||||
PackageManager pm = activity.getPackageManager();
|
||||
List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
if (availableApps != null) {
|
||||
for (ResolveInfo availableApp : availableApps) {
|
||||
String packageName = availableApp.activityInfo.packageName;
|
||||
if (targetApplications.contains(packageName)) {
|
||||
return packageName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static AlertDialog showDownloadDialog(final Activity activity,
|
||||
CharSequence stringTitle,
|
||||
CharSequence stringMessage,
|
||||
CharSequence stringButtonYes,
|
||||
CharSequence stringButtonNo) {
|
||||
private AlertDialog showDownloadDialog() {
|
||||
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
|
||||
downloadDialog.setTitle(stringTitle);
|
||||
downloadDialog.setMessage(stringMessage);
|
||||
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
|
||||
downloadDialog.setTitle(title);
|
||||
downloadDialog.setMessage(message);
|
||||
downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
Uri uri = Uri.parse("market://search?q=pname:" + PACKAGE);
|
||||
Uri uri = Uri.parse("market://details?id=" + BS_PACKAGE);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
try {
|
||||
activity.startActivity(intent);
|
||||
|
@ -224,7 +268,7 @@ public final class IntentIntegrator {
|
|||
}
|
||||
}
|
||||
});
|
||||
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
|
||||
downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {}
|
||||
});
|
||||
|
@ -246,79 +290,36 @@ public final class IntentIntegrator {
|
|||
String contents = intent.getStringExtra("SCAN_RESULT");
|
||||
String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
|
||||
return new IntentResult(contents, formatName);
|
||||
} else {
|
||||
return new IntentResult(null, null);
|
||||
}
|
||||
return new IntentResult(null, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #shareText(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
|
||||
* same, but uses default English labels.
|
||||
*/
|
||||
public static void shareText(Activity activity, CharSequence text) {
|
||||
shareText(activity, text, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #shareText(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
|
||||
* same, but takes string IDs which refer to the {@link Activity}'s resource bundle entries.
|
||||
*/
|
||||
public static void shareText(Activity activity,
|
||||
CharSequence text,
|
||||
int stringTitle,
|
||||
int stringMessage,
|
||||
int stringButtonYes,
|
||||
int stringButtonNo) {
|
||||
shareText(activity,
|
||||
text,
|
||||
activity.getString(stringTitle),
|
||||
activity.getString(stringMessage),
|
||||
activity.getString(stringButtonYes),
|
||||
activity.getString(stringButtonNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares the given text by encoding it as a barcode, such that another user can
|
||||
* scan the text off the screen of the device.
|
||||
*
|
||||
* @param text the text string to encode as a barcode
|
||||
* @param stringTitle title of dialog prompting user to download Barcode Scanner
|
||||
* @param stringMessage text of dialog prompting user to download Barcode Scanner
|
||||
* @param stringButtonYes text of button user clicks when agreeing to download
|
||||
* Barcode Scanner (e.g. "Yes")
|
||||
* @param stringButtonNo text of button user clicks when declining to download
|
||||
* Barcode Scanner (e.g. "No")
|
||||
*/
|
||||
public static void shareText(Activity activity,
|
||||
CharSequence text,
|
||||
CharSequence stringTitle,
|
||||
CharSequence stringMessage,
|
||||
CharSequence stringButtonYes,
|
||||
CharSequence stringButtonNo) {
|
||||
public void shareText(CharSequence text) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(PACKAGE + ".ENCODE");
|
||||
setPackage(intent);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
intent.setAction(BS_PACKAGE + ".ENCODE");
|
||||
intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
|
||||
intent.putExtra("ENCODE_DATA", text);
|
||||
try {
|
||||
String targetAppPackage = findTargetAppPackage(intent);
|
||||
if (targetAppPackage == null) {
|
||||
showDownloadDialog();
|
||||
} else {
|
||||
intent.setPackage(targetAppPackage);
|
||||
activity.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setPackage(Intent intent) {
|
||||
if (PACKAGE_SETTER != null) {
|
||||
try {
|
||||
PACKAGE_SETTER.invoke(intent, PACKAGE);
|
||||
} catch (InvocationTargetException ite) {
|
||||
Log.w(TAG, ite.getTargetException());
|
||||
} catch (IllegalAccessException iae) {
|
||||
Log.w(TAG, iae);
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<String> list(String... values) {
|
||||
return Collections.unmodifiableCollection(Arrays.asList(values));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked in Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# The name of your application package as defined in the manifest.
|
||||
# Used by the 'uninstall' rule.
|
||||
application-package=com.google.zxing.client.android
|
||||
|
||||
# The name of the source folder.
|
||||
#source-folder=src
|
||||
|
||||
# The name of the output folder.
|
||||
#out-folder=bin
|
||||
|
||||
external-libs-folder=external-libs
|
|
@ -1,11 +0,0 @@
|
|||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-10
|
|
@ -99,11 +99,13 @@ final class QRCodeEncoder {
|
|||
private boolean encodeContentsFromZXingIntent(Intent intent) {
|
||||
// Default to QR_CODE if no format given.
|
||||
String formatString = intent.getStringExtra(Intents.Encode.FORMAT);
|
||||
try {
|
||||
format = BarcodeFormat.valueOf(formatString);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// Ignore it then
|
||||
format = null;
|
||||
format = null;
|
||||
if (formatString != null) {
|
||||
try {
|
||||
format = BarcodeFormat.valueOf(formatString);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// Ignore it then
|
||||
}
|
||||
}
|
||||
if (format == null || format == BarcodeFormat.QR_CODE) {
|
||||
String type = intent.getStringExtra(Intents.Encode.TYPE);
|
||||
|
|
|
@ -16,12 +16,11 @@
|
|||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.google.zxing.client.androidtest"
|
||||
android:versionName="1.13"
|
||||
android:versionCode="5">
|
||||
<!-- We require Cupcake (Android 1.5) or later, but are really targeting Donut. -->
|
||||
<uses-sdk android:minSdkVersion="3"
|
||||
android:targetSdkVersion="4"/>
|
||||
<!-- Donut-specific flags which allow us to run on any dpi screens. -->
|
||||
android:versionName="1.2"
|
||||
android:versionCode="6"
|
||||
android:installLocation="auto">
|
||||
<uses-sdk android:minSdkVersion="7"
|
||||
android:targetSdkVersion="7"/>
|
||||
<supports-screens android:xlargeScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
|
@ -39,9 +38,6 @@
|
|||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="CameraTestActivity"
|
||||
android:screenOrientation="landscape">
|
||||
</activity>
|
||||
<activity android:name="BenchmarkActivity"
|
||||
android:label="@string/benchmark_name"
|
||||
android:screenOrientation="portrait"/>
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked in Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# The name of your application package as defined in the manifest.
|
||||
# Used by the 'uninstall' rule.
|
||||
application-package=com.google.zxing.client.androidtest
|
||||
|
||||
# The name of the source folder.
|
||||
#source-folder=src
|
||||
|
||||
# The name of the output folder.
|
||||
#out-folder=bin
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-10
|
|
@ -1,50 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2008 ZXing authors
|
||||
|
||||
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.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<SurfaceView android:id="@+id/preview_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_centerInParent="true"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@color/transparent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/transparent"/>
|
||||
|
||||
<TextView android:id="@+id/status_text_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left|center_vertical"
|
||||
android:layout_weight="0"
|
||||
android:text="@string/parameters_message"
|
||||
android:textColor="@color/status_text"
|
||||
android:background="@color/status_view"
|
||||
android:padding="4px"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -1,56 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2008 ZXing authors
|
||||
|
||||
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.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<SurfaceView android:id="@+id/preview_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_centerInParent="true"/>
|
||||
|
||||
<com.google.zxing.client.androidtest.ViewfinderView
|
||||
android:id="@+id/viewfinder_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@color/transparent"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@color/transparent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/transparent"/>
|
||||
|
||||
<TextView android:id="@+id/status_text_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left|center_vertical"
|
||||
android:layout_weight="0"
|
||||
android:text="@string/status_message"
|
||||
android:textColor="@color/status_text"
|
||||
android:background="@color/status_view"
|
||||
android:padding="4px"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -20,83 +20,79 @@
|
|||
android:gravity="center_horizontal"
|
||||
android:padding="10px">
|
||||
<TableRow>
|
||||
<Button android:id="@+id/take_test_photos"
|
||||
android:layout_width="wrap_content"
|
||||
<Button android:id="@+id/run_benchmark"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/take_test_photos"/>
|
||||
android:text="@string/benchmark_run"/>
|
||||
<Button android:id="@+id/get_camera_parameters"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/get_camera_parameters"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<Button android:id="@+id/scan_product"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/scan_product"/>
|
||||
<Button android:id="@+id/scan_qr_code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/scan_qr_code"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<Button android:id="@+id/scan_anything"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/scan_anything"/>
|
||||
<Button android:id="@+id/search_book_contents"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/search_book_contents"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<Button android:id="@+id/encode_url"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_url"/>
|
||||
<Button android:id="@+id/encode_email"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_email"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<Button android:id="@+id/encode_phone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_phone"/>
|
||||
<Button android:id="@+id/encode_sms"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_sms"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<Button android:id="@+id/encode_contact"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_contact"/>
|
||||
<Button android:id="@+id/encode_location"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_location"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<Button android:id="@+id/encode_hidden_data"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_hidden_data"/>
|
||||
<Button android:id="@+id/encode_bad_data"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/encode_bad_data"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<Button android:id="@+id/share_via_barcode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/share_via_barcode"/>
|
||||
<Button android:id="@+id/run_benchmark"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/benchmark_run"/>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2008 ZXing authors
|
||||
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<declare-styleable name="ViewfinderView">
|
||||
</declare-styleable>
|
||||
</resources>
|
|
@ -1,289 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.androidtest;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This object wraps the Camera service object and expects to be the only one talking to it. The
|
||||
* implementation encapsulates the steps needed to take preview-sized images, which are used for
|
||||
* both preview and decoding.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
final class CameraManager {
|
||||
|
||||
private static final String TAG = CameraManager.class.getSimpleName();
|
||||
|
||||
private static final int MIN_FRAME_WIDTH = 240;
|
||||
private static final int MIN_FRAME_HEIGHT = 240;
|
||||
private static final int MAX_FRAME_WIDTH = 480;
|
||||
private static final int MAX_FRAME_HEIGHT = 360;
|
||||
|
||||
private static CameraManager cameraManager;
|
||||
private static final Pattern SEMICOLON = Pattern.compile(";");
|
||||
|
||||
private Camera camera;
|
||||
private final Context context;
|
||||
private Point screenResolution;
|
||||
private Point cameraResolution;
|
||||
private Rect framingRect;
|
||||
private Handler previewHandler;
|
||||
private int previewMessage;
|
||||
private Handler autoFocusHandler;
|
||||
private int autoFocusMessage;
|
||||
private boolean initialized;
|
||||
private boolean previewing;
|
||||
|
||||
/**
|
||||
* Preview frames are delivered here, which we pass on to the registered handler. Make sure to
|
||||
* clear the handler so it will only receive one message.
|
||||
*/
|
||||
private final Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
|
||||
@Override
|
||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
||||
if (previewHandler != null) {
|
||||
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
|
||||
cameraResolution.y, data);
|
||||
message.sendToTarget();
|
||||
previewHandler = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Autofocus callbacks arrive here, and are dispatched to the Handler which requested them.
|
||||
*/
|
||||
private final Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
|
||||
@Override
|
||||
public void onAutoFocus(boolean success, Camera camera) {
|
||||
if (autoFocusHandler != null) {
|
||||
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
|
||||
// Barcode Scanner needs to insert a delay here because it does continuous focus,
|
||||
// but this test app does not, so send the message immediately.
|
||||
message.sendToTarget();
|
||||
autoFocusHandler = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes this static object with the Context of the calling Activity.
|
||||
*
|
||||
* @param context The Activity which wants to use the camera.
|
||||
*/
|
||||
public static void init(Context context) {
|
||||
if (cameraManager == null) {
|
||||
cameraManager = new CameraManager(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CameraManager singleton instance.
|
||||
*
|
||||
* @return A reference to the CameraManager singleton.
|
||||
*/
|
||||
public static CameraManager get() {
|
||||
return cameraManager;
|
||||
}
|
||||
|
||||
private CameraManager(Context context) {
|
||||
this.context = context;
|
||||
camera = null;
|
||||
initialized = false;
|
||||
previewing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the camera driver and initializes the hardware parameters.
|
||||
*
|
||||
* @param holder The surface object which the camera will draw preview frames into.
|
||||
* @throws IOException Indicates the camera driver failed to open.
|
||||
*/
|
||||
public String openDriver(SurfaceHolder holder, boolean getParameters) throws IOException {
|
||||
String result = null;
|
||||
if (camera == null) {
|
||||
camera = Camera.open();
|
||||
camera.setPreviewDisplay(holder);
|
||||
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
getScreenResolution();
|
||||
}
|
||||
|
||||
if (getParameters) {
|
||||
result = collectCameraParameters();
|
||||
}
|
||||
setCameraParameters();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the camera driver if still in use.
|
||||
*/
|
||||
public void closeDriver() {
|
||||
if (camera != null) {
|
||||
camera.release();
|
||||
camera = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the camera hardware to begin drawing preview frames to the screen.
|
||||
*/
|
||||
public void startPreview() {
|
||||
if (camera != null && !previewing) {
|
||||
camera.startPreview();
|
||||
previewing = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the camera to stop drawing preview frames.
|
||||
*/
|
||||
public void stopPreview() {
|
||||
if (camera != null && previewing) {
|
||||
camera.stopPreview();
|
||||
previewHandler = null;
|
||||
autoFocusHandler = null;
|
||||
previewing = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
|
||||
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
|
||||
* respectively.
|
||||
*
|
||||
* @param handler The handler to send the message to.
|
||||
* @param message The what field of the message to be sent.
|
||||
*/
|
||||
public void requestPreviewFrame(Handler handler, int message) {
|
||||
if (camera != null && previewing) {
|
||||
previewHandler = handler;
|
||||
previewMessage = message;
|
||||
camera.setOneShotPreviewCallback(previewCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the camera hardware to perform an autofocus.
|
||||
*
|
||||
* @param handler The Handler to notify when the autofocus completes.
|
||||
* @param message The message to deliver.
|
||||
*/
|
||||
public void requestAutoFocus(Handler handler, int message) {
|
||||
if (camera != null && previewing) {
|
||||
autoFocusHandler = handler;
|
||||
autoFocusMessage = message;
|
||||
camera.autoFocus(autoFocusCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the framing rect which the UI should draw to show the user where to place the
|
||||
* barcode. This target helps with alignment as well as forces the user to hold the device
|
||||
* far enough away to ensure the image will be in focus.
|
||||
*
|
||||
* @return The rectangle to draw on screen in window coordinates.
|
||||
*/
|
||||
public Rect getFramingRect() {
|
||||
if (framingRect == null) {
|
||||
if (camera == null) {
|
||||
return null;
|
||||
}
|
||||
int width = cameraResolution.x * 3 / 4;
|
||||
if (width < MIN_FRAME_WIDTH) {
|
||||
width = MIN_FRAME_WIDTH;
|
||||
} else if (width > MAX_FRAME_WIDTH) {
|
||||
width = MAX_FRAME_WIDTH;
|
||||
}
|
||||
int height = cameraResolution.y * 3 / 4;
|
||||
if (height < MIN_FRAME_HEIGHT) {
|
||||
height = MIN_FRAME_HEIGHT;
|
||||
} else if (height > MAX_FRAME_HEIGHT) {
|
||||
height = MAX_FRAME_HEIGHT;
|
||||
}
|
||||
int leftOffset = (cameraResolution.x - width) / 2;
|
||||
int topOffset = (cameraResolution.y - height) / 2;
|
||||
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
|
||||
Log.v(TAG, "Calculated framing rect: " + framingRect);
|
||||
}
|
||||
return framingRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera up to take preview images which are used for both preview and decoding.
|
||||
* We detect the preview format here so that buildLuminanceSource() can build an appropriate
|
||||
* LuminanceSource subclass. In the future we may want to force YUV420SP as it's the smallest,
|
||||
* and the planar Y can be used for barcode scanning without a copy in some cases.
|
||||
*/
|
||||
private void setCameraParameters() {
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
Camera.Size size = parameters.getPreviewSize();
|
||||
Log.v(TAG, "Default preview size: " + size.width + ", " + size.height);
|
||||
int previewFormat = parameters.getPreviewFormat();
|
||||
String previewFormatString = parameters.get("preview-format");
|
||||
Log.v(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString);
|
||||
|
||||
// Ensure that the camera resolution is a multiple of 8, as the screen may not be.
|
||||
// IMPORTANT: Do not copy this old code. A much better and more robust solution can be found
|
||||
// in Barcode Scanner under zxing/android.
|
||||
cameraResolution = new Point();
|
||||
cameraResolution.x = (screenResolution.x >> 3) << 3;
|
||||
cameraResolution.y = (screenResolution.y >> 3) << 3;
|
||||
Log.v(TAG, "Setting preview size: " + cameraResolution.x + ", " + cameraResolution.y);
|
||||
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
|
||||
|
||||
camera.setParameters(parameters);
|
||||
}
|
||||
|
||||
private String collectCameraParameters() {
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
String[] params = SEMICOLON.split(parameters.flatten());
|
||||
StringBuilder result = new StringBuilder(100);
|
||||
result.append("Default camera parameters:");
|
||||
for (String param : params) {
|
||||
result.append("\n ");
|
||||
result.append(param);
|
||||
}
|
||||
result.append('\n');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private Point getScreenResolution() {
|
||||
if (screenResolution == null) {
|
||||
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = manager.getDefaultDisplay();
|
||||
screenResolution = new Point(display.getWidth(), display.getHeight());
|
||||
}
|
||||
return screenResolution;
|
||||
}
|
||||
}
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.androidtest;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class CameraTestActivity extends Activity implements SurfaceHolder.Callback {
|
||||
|
||||
private static final String TAG = CameraTestActivity.class.getSimpleName();
|
||||
|
||||
public static final String GET_CAMERA_PARAMETERS = "GET_CAMERA_PARAMETERS";
|
||||
private static final String[] EMAIL_ADDRESS = {"zxing-external@google.com"};
|
||||
|
||||
private SaveThread saveThread;
|
||||
private boolean getCameraParameters;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
getCameraParameters = getIntent().getBooleanExtra(GET_CAMERA_PARAMETERS, false);
|
||||
if (getCameraParameters) {
|
||||
setContentView(R.layout.camera_parameters);
|
||||
} else {
|
||||
setContentView(R.layout.camera_test);
|
||||
}
|
||||
CameraManager.init(getApplication());
|
||||
|
||||
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
|
||||
SurfaceHolder surfaceHolder = surfaceView.getHolder();
|
||||
surfaceHolder.addCallback(this);
|
||||
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (saveThread == null && !getCameraParameters) {
|
||||
saveThread = new SaveThread(this);
|
||||
saveThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
CameraManager.get().stopPreview();
|
||||
if (saveThread != null) {
|
||||
Message quit = Message.obtain(saveThread.handler, R.id.quit);
|
||||
quit.sendToTarget();
|
||||
try {
|
||||
saveThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
// continue
|
||||
}
|
||||
saveThread = null;
|
||||
}
|
||||
CameraManager.get().closeDriver();
|
||||
}
|
||||
|
||||
final Handler handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case R.id.auto_focus:
|
||||
// Do not continuously auto focus
|
||||
break;
|
||||
case R.id.save_succeeded:
|
||||
Toast.makeText(CameraTestActivity.this, R.string.save_succeeded, 500).show();
|
||||
break;
|
||||
case R.id.save_failed:
|
||||
Toast.makeText(CameraTestActivity.this, R.string.save_failed, 2000).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (!getCameraParameters) {
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
|
||||
if (event.getRepeatCount() == 0) {
|
||||
CameraManager.get().requestAutoFocus(handler, R.id.auto_focus);
|
||||
}
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
if (event.getRepeatCount() == 0) {
|
||||
CameraManager.get().requestPreviewFrame(saveThread.handler, R.id.save);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
try {
|
||||
String parameters = CameraManager.get().openDriver(holder, getCameraParameters);
|
||||
CameraManager.get().startPreview();
|
||||
if (getCameraParameters) {
|
||||
collectStatsAndSendEmail(parameters);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
}
|
||||
|
||||
private void collectStatsAndSendEmail(String parameters) {
|
||||
StringBuilder result = new StringBuilder(1000);
|
||||
result.append("Device info:");
|
||||
result.append("\n Board: ");
|
||||
result.append(Build.BOARD);
|
||||
result.append("\n Brand: ");
|
||||
result.append(Build.BRAND);
|
||||
result.append("\n Device: ");
|
||||
result.append(Build.DEVICE);
|
||||
result.append("\n Display: ");
|
||||
result.append(Build.DISPLAY);
|
||||
result.append("\n Fingerprint: ");
|
||||
result.append(Build.FINGERPRINT);
|
||||
result.append("\n Host: ");
|
||||
result.append(Build.HOST);
|
||||
result.append("\n ID: ");
|
||||
result.append(Build.ID);
|
||||
result.append("\n Model: ");
|
||||
result.append(Build.MODEL);
|
||||
result.append("\n Product: ");
|
||||
result.append(Build.PRODUCT);
|
||||
result.append("\n Tags: ");
|
||||
result.append(Build.TAGS);
|
||||
result.append("\n Type: ");
|
||||
result.append(Build.TYPE);
|
||||
result.append("\n User: ");
|
||||
result.append(Build.USER);
|
||||
result.append("\n Version Incremental: ");
|
||||
result.append(Build.VERSION.INCREMENTAL);
|
||||
result.append("\n Version Release: ");
|
||||
result.append(Build.VERSION.RELEASE);
|
||||
result.append("\n Version SDK: ");
|
||||
result.append(Build.VERSION.SDK);
|
||||
|
||||
result.append("\n\n");
|
||||
result.append(parameters);
|
||||
|
||||
FileOutputStream stream = null;
|
||||
try {
|
||||
stream = new FileOutputStream(new File("/sdcard/CameraParameters.txt"));
|
||||
stream.write(result.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Cannot write parameters file ", e);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.putExtra(Intent.EXTRA_EMAIL, EMAIL_ADDRESS);
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, "Camera parameters report");
|
||||
intent.putExtra(Intent.EXTRA_TEXT, result.toString());
|
||||
intent.setType("text/plain");
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.androidtest;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
|
||||
final class SaveThread extends Thread {
|
||||
|
||||
private static final String TAG = SaveThread.class.getSimpleName();
|
||||
|
||||
Handler handler;
|
||||
|
||||
private final CameraTestActivity mActivity;
|
||||
|
||||
SaveThread(CameraTestActivity activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case R.id.save:
|
||||
save((byte[]) message.obj, message.arg1, message.arg2);
|
||||
break;
|
||||
case R.id.quit:
|
||||
Looper.myLooper().quit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
Looper.loop();
|
||||
}
|
||||
|
||||
// Save the center rectangle of the Y channel as a greyscale PNG to the SD card.
|
||||
private void save(byte[] data, int width, int height) {
|
||||
Rect framingRect = CameraManager.get().getFramingRect();
|
||||
int framingWidth = framingRect.width();
|
||||
int framingHeight = framingRect.height();
|
||||
if (framingWidth > width || framingHeight > height) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
int leftOffset = framingRect.left;
|
||||
int topOffset = framingRect.top;
|
||||
int[] colors = new int[framingWidth * framingHeight];
|
||||
|
||||
for (int y = 0; y < framingHeight; y++) {
|
||||
int rowOffset = (y + topOffset) * width + leftOffset;
|
||||
for (int x = 0; x < framingWidth; x++) {
|
||||
int pixel = (int) data[rowOffset + x];
|
||||
pixel = 0xff000000 + (pixel << 16) + (pixel << 8) + pixel;
|
||||
colors[y * framingWidth + x] = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(colors, framingWidth, framingHeight,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
OutputStream outStream = getNewPhotoOutputStream();
|
||||
if (outStream != null) {
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
|
||||
try {
|
||||
outStream.close();
|
||||
Message message = Message.obtain(mActivity.handler, R.id.save_succeeded);
|
||||
message.sendToTarget();
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Exception closing stream: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Message message = Message.obtain(mActivity.handler, R.id.save_failed);
|
||||
message.sendToTarget();
|
||||
}
|
||||
|
||||
private static OutputStream getNewPhotoOutputStream() {
|
||||
File sdcard = new File("/sdcard");
|
||||
if (sdcard.exists()) {
|
||||
File barcodes = new File(sdcard, "barcodes");
|
||||
if (barcodes.exists()) {
|
||||
if (!barcodes.isDirectory()) {
|
||||
Log.e(TAG, "/sdcard/barcodes exists but is not a directory");
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (!barcodes.mkdir()) {
|
||||
Log.e(TAG, "Could not create /sdcard/barcodes directory");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Date now = new Date();
|
||||
String fileName = now.getTime() + ".png";
|
||||
try {
|
||||
return new FileOutputStream(new File(barcodes, fileName));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(TAG, "Could not create FileOutputStream");
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "/sdcard does not exist");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.androidtest;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public final class ViewfinderView extends View {
|
||||
|
||||
private final Paint paint;
|
||||
private final Rect box;
|
||||
private final int maskColor;
|
||||
private final int frameColor;
|
||||
|
||||
// This constructor is used when the class is built from an XML resource.
|
||||
public ViewfinderView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
// Initialize these once for performance rather than calling them every time in onDraw().
|
||||
paint = new Paint();
|
||||
box = new Rect();
|
||||
Resources resources = getResources();
|
||||
maskColor = resources.getColor(R.color.viewfinder_mask);
|
||||
frameColor = resources.getColor(R.color.viewfinder_frame);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
Rect frame = CameraManager.get().getFramingRect();
|
||||
int width = canvas.getWidth();
|
||||
int height = canvas.getHeight();
|
||||
|
||||
// Draw the exterior (i.e. outside the framing rect) darkened, in red to distinguish it from
|
||||
// the regular barcodes app
|
||||
paint.setColor(maskColor);
|
||||
box.set(0, 0, width, frame.top);
|
||||
canvas.drawRect(box, paint);
|
||||
box.set(0, frame.top, frame.left, frame.bottom + 1);
|
||||
canvas.drawRect(box, paint);
|
||||
box.set(frame.right + 1, frame.top, width, frame.bottom + 1);
|
||||
canvas.drawRect(box, paint);
|
||||
box.set(0, frame.bottom + 1, width, height);
|
||||
canvas.drawRect(box, paint);
|
||||
|
||||
// Draw a two pixel solid white border inside the framing rect
|
||||
paint.setColor(frameColor);
|
||||
box.set(frame.left, frame.top, frame.right + 1, frame.top + 2);
|
||||
canvas.drawRect(box, paint);
|
||||
box.set(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1);
|
||||
canvas.drawRect(box, paint);
|
||||
box.set(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1);
|
||||
canvas.drawRect(box, paint);
|
||||
box.set(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1);
|
||||
canvas.drawRect(box, paint);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,24 +21,36 @@ import android.app.AlertDialog;
|
|||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Contacts;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class ZXingTestActivity extends Activity {
|
||||
|
||||
private static final String TAG = ZXingTestActivity.class.getSimpleName();
|
||||
private static final int ABOUT_ID = Menu.FIRST;
|
||||
private static final String PACKAGE_NAME = "com.google.zxing.client.androidtest";
|
||||
private static final String PACKAGE_NAME = ZXingTestActivity.class.getPackage().getName();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
setContentView(R.layout.test);
|
||||
|
||||
findViewById(R.id.take_test_photos).setOnClickListener(takeTestPhotos);
|
||||
findViewById(R.id.get_camera_parameters).setOnClickListener(getCameraParameters);
|
||||
findViewById(R.id.scan_product).setOnClickListener(scanProduct);
|
||||
findViewById(R.id.scan_qr_code).setOnClickListener(scanQRCode);
|
||||
|
@ -86,23 +98,30 @@ public final class ZXingTestActivity extends Activity {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private final Button.OnClickListener takeTestPhotos = new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setClassName(ZXingTestActivity.this, CameraTestActivity.class.getName());
|
||||
intent.putExtra(CameraTestActivity.GET_CAMERA_PARAMETERS, false);
|
||||
startActivity(intent);
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
|
||||
if (result != null) {
|
||||
String contents = result.getContents();
|
||||
if (contents != null) {
|
||||
showDialog(R.string.result_succeeded, "Format: " + result.getFormatName() + "\nContents: " + contents);
|
||||
} else {
|
||||
showDialog(R.string.result_failed, getString(R.string.result_failed_why));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private final Button.OnClickListener getCameraParameters = new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setClassName(ZXingTestActivity.this, CameraTestActivity.class.getName());
|
||||
intent.putExtra(CameraTestActivity.GET_CAMERA_PARAMETERS, true);
|
||||
String stats = collectStats();
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.putExtra(Intent.EXTRA_EMAIL, "zxing-external@google.com");
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, "Camera parameters report");
|
||||
intent.putExtra(Intent.EXTRA_TEXT, stats);
|
||||
intent.setType("text/plain");
|
||||
startActivity(intent);
|
||||
}
|
||||
};
|
||||
|
@ -123,24 +142,23 @@ public final class ZXingTestActivity extends Activity {
|
|||
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
|
||||
intent.putExtra("SCAN_WIDTH", 800);
|
||||
intent.putExtra("SCAN_HEIGHT", 200);
|
||||
startActivityForResult(intent, 0);
|
||||
startActivityForResult(intent, IntentIntegrator.REQUEST_CODE);
|
||||
}
|
||||
};
|
||||
|
||||
private final Button.OnClickListener scanQRCode = new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
||||
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
|
||||
startActivityForResult(intent, 0);
|
||||
IntentIntegrator integrator = new IntentIntegrator(ZXingTestActivity.this);
|
||||
integrator.initiateScan(IntentIntegrator.QR_CODE_TYPES);
|
||||
}
|
||||
};
|
||||
|
||||
private final Button.OnClickListener scanAnything = new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
|
||||
startActivityForResult(intent, 0);
|
||||
IntentIntegrator integrator = new IntentIntegrator(ZXingTestActivity.this);
|
||||
integrator.initiateScan();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -154,19 +172,6 @@ public final class ZXingTestActivity extends Activity {
|
|||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
if (requestCode == 0) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
String contents = intent.getStringExtra("SCAN_RESULT");
|
||||
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
|
||||
showDialog(R.string.result_succeeded, "Format: " + format + "\nContents: " + contents);
|
||||
} else if (resultCode == RESULT_CANCELED) {
|
||||
showDialog(R.string.result_failed, getString(R.string.result_failed_why));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Button.OnClickListener encodeURL = new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@ -199,10 +204,10 @@ public final class ZXingTestActivity extends Activity {
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(Contacts.Intents.Insert.NAME, "Jenny");
|
||||
bundle.putString(Contacts.Intents.Insert.PHONE, "8675309");
|
||||
bundle.putString(Contacts.Intents.Insert.EMAIL, "jenny@the80s.com");
|
||||
bundle.putString(Contacts.Intents.Insert.POSTAL, "123 Fake St. San Francisco, CA 94102");
|
||||
bundle.putString(ContactsContract.Intents.Insert.NAME, "Jenny");
|
||||
bundle.putString(ContactsContract.Intents.Insert.PHONE, "8675309");
|
||||
bundle.putString(ContactsContract.Intents.Insert.EMAIL, "jenny@the80s.com");
|
||||
bundle.putString(ContactsContract.Intents.Insert.POSTAL, "123 Fake St. San Francisco, CA 94102");
|
||||
encodeBarcode("CONTACT_TYPE", bundle);
|
||||
}
|
||||
};
|
||||
|
@ -264,4 +269,75 @@ public final class ZXingTestActivity extends Activity {
|
|||
startActivity(intent);
|
||||
}
|
||||
|
||||
private static String getFlattenedParams() {
|
||||
Camera camera = Camera.open();
|
||||
if (camera == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
if (parameters == null) {
|
||||
return null;
|
||||
}
|
||||
return parameters.flatten();
|
||||
} finally {
|
||||
camera.release();
|
||||
}
|
||||
}
|
||||
|
||||
private static String collectStats() {
|
||||
StringBuilder result = new StringBuilder(1000);
|
||||
|
||||
result.append("BOARD=").append(Build.BOARD).append('\n');
|
||||
result.append("BRAND=").append(Build.BRAND).append('\n');
|
||||
result.append("CPU_ABI=").append(Build.CPU_ABI).append('\n');
|
||||
result.append("DEVICE=").append(Build.DEVICE).append('\n');
|
||||
result.append("DISPLAY=").append(Build.DISPLAY).append('\n');
|
||||
result.append("FINGERPRINT=").append(Build.FINGERPRINT).append('\n');
|
||||
result.append("HOST=").append(Build.HOST).append('\n');
|
||||
result.append("ID=").append(Build.ID).append('\n');
|
||||
result.append("MANUFACTURER=").append(Build.MANUFACTURER).append('\n');
|
||||
result.append("MODEL=").append(Build.MODEL).append('\n');
|
||||
result.append("PRODUCT=").append(Build.PRODUCT).append('\n');
|
||||
result.append("TAGS=").append(Build.TAGS).append('\n');
|
||||
result.append("TIME=").append(Build.TIME).append('\n');
|
||||
result.append("TYPE=").append(Build.TYPE).append('\n');
|
||||
result.append("USER=").append(Build.USER).append('\n');
|
||||
result.append("VERSION.CODENAME=").append(Build.VERSION.CODENAME).append('\n');
|
||||
result.append("VERSION.INCREMENTAL=").append(Build.VERSION.INCREMENTAL).append('\n');
|
||||
result.append("VERSION.RELEASE=").append(Build.VERSION.RELEASE).append('\n');
|
||||
result.append("VERSION.SDK_INT=").append(Build.VERSION.SDK_INT).append('\n');
|
||||
|
||||
String flattened = getFlattenedParams();
|
||||
String[] params = flattened.split(";");
|
||||
Arrays.sort(params);
|
||||
for (String param : params) {
|
||||
result.append(param).append('\n');
|
||||
}
|
||||
|
||||
String resultString = result.toString();
|
||||
writeStats(resultString);
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
private static void writeStats(String resultString) {
|
||||
Writer out = null;
|
||||
try {
|
||||
out = new OutputStreamWriter(new FileOutputStream(new File("/sdcard/CameraParameters.txt")),
|
||||
Charset.forName("UTF-8"));
|
||||
out.write(resultString);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Cannot write parameters file ", e);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -130,9 +130,7 @@
|
|||
<target name="clean">
|
||||
<delete dir="build"/>
|
||||
<delete dir="build-test"/>
|
||||
<delete dir="optimized"/>
|
||||
<delete file="core.jar"/>
|
||||
<delete file="ZXingReader.*"/>
|
||||
<delete file="proguard-dump.txt"/>
|
||||
</target>
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<artifactId>core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>ZXing Core</name>
|
||||
<version>1.6-SNAPSHOT</version>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<description>Core barcode encoding/decoding library</description>
|
||||
<url>http://code.google.com/p/zxing</url>
|
||||
<inceptionYear>2007</inceptionYear>
|
||||
|
|
Loading…
Reference in a new issue