diff --git a/src/android/com/phonegap/plugins/barcodescanner/BarcodeScanner.java b/src/android/com/phonegap/plugins/barcodescanner/BarcodeScanner.java index bad6252f..b6aa7113 100644 --- a/src/android/com/phonegap/plugins/barcodescanner/BarcodeScanner.java +++ b/src/android/com/phonegap/plugins/barcodescanner/BarcodeScanner.java @@ -8,24 +8,21 @@ */ package com.phonegap.plugins.barcodescanner; -import com.google.zxing.client.android.Intents; - -import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import android.Manifest; import android.app.Activity; import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Build; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; import android.util.Log; +import android.content.pm.PackageManager; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CallbackContext; +import org.apache.cordova.PluginResult; +import org.apache.cordova.PermissionHelper; + +import android.util.Log; /** * This calls out to the ZXing barcode reader and returns the result. @@ -35,8 +32,6 @@ public class BarcodeScanner extends CordovaPlugin { public static final int REQUEST_CODE = 0x0ba7c0de; - private static final String REQUEST_CAMERA_PERMISSION = "requestCameraPermission"; - private static final String HAS_CAMERA_PERMISSION = "hasCameraPermission"; private static final String SCAN = "scan"; private static final String ENCODE = "encode"; private static final String CANCELLED = "cancelled"; @@ -60,6 +55,9 @@ public class BarcodeScanner extends CordovaPlugin { private static final String LOG_TAG = "BarcodeScanner"; + private String [] permissions = { Manifest.permission.CAMERA }; + + private JSONArray requestArgs; private CallbackContext callbackContext; /** @@ -87,6 +85,7 @@ public BarcodeScanner() { @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) { this.callbackContext = callbackContext; + this.requestArgs = args; if (action.equals(ENCODE)) { JSONObject obj = args.optJSONObject(0); @@ -110,74 +109,86 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo return true; } } else if (action.equals(SCAN)) { - scan(args.optJSONObject(0)); - } else if (action.equals(HAS_CAMERA_PERMISSION)) { - hasCameraPermission(); - } else if (action.equals(REQUEST_CAMERA_PERMISSION)) { - requestCameraPermission(); + + //android permission auto add + if(!hasPermisssion()) { + requestPermissions(0); + } else { + scan(args); + } } else { return false; } return true; } - public void hasCameraPermission() { - this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, cameraPermissionGranted())); - } - - private boolean cameraPermissionGranted() { - boolean hasPermission = Build.VERSION.SDK_INT < 23; // Android M. (6.0) - if (!hasPermission) { - hasPermission = PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this.cordova.getActivity(), Manifest.permission.CAMERA); - } - return hasPermission; - } - - public void requestCameraPermission() { - if (!cameraPermissionGranted()) { - ActivityCompat.requestPermissions( - this.cordova.getActivity(), - new String[]{Manifest.permission.CAMERA}, - 444); - } - // this method executes async and we seem to have no known way to receive the result, so simply returning ok now - this.callbackContext.success(); - } - - public void scan(final JSONObject obj) { - - // note that if the dev didn't call requestCameraPermission before scan and cameraPermissionGranted returns false, - // then the app will ask permission and the scan method needs to be invoked again (done for backward compat). - if (!cameraPermissionGranted()) { - requestCameraPermission(); - this.callbackContext.error("Please allow camera access and try again."); - return; - } + /** + * Starts an intent to scan and decode a barcode. + */ + public void scan(JSONArray args) { final CordovaPlugin that = this; cordova.getThreadPool().execute(new Runnable() { public void run() { + Intent intentScan = new Intent(SCAN_INTENT); intentScan.addCategory(Intent.CATEGORY_DEFAULT); - // avoid calling other apps using the same intent filter action - intentScan.setPackage(that.cordova.getActivity().getApplicationContext().getPackageName()); - - if (obj != null) { - intentScan.putExtra(Intents.Scan.CAMERA_ID, obj.optBoolean(PREFER_FRONTCAMERA, false) ? 1 : 0); - intentScan.putExtra(Intents.Scan.SHOW_FLIP_CAMERA_BUTTON, obj.optBoolean(SHOW_FLIP_CAMERA_BUTTON, false)); - if (obj.has(FORMATS)) { - intentScan.putExtra(Intents.Scan.FORMATS, obj.optString(FORMATS)); - } - if (obj.has(PROMPT)) { - intentScan.putExtra(Intents.Scan.PROMPT_MESSAGE, obj.optString(PROMPT)); - } - if (obj.has(ORIENTATION)) { - intentScan.putExtra(Intents.Scan.ORIENTATION_LOCK, obj.optString(ORIENTATION)); + + // add config as intent extras + if (args.length() > 0) { + + JSONObject obj; + JSONArray names; + String key; + Object value; + + for (int i = 0; i < args.length(); i++) { + + try { + obj = args.getJSONObject(i); + } catch (JSONException e) { + Log.i("CordovaLog", e.getLocalizedMessage()); + continue; + } + + names = obj.names(); + for (int j = 0; j < names.length(); j++) { + try { + key = names.getString(j); + value = obj.get(key); + + if (value instanceof Integer) { + intentScan.putExtra(key, (Integer) value); + } else if (value instanceof String) { + intentScan.putExtra(key, (String) value); + } + + } catch (JSONException e) { + Log.i("CordovaLog", e.getLocalizedMessage()); + continue; + } + } + + intentScan.putExtra(Intents.Scan.CAMERA_ID, obj.optBoolean(PREFER_FRONTCAMERA, false) ? 1 : 0); + intentScan.putExtra(Intents.Scan.SHOW_FLIP_CAMERA_BUTTON, obj.optBoolean(SHOW_FLIP_CAMERA_BUTTON, false)); + if (obj.has(FORMATS)) { + intentScan.putExtra(Intents.Scan.FORMATS, obj.optString(FORMATS)); + } + if (obj.has(PROMPT)) { + intentScan.putExtra(Intents.Scan.PROMPT_MESSAGE, obj.optString(PROMPT)); + } + if (obj.has(ORIENTATION)) { + intentScan.putExtra(Intents.Scan.ORIENTATION_LOCK, obj.optString(ORIENTATION)); + } } + } - that.cordova.startActivityForResult(that, intentScan, REQUEST_CODE); + // avoid calling other phonegap apps + intentScan.setPackage(this.cordova.getActivity().getApplicationContext().getPackageName()); + + this.cordova.startActivityForResult((CordovaPlugin) this, intentScan, REQUEST_CODE); } }); } @@ -237,4 +248,58 @@ public void encode(String type, String data) { this.cordova.getActivity().startActivity(intentEncode); } + + /** + * check application's permissions + */ + public boolean hasPermisssion() { + for(String p : permissions) + { + if(!PermissionHelper.hasPermission(this, p)) + { + return false; + } + } + return true; + } + + /** + * We override this so that we can access the permissions variable, which no longer exists in + * the parent class, since we can't initialize it reliably in the constructor! + * + * @param requestCode The code to get request action + */ + public void requestPermissions(int requestCode) + { + PermissionHelper.requestPermissions(this, requestCode, permissions); + } + + /** + * processes the result of permission request + * + * @param requestCode The code to get request action + * @param permissions The collection of permissions + * @param grantResults The result of grant + */ + public void onRequestPermissionResult(int requestCode, String[] permissions, + int[] grantResults) throws JSONException + { + PluginResult result; + for (int r : grantResults) { + if (r == PackageManager.PERMISSION_DENIED) { + Log.d(LOG_TAG, "Permission Denied!"); + result = new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION); + this.callbackContext.sendPluginResult(result); + return; + } + } + + switch(requestCode) + { + case 0: + scan(this.requestArgs); + break; + } + } + }