/**
* Copyright (C) 2013 by Raphael Michel under the MIT license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software
* is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package de.geeksfactory.opacclient.barcode;
import android.app.Activity;
import android.support.v7.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import de.geeksfactory.opacclient.R;
import de.geeksfactory.opacclient.utils.CompatibilityUtils;
public class BarcodeScanIntegrator {
public static final int REQUEST_CODE_QRDROID = 0x0000094c;
public static final int REQUEST_CODE_ZXING = 0x0000094d;
private Activity ctx = null;
public BarcodeScanIntegrator(Activity ctx) {
this.ctx = ctx;
}
public static ScanResult parseActivityResult(int requestCode,
int resultCode, Intent idata) {
if (resultCode != Activity.RESULT_OK || idata == null
|| idata.getExtras() == null) {
return null;
}
if (requestCode == REQUEST_CODE_QRDROID) {
String result = idata.getExtras().getString("la.droid.qr.result");
return new ScanResult(result, null);
} else if (requestCode == REQUEST_CODE_ZXING) {
String contents = idata.getStringExtra("SCAN_RESULT");
String formatName = idata.getStringExtra("SCAN_RESULT_FORMAT");
return new ScanResult(contents, formatName);
} else {
return null;
}
}
private static Collection<String> list(String... values) {
return Collections.unmodifiableCollection(Arrays.asList(values));
}
public void initiateScan() {
PackageManager pm = ctx.getPackageManager();
// TODO: We should probably use PackageManager.getInstalledPackages() and iterate through
// all of them to avoid those try/catch-blocks
try {
pm.getPackageInfo("com.google.zxing.client.android", 0);
initiate_scan_zxing();
return;
} catch (NameNotFoundException e) {
}
try {
pm.getPackageInfo("com.srowen.bs.android", 0);
initiate_scan_zxing();
return;
} catch (NameNotFoundException e) {
}
try {
pm.getPackageInfo("com.srowen.bs.android.simple", 0);
initiate_scan_zxing();
return;
} catch (NameNotFoundException e) {
}
try {
pm.getPackageInfo("com.srowen.bs.android.simple", 0);
initiate_scan_zxing();
return;
} catch (NameNotFoundException e) {
}
try {
pm.getPackageInfo("la.droid.qr", 0);
initiate_scan_qrdroid();
return;
} catch (NameNotFoundException e) {
}
try {
pm.getPackageInfo("la.droid.qr.priva", 0);
initiate_scan_qrdroid();
return;
} catch (NameNotFoundException e) {
}
download_dialog();
}
public void download_dialog() {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(ctx);
downloadDialog.setTitle(R.string.barcode_title);
downloadDialog.setMessage(R.string.barcode_desc);
downloadDialog.setPositiveButton(R.string.barcode_gplay,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Uri uri = Uri
.parse("market://details?id=com.google.zxing.client.android");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
ctx.startActivity(intent);
} catch (ActivityNotFoundException anfe) {
// Hmm, market is not installed
}
}
});
downloadDialog.setNeutralButton(R.string.barcode_amazon,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Uri uri = Uri
.parse("http://www.amazon.com/gp/mas/dl/android?p=com.google" +
".zxing.client.android");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
ctx.startActivity(intent);
}
});
downloadDialog.setNegativeButton(R.string.no,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
AlertDialog alert = downloadDialog.create();
alert.show();
}
public void initiate_scan_zxing() {
/*final Collection<String> desiredBarcodeFormats = list("UPC_A", "UPC_E",
"EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128");*/
Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
/*if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
}*/
String targetAppPackage = findTargetAppPackage(intentScan);
if (targetAppPackage == null) {
download_dialog();
return;
}
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(CompatibilityUtils.getNewDocumentIntentFlag());
ctx.startActivityForResult(intentScan, REQUEST_CODE_ZXING);
}
private String findTargetAppPackage(Intent intent) {
final Collection<String> targetApplications = list(
"com.google.zxing.client.android", "com.srowen.bs.android",
"com.srowen.bs.android.simple");
PackageManager pm = ctx.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;
}
public void initiate_scan_qrdroid() {
Intent qrDroid = new Intent("la.droid.qr.scan");
qrDroid.putExtra("la.droid.qr.complete", true);
ctx.startActivityForResult(qrDroid, REQUEST_CODE_QRDROID);
}
public static class ScanResult {
private final String contents;
private final String formatName;
public ScanResult(String contents, String formatName) {
this.contents = contents;
this.formatName = formatName;
}
/**
* @return raw content of barcode
*/
public String getContents() {
return contents;
}
/**
* @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more
* format names.
*/
public String getFormatName() {
return formatName;
}
}
}