Let callers specify more extras to IntentIntegrator. Use it in test app, so we can use it in all cases, and avoid ActivityNotFoundException

git-svn-id: https://zxing.googlecode.com/svn/trunk@2260 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2012-04-26 16:22:24 +00:00
parent 6067089669
commit 8f461afd09
2 changed files with 84 additions and 33 deletions

View file

@ -19,7 +19,9 @@ package com.google.zxing.integration.android;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.AlertDialog;
@ -29,6 +31,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
/**
@ -75,6 +78,10 @@ import android.util.Log;
* <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>Finally, you can use {@link #addExtra(String, Object)} to add more parameters to the Intent used
* to invoke the scanner. This can be used to set additional options not directly exposed by this
* simplified API.</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)}.
@ -111,6 +118,7 @@ public class IntentIntegrator {
public static final String DEFAULT_NO = "No";
private static final String BS_PACKAGE = "com.google.zxing.client.android";
private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
// supported barcode formats
public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
@ -125,9 +133,9 @@ public class IntentIntegrator {
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?
BSPLUS_PACKAGE, // Barcode Scanner+
BSPLUS_PACKAGE + ".simple" // Barcode Scanner+ Simple
// What else supports this intent?
);
private final Activity activity;
@ -136,6 +144,7 @@ public class IntentIntegrator {
private String buttonYes;
private String buttonNo;
private Collection<String> targetApplications;
private final Map<String,Object> moreExtras;
public IntentIntegrator(Activity activity) {
this.activity = activity;
@ -144,6 +153,7 @@ public class IntentIntegrator {
buttonYes = DEFAULT_YES;
buttonNo = DEFAULT_NO;
targetApplications = TARGET_ALL_KNOWN;
moreExtras = new HashMap<String,Object>(3);
}
public String getTitle() {
@ -206,6 +216,14 @@ public class IntentIntegrator {
this.targetApplications = Collections.singleton(targetApplication);
}
public Map<String,?> getMoreExtras() {
return moreExtras;
}
public void addExtra(String key, Object value) {
moreExtras.put(key, value);
}
/**
* Initiates a scan for all known barcode types.
*/
@ -217,6 +235,9 @@ public class IntentIntegrator {
* 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.
*
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
@ -242,6 +263,7 @@ public class IntentIntegrator {
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
startActivityForResult(intentScan, REQUEST_CODE);
return null;
}
@ -328,31 +350,66 @@ public class IntentIntegrator {
}
/**
* Defaults to type "TEXT_TYPE".
* @see #shareText(CharSequence, CharSequence)
*/
public AlertDialog shareText(CharSequence text) {
return shareText(text, "TEXT_TYPE");
}
/**
* 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 type type of data to encode. See {@code com.google.zxing.client.android.Contents.Type} constants.
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public void shareText(CharSequence text) {
public AlertDialog shareText(CharSequence text, CharSequence type) {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(BS_PACKAGE + ".ENCODE");
intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", text);
String targetAppPackage = findTargetAppPackage(intent);
if (targetAppPackage == null) {
showDownloadDialog();
} else {
intent.setPackage(targetAppPackage);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
activity.startActivity(intent);
return showDownloadDialog();
}
intent.setPackage(targetAppPackage);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intent);
activity.startActivity(intent);
return null;
}
private static Collection<String> list(String... values) {
return Collections.unmodifiableCollection(Arrays.asList(values));
}
private void attachMoreExtras(Intent intent) {
for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Kind of hacky
if (value instanceof Integer) {
intent.putExtra(key, (Integer) value);
} else if (value instanceof Long) {
intent.putExtra(key, (Long) value);
} else if (value instanceof Boolean) {
intent.putExtra(key, (Boolean) value);
} else if (value instanceof Double) {
intent.putExtra(key, (Double) value);
} else if (value instanceof Float) {
intent.putExtra(key, (Float) value);
} else if (value instanceof Bundle) {
intent.putExtra(key, (Bundle) value);
} else {
intent.putExtra(key, value.toString());
}
}
}
}

View file

@ -138,13 +138,12 @@ public final class ZXingTestActivity extends Activity {
private final Button.OnClickListener scanProduct = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
intent.putExtra("SCAN_WIDTH", 800);
intent.putExtra("SCAN_HEIGHT", 200);
intent.putExtra("RESULT_DISPLAY_DURATION_MS", 3000L);
intent.putExtra("PROMPT_MESSAGE", "Custom prompt to scan a product");
startActivityForResult(intent, IntentIntegrator.REQUEST_CODE);
IntentIntegrator integrator = new IntentIntegrator(ZXingTestActivity.this);
integrator.addExtra("SCAN_WIDTH", 800);
integrator.addExtra("SCAN_HEIGHT", 200);
integrator.addExtra("RESULT_DISPLAY_DURATION_MS", 3000L);
integrator.addExtra("PROMPT_MESSAGE", "Custom prompt to scan a product");
integrator.initiateScan(IntentIntegrator.PRODUCT_CODE_TYPES);
}
};
@ -227,11 +226,9 @@ public final class ZXingTestActivity extends Activity {
private final Button.OnClickListener encodeHiddenData = new Button.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
intent.putExtra("ENCODE_DATA", "SURPRISE!");
intent.putExtra("ENCODE_SHOW_CONTENTS", false);
startActivity(intent);
IntentIntegrator integrator = new IntentIntegrator(ZXingTestActivity.this);
integrator.addExtra("ENCODE_SHOW_CONTENTS", false);
integrator.shareText("SURPRISE!");
}
};
@ -257,18 +254,15 @@ public final class ZXingTestActivity extends Activity {
builder.show();
}
private void encodeBarcode(String type, String data) {
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", data);
startActivity(intent);
private void encodeBarcode(CharSequence type, CharSequence data) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.shareText(data, type);
}
private void encodeBarcode(String type, Bundle data) {
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", data);
startActivity(intent);
private void encodeBarcode(CharSequence type, Bundle data) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.addExtra("ENCODE_DATA", data);
integrator.shareText(data.toString(), type); // data.toString() isn't used
}
private static String getFlattenedParams() {