Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Commit

Permalink
fix Android M permission
Browse files Browse the repository at this point in the history
  • Loading branch information
JrontEnd authored and EddyVerbruggen committed May 2, 2016
1 parent f0ad027 commit 29d3308
Showing 1 changed file with 127 additions and 62 deletions.
189 changes: 127 additions & 62 deletions src/android/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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";
Expand All @@ -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;

/**
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
});
}
Expand Down Expand Up @@ -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;
}
}

}

0 comments on commit 29d3308

Please sign in to comment.