mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 13:19:52 +01:00
Factor out permission related code from KeyAgreementActivity to AddNearbyContactPermissionManager
This commit is contained in:
@@ -0,0 +1,154 @@
|
|||||||
|
package org.briarproject.briar.android.contact.add.nearby;
|
||||||
|
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||||
|
import static android.Manifest.permission.CAMERA;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.getGoToSettingsListener;
|
||||||
|
|
||||||
|
class AddNearbyContactPermissionManager {
|
||||||
|
|
||||||
|
private enum Permission {
|
||||||
|
UNKNOWN, GRANTED, SHOW_RATIONALE, PERMANENTLY_DENIED
|
||||||
|
}
|
||||||
|
|
||||||
|
private Permission cameraPermission = Permission.UNKNOWN;
|
||||||
|
private Permission locationPermission = Permission.UNKNOWN;
|
||||||
|
|
||||||
|
private final BaseActivity ctx;
|
||||||
|
private final boolean isBluetoothSupported;
|
||||||
|
|
||||||
|
AddNearbyContactPermissionManager(BaseActivity ctx,
|
||||||
|
boolean isBluetoothSupported) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.isBluetoothSupported = isBluetoothSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetPermissions() {
|
||||||
|
cameraPermission = Permission.UNKNOWN;
|
||||||
|
locationPermission = Permission.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean areEssentialPermissionsGranted() {
|
||||||
|
return cameraPermission == Permission.GRANTED &&
|
||||||
|
(SDK_INT < 23 || locationPermission == Permission.GRANTED ||
|
||||||
|
!isBluetoothSupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkPermissions() {
|
||||||
|
if (areEssentialPermissionsGranted()) return true;
|
||||||
|
// If an essential permission has been permanently denied, ask the
|
||||||
|
// user to change the setting
|
||||||
|
if (cameraPermission == Permission.PERMANENTLY_DENIED) {
|
||||||
|
showDenialDialog(R.string.permission_camera_title,
|
||||||
|
R.string.permission_camera_denied_body);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isBluetoothSupported &&
|
||||||
|
locationPermission == Permission.PERMANENTLY_DENIED) {
|
||||||
|
showDenialDialog(R.string.permission_location_title,
|
||||||
|
R.string.permission_location_denied_body);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Should we show the rationale for one or both permissions?
|
||||||
|
if (cameraPermission == Permission.SHOW_RATIONALE &&
|
||||||
|
locationPermission == Permission.SHOW_RATIONALE) {
|
||||||
|
showRationale(R.string.permission_camera_location_title,
|
||||||
|
R.string.permission_camera_location_request_body);
|
||||||
|
} else if (cameraPermission == Permission.SHOW_RATIONALE) {
|
||||||
|
showRationale(R.string.permission_camera_title,
|
||||||
|
R.string.permission_camera_request_body);
|
||||||
|
} else if (locationPermission == Permission.SHOW_RATIONALE) {
|
||||||
|
showRationale(R.string.permission_location_title,
|
||||||
|
R.string.permission_location_request_body);
|
||||||
|
} else {
|
||||||
|
requestPermissions();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDenialDialog(@StringRes int title, @StringRes int body) {
|
||||||
|
AlertDialog.Builder builder =
|
||||||
|
new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
|
||||||
|
builder.setTitle(title);
|
||||||
|
builder.setMessage(body);
|
||||||
|
builder.setPositiveButton(R.string.ok, getGoToSettingsListener(ctx));
|
||||||
|
builder.setNegativeButton(R.string.cancel,
|
||||||
|
(dialog, which) -> ctx.supportFinishAfterTransition());
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showRationale(@StringRes int title, @StringRes int body) {
|
||||||
|
AlertDialog.Builder builder =
|
||||||
|
new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
|
||||||
|
builder.setTitle(title);
|
||||||
|
builder.setMessage(body);
|
||||||
|
builder.setNeutralButton(R.string.continue_button,
|
||||||
|
(dialog, which) -> requestPermissions());
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestPermissions() {
|
||||||
|
String[] permissions;
|
||||||
|
if (isBluetoothSupported) {
|
||||||
|
permissions = new String[] {CAMERA, ACCESS_FINE_LOCATION};
|
||||||
|
} else {
|
||||||
|
permissions = new String[] {CAMERA};
|
||||||
|
}
|
||||||
|
ActivityCompat.requestPermissions(ctx, permissions,
|
||||||
|
REQUEST_PERMISSION_CAMERA_LOCATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onRequestPermissionsResult(int requestCode, String[] permissions,
|
||||||
|
int[] grantResults, Runnable onPermissionsGranted) {
|
||||||
|
if (requestCode != REQUEST_PERMISSION_CAMERA_LOCATION)
|
||||||
|
throw new AssertionError();
|
||||||
|
if (gotPermission(CAMERA, permissions, grantResults)) {
|
||||||
|
cameraPermission = Permission.GRANTED;
|
||||||
|
} else if (shouldShowRationale(CAMERA)) {
|
||||||
|
cameraPermission = Permission.SHOW_RATIONALE;
|
||||||
|
} else {
|
||||||
|
cameraPermission = Permission.PERMANENTLY_DENIED;
|
||||||
|
}
|
||||||
|
if (isBluetoothSupported) {
|
||||||
|
if (gotPermission(ACCESS_FINE_LOCATION, permissions,
|
||||||
|
grantResults)) {
|
||||||
|
locationPermission = Permission.GRANTED;
|
||||||
|
} else if (shouldShowRationale(ACCESS_FINE_LOCATION)) {
|
||||||
|
locationPermission = Permission.SHOW_RATIONALE;
|
||||||
|
} else {
|
||||||
|
locationPermission = Permission.PERMANENTLY_DENIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If a permission dialog has been shown, showing the QR code fragment
|
||||||
|
// on this call path would cause a crash due to
|
||||||
|
// https://code.google.com/p/android/issues/detail?id=190966.
|
||||||
|
// In that case the isResumed flag prevents the fragment from being
|
||||||
|
// shown here, and showQrCodeFragmentIfAllowed() will be called again
|
||||||
|
// from onPostResume().
|
||||||
|
if (checkPermissions()) onPermissionsGranted.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean gotPermission(String permission, String[] permissions,
|
||||||
|
int[] grantResults) {
|
||||||
|
for (int i = 0; i < permissions.length; i++) {
|
||||||
|
if (permission.equals(permissions[i]))
|
||||||
|
return grantResults[i] == PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldShowRationale(String permission) {
|
||||||
|
return ActivityCompat
|
||||||
|
.shouldShowRequestPermissionRationale(ctx, permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,38 +21,25 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.StringRes;
|
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.appcompat.app.AlertDialog.Builder;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
|
||||||
import static android.Manifest.permission.CAMERA;
|
|
||||||
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
|
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
|
||||||
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
|
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION;
|
|
||||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.ACCEPTED;
|
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.ACCEPTED;
|
||||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.REFUSED;
|
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.REFUSED;
|
||||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.UNKNOWN;
|
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.UNKNOWN;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.getGoToSettingsListener;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public abstract class KeyAgreementActivity extends BriarActivity
|
public abstract class KeyAgreementActivity extends BriarActivity
|
||||||
implements BaseFragmentListener {
|
implements BaseFragmentListener {
|
||||||
|
|
||||||
private enum Permission {
|
|
||||||
UNKNOWN, GRANTED, SHOW_RATIONALE, PERMANENTLY_DENIED
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(KeyAgreementActivity.class.getName());
|
getLogger(KeyAgreementActivity.class.getName());
|
||||||
|
|
||||||
@@ -60,6 +47,7 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
protected ContactExchangeViewModel viewModel;
|
protected ContactExchangeViewModel viewModel;
|
||||||
|
private AddNearbyContactPermissionManager permissionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to true in onPostResume() and false in onPause(). This prevents the
|
* Set to true in onPostResume() and false in onPause(). This prevents the
|
||||||
@@ -68,9 +56,6 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
* https://issuetracker.google.com/issues/37067655.
|
* https://issuetracker.google.com/issues/37067655.
|
||||||
*/
|
*/
|
||||||
private boolean isResumed = false;
|
private boolean isResumed = false;
|
||||||
|
|
||||||
private Permission cameraPermission = Permission.UNKNOWN;
|
|
||||||
private Permission locationPermission = Permission.UNKNOWN;
|
|
||||||
private BroadcastReceiver bluetoothReceiver = null;
|
private BroadcastReceiver bluetoothReceiver = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,6 +63,8 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
component.inject(this);
|
component.inject(this);
|
||||||
viewModel = new ViewModelProvider(this, viewModelFactory)
|
viewModel = new ViewModelProvider(this, viewModelFactory)
|
||||||
.get(ContactExchangeViewModel.class);
|
.get(ContactExchangeViewModel.class);
|
||||||
|
permissionManager = new AddNearbyContactPermissionManager(this,
|
||||||
|
viewModel.isBluetoothSupported());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,7 +81,9 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
bluetoothReceiver = new BluetoothStateReceiver();
|
bluetoothReceiver = new BluetoothStateReceiver();
|
||||||
registerReceiver(bluetoothReceiver, filter);
|
registerReceiver(bluetoothReceiver, filter);
|
||||||
viewModel.getWasContinueClicked().observe(this, clicked -> {
|
viewModel.getWasContinueClicked().observe(this, clicked -> {
|
||||||
if (clicked && checkPermissions()) showQrCodeFragmentIfAllowed();
|
if (clicked && permissionManager.checkPermissions()) {
|
||||||
|
showQrCodeFragmentIfAllowed();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
viewModel.getTransportStateChanged().observeEvent(this,
|
viewModel.getTransportStateChanged().observeEvent(this,
|
||||||
t -> showQrCodeFragmentIfAllowed());
|
t -> showQrCodeFragmentIfAllowed());
|
||||||
@@ -107,8 +96,7 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
// Permissions may have been granted manually while we were stopped
|
// Permissions may have been granted manually while we were stopped
|
||||||
cameraPermission = Permission.UNKNOWN;
|
permissionManager.resetPermissions();
|
||||||
locationPermission = Permission.UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -126,11 +114,6 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
isResumed = false;
|
isResumed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
@@ -146,31 +129,29 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("StatementWithEmptyBody")
|
@Override
|
||||||
private void showQrCodeFragmentIfAllowed() {
|
public void onActivityResult(int request, int result,
|
||||||
boolean continueClicked = // never set to null
|
@Nullable Intent data) {
|
||||||
requireNonNull(viewModel.getWasContinueClicked().getValue());
|
if (request == REQUEST_BLUETOOTH_DISCOVERABLE) {
|
||||||
if (isResumed && continueClicked && areEssentialPermissionsGranted()) {
|
if (result == RESULT_CANCELED) {
|
||||||
if (viewModel.isWifiReady() && viewModel.isBluetoothReady()) {
|
LOG.info("Bluetooth discoverability was refused");
|
||||||
LOG.info("Wifi and Bluetooth are ready");
|
viewModel.bluetoothDecision = REFUSED;
|
||||||
viewModel.startAddingContact();
|
|
||||||
} else {
|
} else {
|
||||||
viewModel.enableWifiIfWeShould();
|
LOG.info("Bluetooth discoverability was accepted");
|
||||||
if (viewModel.bluetoothDecision == UNKNOWN) {
|
viewModel.bluetoothDecision = ACCEPTED;
|
||||||
requestBluetoothDiscoverable();
|
|
||||||
} else if (viewModel.bluetoothDecision == REFUSED) {
|
|
||||||
// Ask again when the user clicks "continue"
|
|
||||||
} else {
|
|
||||||
viewModel.enableBluetoothIfWeShould();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
showQrCodeFragmentIfAllowed();
|
||||||
|
} else super.onActivityResult(request, result, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean areEssentialPermissionsGranted() {
|
@Override
|
||||||
return cameraPermission == Permission.GRANTED &&
|
@UiThread
|
||||||
(SDK_INT < 23 || locationPermission == Permission.GRANTED ||
|
public void onRequestPermissionsResult(int requestCode,
|
||||||
!viewModel.isBluetoothSupported());
|
String[] permissions, int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions,
|
||||||
|
grantResults);
|
||||||
|
permissionManager.onRequestPermissionsResult(requestCode, permissions,
|
||||||
|
grantResults, this::showQrCodeFragmentIfAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestBluetoothDiscoverable() {
|
private void requestBluetoothDiscoverable() {
|
||||||
@@ -190,19 +171,27 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SuppressWarnings("StatementWithEmptyBody")
|
||||||
public void onActivityResult(int request, int result,
|
private void showQrCodeFragmentIfAllowed() {
|
||||||
@Nullable Intent data) {
|
boolean continueClicked = // never set to null
|
||||||
if (request == REQUEST_BLUETOOTH_DISCOVERABLE) {
|
requireNonNull(viewModel.getWasContinueClicked().getValue());
|
||||||
if (result == RESULT_CANCELED) {
|
boolean permissionsGranted =
|
||||||
LOG.info("Bluetooth discoverability was refused");
|
permissionManager.areEssentialPermissionsGranted();
|
||||||
viewModel.bluetoothDecision = REFUSED;
|
if (isResumed && continueClicked && permissionsGranted) {
|
||||||
|
if (viewModel.isWifiReady() && viewModel.isBluetoothReady()) {
|
||||||
|
LOG.info("Wifi and Bluetooth are ready");
|
||||||
|
viewModel.startAddingContact();
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Bluetooth discoverability was accepted");
|
viewModel.enableWifiIfWeShould();
|
||||||
viewModel.bluetoothDecision = ACCEPTED;
|
if (viewModel.bluetoothDecision == UNKNOWN) {
|
||||||
|
requestBluetoothDiscoverable();
|
||||||
|
} else if (viewModel.bluetoothDecision == REFUSED) {
|
||||||
|
// Ask again when the user clicks "continue"
|
||||||
|
} else {
|
||||||
|
viewModel.enableBluetoothIfWeShould();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showQrCodeFragmentIfAllowed();
|
}
|
||||||
} else super.onActivityResult(request, result, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showQrCodeFragment() {
|
private void showQrCodeFragment() {
|
||||||
@@ -217,118 +206,7 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkPermissions() {
|
|
||||||
if (areEssentialPermissionsGranted()) return true;
|
|
||||||
// If an essential permission has been permanently denied, ask the
|
|
||||||
// user to change the setting
|
|
||||||
if (cameraPermission == Permission.PERMANENTLY_DENIED) {
|
|
||||||
showDenialDialog(R.string.permission_camera_title,
|
|
||||||
R.string.permission_camera_denied_body);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (viewModel.isBluetoothSupported() &&
|
|
||||||
locationPermission == Permission.PERMANENTLY_DENIED) {
|
|
||||||
showDenialDialog(R.string.permission_location_title,
|
|
||||||
R.string.permission_location_denied_body);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Should we show the rationale for one or both permissions?
|
|
||||||
if (cameraPermission == Permission.SHOW_RATIONALE &&
|
|
||||||
locationPermission == Permission.SHOW_RATIONALE) {
|
|
||||||
showRationale(R.string.permission_camera_location_title,
|
|
||||||
R.string.permission_camera_location_request_body);
|
|
||||||
} else if (cameraPermission == Permission.SHOW_RATIONALE) {
|
|
||||||
showRationale(R.string.permission_camera_title,
|
|
||||||
R.string.permission_camera_request_body);
|
|
||||||
} else if (locationPermission == Permission.SHOW_RATIONALE) {
|
|
||||||
showRationale(R.string.permission_location_title,
|
|
||||||
R.string.permission_location_request_body);
|
|
||||||
} else {
|
|
||||||
requestPermissions();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showDenialDialog(@StringRes int title, @StringRes int body) {
|
|
||||||
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
|
||||||
builder.setTitle(title);
|
|
||||||
builder.setMessage(body);
|
|
||||||
builder.setPositiveButton(R.string.ok, getGoToSettingsListener(this));
|
|
||||||
builder.setNegativeButton(R.string.cancel,
|
|
||||||
(dialog, which) -> supportFinishAfterTransition());
|
|
||||||
builder.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showRationale(@StringRes int title, @StringRes int body) {
|
|
||||||
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
|
||||||
builder.setTitle(title);
|
|
||||||
builder.setMessage(body);
|
|
||||||
builder.setNeutralButton(R.string.continue_button,
|
|
||||||
(dialog, which) -> requestPermissions());
|
|
||||||
builder.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void requestPermissions() {
|
|
||||||
String[] permissions;
|
|
||||||
if (viewModel.isBluetoothSupported()) {
|
|
||||||
permissions = new String[] {CAMERA, ACCESS_FINE_LOCATION};
|
|
||||||
} else {
|
|
||||||
permissions = new String[] {CAMERA};
|
|
||||||
}
|
|
||||||
ActivityCompat.requestPermissions(this, permissions,
|
|
||||||
REQUEST_PERMISSION_CAMERA_LOCATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@UiThread
|
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
|
||||||
String[] permissions, int[] grantResults) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions,
|
|
||||||
grantResults);
|
|
||||||
if (requestCode != REQUEST_PERMISSION_CAMERA_LOCATION)
|
|
||||||
throw new AssertionError();
|
|
||||||
if (gotPermission(CAMERA, permissions, grantResults)) {
|
|
||||||
cameraPermission = Permission.GRANTED;
|
|
||||||
} else if (shouldShowRationale(CAMERA)) {
|
|
||||||
cameraPermission = Permission.SHOW_RATIONALE;
|
|
||||||
} else {
|
|
||||||
cameraPermission = Permission.PERMANENTLY_DENIED;
|
|
||||||
}
|
|
||||||
if (viewModel.isBluetoothSupported()) {
|
|
||||||
if (gotPermission(ACCESS_FINE_LOCATION, permissions,
|
|
||||||
grantResults)) {
|
|
||||||
locationPermission = Permission.GRANTED;
|
|
||||||
} else if (shouldShowRationale(ACCESS_FINE_LOCATION)) {
|
|
||||||
locationPermission = Permission.SHOW_RATIONALE;
|
|
||||||
} else {
|
|
||||||
locationPermission = Permission.PERMANENTLY_DENIED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If a permission dialog has been shown, showing the QR code fragment
|
|
||||||
// on this call path would cause a crash due to
|
|
||||||
// https://code.google.com/p/android/issues/detail?id=190966.
|
|
||||||
// In that case the isResumed flag prevents the fragment from being
|
|
||||||
// shown here, and showQrCodeFragmentIfAllowed() will be called again
|
|
||||||
// from onPostResume().
|
|
||||||
if (checkPermissions()) showQrCodeFragmentIfAllowed();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean gotPermission(String permission, String[] permissions,
|
|
||||||
int[] grantResults) {
|
|
||||||
for (int i = 0; i < permissions.length; i++) {
|
|
||||||
if (permission.equals(permissions[i]))
|
|
||||||
return grantResults[i] == PERMISSION_GRANTED;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean shouldShowRationale(String permission) {
|
|
||||||
return ActivityCompat.shouldShowRequestPermissionRationale(this,
|
|
||||||
permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
LOG.info("Bluetooth scan mode changed");
|
LOG.info("Bluetooth scan mode changed");
|
||||||
|
|||||||
Reference in New Issue
Block a user