在phonegap中通过二维码实现也是通过扩展phonegap的插件实现。
项目结构如下:
实现如下:
二维码扫码实现的插件类:
package com.easyway.barcode; import org.json.JSONArray; import org.json.JSONException; import android.app.Activity; import android.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import com.phonegap.api.PhonegapActivity; import com.phonegap.api.Plugin; import com.phonegap.api.PluginResult; /** * 扩展二维码扫描的phonegap类实现 * 实现原理如下: * 1.使用phonegap的js类库实现通过插件调用相关的Plugin java类。 * 2.plugin调用zxing相关的二维码扫码的方法实现。 * 3.如果调用zxing没有安装,到google下载相关的zxing apk安装,并调用对应的intent实现。 * * This calls out to the ZXing barcode reader and returns the result. */ public class BarcodeScanner extends Plugin { public static final int REQUEST_CODE = 0x0ba7c0de; public static final String defaultInstallTitle = "Install Barcode Scanner?"; public static final String defaultInstallMessage = "This requires the free Barcode Scanner app. Would you like to install it now?"; public static final String defaultYesString = "Yes"; public static final String defaultNoString = "No"; public String callback; /** * Constructor. */ public BarcodeScanner() { } /** * * 用于plugin相关的方法,用于暴露相关的方法使用。 * * Executes the request and returns PluginResult. * * @param action The action to execute. * @param args JSONArray of arguments for the plugin. * @param callbackId The callback id used when calling back into JavaScript. * @return A PluginResult object with a status and message. */ public PluginResult execute(String action, JSONArray args, String callbackId) { this.callback = callbackId; try { if (action.equals("encode")) { String type = null; if(args.length() > 0) { type = args.getString(0); } String data = null; if(args.length() > 1) { data = args.getString(1); } String installTitle = defaultInstallTitle; if(args.length() > 2) { installTitle = args.getString(2); } String installMessage = defaultInstallMessage; if(args.length() > 3) { installMessage = args.getString(3); } String yesString = defaultYesString; if(args.length() > 4) { yesString = args.getString(4); } String noString = defaultNoString; if(args.length() > 5) { noString = args.getString(5); } // if data.TypeOf() == Bundle, then call // encode(type, Bundle) // else // encode(type, String) this.encode(type, data, installTitle, installMessage, yesString, noString); } else if (action.equals("scan")) { String barcodeTypes = null; if(args.length() > 0) { barcodeTypes = args.getString(0); } String installTitle = defaultInstallTitle; if(args.length() > 1) { installTitle = args.getString(1); } String installMessage = defaultInstallMessage; if(args.length() > 2) { installMessage = args.getString(2); } String yesString = defaultYesString; if(args.length() > 3) { yesString = args.getString(3); } String noString = defaultNoString; if(args.length() > 4) { noString = args.getString(4); } scan(barcodeTypes, installTitle, installMessage, yesString, noString); } else { return new PluginResult(PluginResult.Status.INVALID_ACTION); } PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT); r.setKeepCallback(true); return r; } catch (JSONException e) { e.printStackTrace(); return new PluginResult(PluginResult.Status.JSON_EXCEPTION); } } /** * 扫描二维码的方法 * 备注:在扫描二维码的类型最好不好设置,在前期的zxing可能需要,在后期的版本中不需要, * zxing会自动检索二维码的类型,并识别相关二维码。 * * Initiates a barcode scan. If the ZXing scanner isn't installed, the user * will be prompted to install it. * @param types The barcode types to accept * @param installTitle The title for the dialog box that prompts the user to install the scanner * @param installMessage The message prompting the user to install the barcode scanner * @param yesString The string "Yes" or localised equivalent * @param noString The string "No" or localised version */ public void scan(String barcodeFormats, String installTitle, String installMessage, String yesString, String noString ) { Intent intentScan = new Intent("com.google.zxing.client.android.SCAN"); // intentScan.addCategory(Intent.CATEGORY_DEFAULT); //设置扫描特定类型的二维码 //if (barcodeFormats != null) { // Tell the scanner what types we're after // intentScan.putExtra("SCAN_FORMATS", barcodeFormats); // } try { this.ctx.startActivityForResult((Plugin) this, intentScan, REQUEST_CODE); } catch (ActivityNotFoundException e) { showDownloadDialog(installTitle, installMessage, yesString, noString); } } /** * 用于获取二维码扫描之后获取相关的二维码相关的信息 * Called when the barcode scanner exits * * @param requestCode The request code originally supplied to startActivityForResult(), * allowing you to identify who this result came from. * @param resultCode The integer result code returned by the child activity through its setResult(). * @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). */ public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { String contents = intent.getStringExtra("SCAN_RESULT"); String format = intent.getStringExtra("SCAN_RESULT_FORMAT"); this.success(new PluginResult(PluginResult.Status.OK, " 条形码为:"+contents+" 条码类型为: "+format), this.callback); } else { this.error(new PluginResult(PluginResult.Status.ERROR), this.callback); } } } /** * 创建相关的对话框,在通过没有安装相关的zxing开源组件时候,调用远程的intent或者下载相关执行类实现相关的 * 功能 * @param title * @param message * @param yesString * @param noString */ private void showDownloadDialog(final String title, final String message, final String yesString, final String noString) { final PhonegapActivity context = this.ctx; Runnable runnable = new Runnable() { public void run() { AlertDialog.Builder dialog = new AlertDialog.Builder(context); dialog.setTitle(title); dialog.setMessage(message); dialog.setPositiveButton(yesString, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dlg, int i) { dlg.dismiss(); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:com.google.zxing.client.android") ); try { context.startActivity(intent); } catch (ActivityNotFoundException e) { // We don't have the market app installed, so download it directly. Intent in = new Intent(Intent.ACTION_VIEW); in.setData(Uri.parse("http://zxing.googlecode.com/files/BarcodeScanner4.1.apk")); context.startActivity(in); } } }); dialog.setNegativeButton(noString, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dlg, int i) { dlg.dismiss(); } }); dialog.create(); dialog.show(); } }; context.runOnUiThread(runnable); } /** * * * Initiates a barcode encode. If the ZXing scanner isn't installed, the user * will be prompted to install it. * @param type The barcode type to encode * @param data The data to encode in the bar code * @param installTitle The title for the dialog box that prompts the user to install the scanner * @param installMessage The message prompting the user to install the barcode scanner * @param yesString The string "Yes" or localised equivalent * @param noString The string "No" or localised version */ public void encode(String type, String data, String installTitle, String installMessage, String yesString, String noString) { Intent intentEncode = new Intent("com.google.zxing.client.android.ENCODE"); intentEncode.putExtra("ENCODE_TYPE", type); intentEncode.putExtra("ENCODE_DATA", data); try { this.ctx.startActivity(intentEncode); } catch (ActivityNotFoundException e) { showDownloadDialog(installTitle, installMessage, yesString, noString); } } }
package com.easyway.barcode; import com.phonegap.*; import android.os.Bundle; /** * phonegap实现相关的二维码的扫码功能 * * @Title: * @Description: 实现phonegap实现相关的二维码的扫码功能 * @Copyright:Copyright (c) 2011 * @Company:易程科技股份有限公司 * @Date:2012-5-10 * @author longgangbai * @version 1.0 */ public class PhonegapBarcodeActivity extends DroidGap { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.loadUrl("file:///android_asset/www/index.html"); } }
二维码扫码实现的js:
/** * Phonegap Barcode Scanner plugin * Copyright (c) Matt Kane 2010 * */ var BarcodeScanner = function() { } BarcodeScanner.Type = { QR_CODE: "QR_CODE", DATA_MATRIX: "DATA_MATRIX", UPC_E: "UPC_E", UPC_A: "UPC_A", EAN_8: "EAN_8", EAN_13: "EAN_13", CODE_128: "CODE_128", CODE_39: "CODE_39", CODE_93: "CODE_93", CODABAR: "CODABAR", ITF: "ITF", RSS14: "RSS14", PDF417: "PDF417", RSS_EXPANDED: "RSS_EXPANDED", PRODUCT_CODE_TYPES: "UPC_A,UPC_E,EAN_8,EAN_13", ONE_D_CODE_TYPES: "UPC_A,UPC_E,EAN_8,EAN_13,CODE_39,CODE_93,CODE_128", QR_CODE_TYPES: "QR_CODE", ALL_CODE_TYPES: null } BarcodeScanner.Encode = { TEXT_TYPE: "TEXT_TYPE", EMAIL_TYPE: "EMAIL_TYPE", PHONE_TYPE: "PHONE_TYPE", SMS_TYPE: "SMS_TYPE", // CONTACT_TYPE: "CONTACT_TYPE", // TODO: not implemented, requires passing a Bundle class from Javascriopt to Java // LOCATION_TYPE: "LOCATION_TYPE" // TODO: not implemented, requires passing a Bundle class from Javascriopt to Java } //二维码扫描的方法 BarcodeScanner.prototype.scan = function(types, success, fail, options) { /* These are the strings used in the dialog that appears if ZXing isn't installed */ var installTitle = "Install Barcode Scanner?"; var installMessage = "This requires the free Barcode Scanner app. Would you like to install it now?"; var yesString = "Yes"; var noString = "No"; if (typeof options != 'undefined') { if(typeof options.installTitle != 'undefined') { installTitle = options.installTitle; } if(typeof options.installMessage != 'undefined') { installMessage = options.installMessage; } if(typeof options.yesString != 'undefined') { yesString = options.yesString; } if(typeof options.noString != 'undefined') { noString = options.noString; } } return PhoneGap.exec(function(args) { success(args); }, function(args) { fail(args); }, 'BarcodeScanner', 'scan', [types, installTitle, installMessage, yesString, noString]); }; BarcodeScanner.prototype.encode = function(type, data, success, fail, options) { /* These are the strings used in the dialog that appears if ZXing isn't installed */ var installTitle = "Install Barcode Scanner?"; var installMessage = "This requires the free Barcode Scanner app. Would you like to install it now?"; var yesString = "Yes"; var noString = "No"; if (typeof options != 'undefined') { if(typeof options.installTitle != 'undefined') { installTitle = options.installTitle; } if(typeof options.installMessage != 'undefined') { installMessage = options.installMessage; } if(typeof options.yesString != 'undefined') { yesString = options.yesString; } if(typeof options.noString != 'undefined') { noString = options.noString; } } return PhoneGap.exec(function(args) { success(args); }, function(args) { fail(args); }, 'BarcodeScanner', 'encode', [type, data, installTitle, installMessage, yesString, noString]); }; PhoneGap.addConstructor(function() { //如果不支持window.plugins,则创建并设置 if(!window.plugins){ window.plugins={}; } window.plugins.barcodeScanner=new BarcodeScanner(); //PhoneGap.addPlugin('barcodeScanner', new BarcodeScanner()); PluginManager.addService("BarcodeScanner","com.easyway.barcode.BarcodeScanner"); });
二维码调用的页面如下:
<!DOCTYPE HTML> <html> <head> <meta name="viewport" content="width=320; user-scalable=no" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>二维码扫描</title> <!-- 加载phonegap --> <script type="text/javascript" charset="utf-8" src="phonegap-1.4.1.js"></script> <!-- 加载jquery --> <script type="text/javascript" charset="utf-8" src="jquery.mobile/jquery-1.6.4.min"></script> <!-- 加载jquerymobile --> <script type="text/javascript" charset="utf-8" src="jquery.mobile/jquery.mobile-1.0.1.js"></script> <!-- 加载自定义插件 --> <script type="text/javascript" charset="utf-8" src="barcodescanner.js"></script> <script type="text/javascript" charset="utf-8"> $(function(){ $("#btnbarcode").click(function(){ window.plugins.barcodeScanner.scan( BarcodeScanner.Type.QR_CODE, function(result) { $("#barcodediv").html(""+result); }, function(error) { $("#barcodediv").html("扫描失败:"+result); }, { installTitle: "安装提示", installMessage:"是否安装开源免费的ZXing二维码扫描器", yesString:"确定", noString:"取消" } ); }); }); </script> </head> <body > <h2>二维码扫描</h2> <p>二维码信息:</p> <div id="barcodediv"></div> <input type="button" id="btnbarcode" value="扫描" /> </body> </html>
备注附件中phonegap的apk,下载之后需要重新命名为PhonegapBarcode.apk即可使用。