Skip to content

Commit

Permalink
Camera permission behaviour (#505)
Browse files Browse the repository at this point in the history
* Remove unused else

* Remove SDK version check since we are on minimum 24 already

* Add intent key about missing camera permission

* Add boolean value to show error dialog

- always true for the beginning to keep current behaviour

* Make displaying an error dialog for missing camera permissions optional

* Add intent extras for Intent initialisation

* Initialise camera permission dialog visibility from Intent

* Add original intent to IntentResult

* Use original intent in IntentResult

* Make onRequestPermissionResult public again

* Forward onRequestPermissionResult

* React on Intent information

- for example on the missing camera permission

* Revert "Remove SDK version check since we are on minimum 24 already"

This reverts commit 8f79f56

* Add missing imports
  • Loading branch information
Andre Ippisch authored and rkistner committed Jan 7, 2020
1 parent 9b924e6 commit e0d3409
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 30 deletions.
8 changes: 8 additions & 0 deletions sample/src/main/java/example/zxing/CustomScannerActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import android.view.View;
import android.widget.Button;

import androidx.annotation.NonNull;

import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.journeyapps.barcodescanner.ViewfinderView;
Expand Down Expand Up @@ -45,6 +47,7 @@ protected void onCreate(Bundle savedInstanceState) {

capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.setShowMissingCameraPermissionDialog(false);
capture.decode();

changeMaskColor(null);
Expand Down Expand Up @@ -116,4 +119,9 @@ public void onTorchOn() {
public void onTorchOff() {
switchFlashlightButton.setText(R.string.turn_on_flashlight);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
10 changes: 8 additions & 2 deletions sample/src/main/java/example/zxing/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,14 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(resultCode, data);

if(result.getContents() == null) {
Log.d("MainActivity", "Cancelled scan");
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
Intent originalIntent = result.getOriginalIntent();
if (originalIntent == null) {
Log.d("MainActivity", "Cancelled scan");
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else if(originalIntent.hasExtra(Intents.Scan.MISSING_CAMERA_PERMISSION)) {
Log.d("MainActivity", "Cancelled scan due to missing camera permission");
Toast.makeText(this, "Cancelled due to missing camera permission", Toast.LENGTH_LONG).show();
}
} else {
Log.d("MainActivity", "Scanned");
Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ public static final class Scan {
*/
public static final String TIMEOUT = "TIMEOUT";

/**
* Set the time to finish the scan screen.
*/
public static final String MISSING_CAMERA_PERMISSION = "MISSING_CAMERA_PERMISSION";

/**
* Set the time to finish the scan screen.
*/
public static final String SHOW_MISSING_CAMERA_PERMISSION_DIALOG = "SHOW_MISSING_CAMERA_PERMISSION_DIALOG";

/**
* Set the time to finish the scan screen.
*/
public static final String MISSING_CAMERA_PERMISSION_DIALOG_MESSAGE = "MISSING_CAMERA_PERMISSION_DIALOG_MESSAGE";

/**
* Whether or not the orientation should be locked when the activity is first started.
* Defaults to true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,10 @@ public static IntentResult parseActivityResult(int resultCode, Intent intent) {
rawBytes,
orientation,
errorCorrectionLevel,
barcodeImagePath);
barcodeImagePath,
intent);
}
return new IntentResult();
return new IntentResult(intent);
}

private static List<String> list(String... values) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.google.zxing.integration.android;

import android.content.Intent;

/**
* <p>Encapsulates the result of a barcode scan invoked through {@link IntentIntegrator}.</p>
*
Expand All @@ -29,23 +31,30 @@ public final class IntentResult {
private final Integer orientation;
private final String errorCorrectionLevel;
private final String barcodeImagePath;
private final Intent originalIntent;

IntentResult() {
this(null, null, null, null, null, null);
this(null, null, null, null, null, null, null);
}

IntentResult(Intent intent) {
this(null, null, null, null, null, null, intent);
}

IntentResult(String contents,
String formatName,
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel,
String barcodeImagePath) {
String barcodeImagePath,
Intent originalIntent) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
this.barcodeImagePath = barcodeImagePath;
this.originalIntent = originalIntent;
}

/**
Expand Down Expand Up @@ -90,6 +99,13 @@ public String getBarcodeImagePath() {
return barcodeImagePath;
}

/**
* @return the original intent
*/
public Intent getOriginalIntent() {
return originalIntent;
}

@Override
public String toString() {
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
Expand All @@ -98,6 +114,7 @@ public String toString() {
"Raw bytes: (" + rawBytesLength + " bytes)\n" +
"Orientation: " + orientation + '\n' +
"EC level: " + errorCorrectionLevel + '\n' +
"Barcode image: " + barcodeImagePath + '\n';
"Barcode image: " + barcodeImagePath + '\n' +
"Original intent: " + originalIntent + '\n';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
Expand All @@ -13,14 +12,15 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.Window;
import android.view.WindowManager;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.zxing.ResultMetadataType;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.BeepManager;
Expand Down Expand Up @@ -61,6 +61,9 @@ public class CaptureManager {
private static final String SAVED_ORIENTATION_LOCK = "SAVED_ORIENTATION_LOCK";
private boolean returnBarcodeImagePath = false;

private boolean showDialogIfMissingCameraPermission = true;
private String missingCameraPermissionDialogMessage = "";

private boolean destroyed = false;

private InactivityTimer inactivityTimer;
Expand Down Expand Up @@ -103,7 +106,9 @@ public void previewStopped() {

@Override
public void cameraError(Exception error) {
displayFrameworkBugMessageAndExit();
displayFrameworkBugMessageAndExit(
activity.getString(R.string.zxing_msg_camera_framework_bug)
);
}

@Override
Expand Down Expand Up @@ -162,6 +167,13 @@ public void initializeFromIntent(Intent intent, Bundle savedInstanceState) {
beepManager.setBeepEnabled(false);
}

if (intent.hasExtra(Intents.Scan.SHOW_MISSING_CAMERA_PERMISSION_DIALOG)) {
setShowMissingCameraPermissionDialog(
intent.getBooleanExtra(Intents.Scan.SHOW_MISSING_CAMERA_PERMISSION_DIALOG, true),
intent.getStringExtra(Intents.Scan.MISSING_CAMERA_PERMISSION_DIALOG_MESSAGE)
);
}

if (intent.hasExtra(Intents.Scan.TIMEOUT)) {
handler.postDelayed(this::returnResultTimeout, intent.getLongExtra(Intents.Scan.TIMEOUT, 0L));
}
Expand Down Expand Up @@ -234,9 +246,7 @@ private void openCameraWithPermission() {
new String[]{Manifest.permission.CAMERA},
cameraPermissionReqCode);
askedPermission = true;
} else {
// Wait for permission result
}
} // else wait for permission result
}

/**
Expand All @@ -253,8 +263,13 @@ public void onRequestPermissionsResult(int requestCode, String permissions[], in
// permission was granted
barcodeView.resume();
} else {
// TODO: display better error message.
displayFrameworkBugMessageAndExit();
setMissingCameraPermissionResult();

if (showDialogIfMissingCameraPermission) {
displayFrameworkBugMessageAndExit(missingCameraPermissionDialogMessage);
} else {
closeAndFinish();
}
}
}
}
Expand Down Expand Up @@ -369,6 +384,12 @@ protected void closeAndFinish() {
inactivityTimer.cancel();
}

private void setMissingCameraPermissionResult() {
Intent intent = new Intent(Intents.Scan.ACTION);
intent.putExtra(Intents.Scan.MISSING_CAMERA_PERMISSION, true);
activity.setResult(Activity.RESULT_CANCELED, intent);
}

protected void returnResultTimeout() {
Intent intent = new Intent(Intents.Scan.ACTION);
intent.putExtra(Intents.Scan.TIMEOUT, true);
Expand All @@ -382,25 +403,20 @@ protected void returnResult(BarcodeResult rawResult) {
closeAndFinish();
}

protected void displayFrameworkBugMessageAndExit() {
protected void displayFrameworkBugMessageAndExit(String message) {
if (activity.isFinishing() || this.destroyed || finishWhenClosed) {
return;
}

if (message.isEmpty()) {
message = activity.getString(R.string.zxing_msg_camera_framework_bug);
}

AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(activity.getString(R.string.zxing_app_name));
builder.setMessage(activity.getString(R.string.zxing_msg_camera_framework_bug));
builder.setPositiveButton(R.string.zxing_button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
finish();
}
});
builder.setMessage(message);
builder.setPositiveButton(R.string.zxing_button_ok, (dialog, which) -> finish());
builder.setOnCancelListener(dialog -> finish());
builder.show();
}

Expand All @@ -411,4 +427,29 @@ public static int getCameraPermissionReqCode() {
public static void setCameraPermissionReqCode(int cameraPermissionReqCode) {
CaptureManager.cameraPermissionReqCode = cameraPermissionReqCode;
}

/**
* If set to true, shows the default error dialog if camera permission is missing.
* <p>
* If set to false, instead the capture manager just finishes.
* <p>
* In both cases, the activity result is set to {@link Intents.Scan#MISSING_CAMERA_PERMISSION}
* and cancelled
*/
public void setShowMissingCameraPermissionDialog(boolean visible) {
setShowMissingCameraPermissionDialog(visible, "");
}

/**
* If set to true, shows the specified error dialog message if camera permission is missing.
* <p>
* If set to false, instead the capture manager just finishes.
* <p>
* In both cases, the activity result is set to {@link Intents.Scan#MISSING_CAMERA_PERMISSION}
* and cancelled
*/
public void setShowMissingCameraPermissionDialog(boolean visible, String message) {
showDialogIfMissingCameraPermission = visible;
missingCameraPermissionDialogMessage = message != null ? message : "";
}
}

0 comments on commit e0d3409

Please sign in to comment.