mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-28 21:33:53 +01:00
Android 13 permission related fixes (#5299)
* Android 13 permission related fixes * removes audio and video as permissions
This commit is contained in:
parent
f5770539a5
commit
6881158743
12 changed files with 162 additions and 125 deletions
|
|
@ -38,7 +38,7 @@ object DownloadUtils {
|
|||
}
|
||||
PermissionUtils.checkPermissionsAndPerformAction(
|
||||
activity,
|
||||
permission.WRITE_EXTERNAL_STORAGE,
|
||||
PermissionUtils.PERMISSIONS_STORAGE,
|
||||
{ enqueueRequest(activity, req) },
|
||||
{
|
||||
Toast.makeText(
|
||||
|
|
|
|||
|
|
@ -1,121 +1,143 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.karumi.dexter.Dexter;
|
||||
import com.karumi.dexter.MultiplePermissionsReport;
|
||||
import com.karumi.dexter.PermissionToken;
|
||||
import com.karumi.dexter.listener.PermissionDeniedResponse;
|
||||
import com.karumi.dexter.listener.PermissionGrantedResponse;
|
||||
import com.karumi.dexter.listener.PermissionRequest;
|
||||
import com.karumi.dexter.listener.single.BasePermissionListener;
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
|
||||
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.R;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class PermissionUtils {
|
||||
|
||||
public static String[] PERMISSIONS_STORAGE = isSDKVersionScopedStorageCompatible() ?
|
||||
isSDKVersionTiramisu() ? new String[]{
|
||||
Manifest.permission.READ_MEDIA_IMAGES} :
|
||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}
|
||||
: isSDKVersionTiramisu() ? new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_MEDIA_IMAGES}
|
||||
: new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE};
|
||||
|
||||
private static boolean isSDKVersionScopedStorageCompatible() {
|
||||
return Build.VERSION.SDK_INT > Build.VERSION_CODES.P;
|
||||
}
|
||||
|
||||
public static boolean isSDKVersionTiramisu() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be used by any activity which requires a permission which has been blocked(marked never ask again by the user)
|
||||
It open the app settings from where the user can manually give us the required permission.
|
||||
* This method can be used by any activity which requires a permission which has been
|
||||
* blocked(marked never ask again by the user) It open the app settings from where the user can
|
||||
* manually give us the required permission.
|
||||
*
|
||||
* @param activity
|
||||
*/
|
||||
private static void askUserToManuallyEnablePermissionFromSettings(Activity activity) {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
activity.startActivityForResult(intent,CommonsApplication.OPEN_APPLICATION_DETAIL_SETTINGS);
|
||||
activity.startActivityForResult(intent,
|
||||
CommonsApplication.OPEN_APPLICATION_DETAIL_SETTINGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the app already has a particular permission
|
||||
*
|
||||
* @param activity
|
||||
* @param permission permission to be checked
|
||||
* @param permissions permissions to be checked
|
||||
* @return
|
||||
*/
|
||||
public static boolean hasPermission(Activity activity, String permission) {
|
||||
return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
|
||||
|
||||
public static boolean hasPermission(Activity activity, String permissions[]) {
|
||||
boolean hasPermission = true;
|
||||
for (String permission : permissions
|
||||
) {
|
||||
hasPermission = hasPermission &&
|
||||
ContextCompat.checkSelfPermission(activity, permission)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
return hasPermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a particular permission and runs the runnable to perform an action when the permission is granted
|
||||
* Also, it shows a rationale if needed
|
||||
*
|
||||
* rationaleTitle and rationaleMessage can be invalid @StringRes. If the value is -1 then no permission rationale
|
||||
* will be displayed and permission would be requested
|
||||
*
|
||||
* Checks for a particular permission and runs the runnable to perform an action when the
|
||||
* permission is granted Also, it shows a rationale if needed
|
||||
* <p>
|
||||
* rationaleTitle and rationaleMessage can be invalid @StringRes. If the value is -1 then no
|
||||
* permission rationale will be displayed and permission would be requested
|
||||
* <p>
|
||||
* Sample usage:
|
||||
*
|
||||
* PermissionUtils.checkPermissionsAndPerformAction(activity,
|
||||
* Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
* () -> initiateCameraUpload(activity),
|
||||
* R.string.storage_permission_title,
|
||||
* R.string.write_storage_permission_rationale);
|
||||
*
|
||||
* <p>
|
||||
* PermissionUtils.checkPermissionsAndPerformAction(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
* () -> initiateCameraUpload(activity), R.string.storage_permission_title,
|
||||
* R.string.write_storage_permission_rationale);
|
||||
* <p>
|
||||
* If you don't want the permission rationale to be shown then use:
|
||||
* <p>
|
||||
* PermissionUtils.checkPermissionsAndPerformAction(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
* () -> initiateCameraUpload(activity), - 1, -1);
|
||||
*
|
||||
* PermissionUtils.checkPermissionsAndPerformAction(activity,
|
||||
* Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
* () -> initiateCameraUpload(activity),
|
||||
* - 1, -1);
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param activity activity requesting permissions
|
||||
* @param permission the permission being requests
|
||||
* @param activity activity requesting permissions
|
||||
* @param permissions the permissions array being requests
|
||||
* @param onPermissionGranted the runnable to be executed when the permission is granted
|
||||
* @param rationaleTitle rationale title to be displayed when permission was denied. It can be an invalid @StringRes
|
||||
* @param rationaleMessage rationale message to be displayed when permission was denied. It can be an invalid @StringRes
|
||||
* @param rationaleTitle rationale title to be displayed when permission was denied. It can
|
||||
* be an invalid @StringRes
|
||||
* @param rationaleMessage rationale message to be displayed when permission was denied. It
|
||||
* can be an invalid @StringRes
|
||||
*/
|
||||
public static void checkPermissionsAndPerformAction(Activity activity, String permission,
|
||||
public static void checkPermissionsAndPerformAction(Activity activity, String[] permissions,
|
||||
Runnable onPermissionGranted, @StringRes int rationaleTitle,
|
||||
@StringRes int rationaleMessage) {
|
||||
checkPermissionsAndPerformAction(activity, permission, onPermissionGranted, null,
|
||||
checkPermissionsAndPerformAction(activity, permissions, onPermissionGranted, null,
|
||||
rationaleTitle, rationaleMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a particular permission and runs the corresponding runnables to perform an action when the permission is granted/denied
|
||||
* Also, it shows a rationale if needed
|
||||
*
|
||||
* Checks for a particular permission and runs the corresponding runnables to perform an action
|
||||
* when the permission is granted/denied Also, it shows a rationale if needed
|
||||
* <p>
|
||||
* Sample usage:
|
||||
* <p>
|
||||
* PermissionUtils.checkPermissionsAndPerformAction(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
* () -> initiateCameraUpload(activity), () -> showMessage(), R.string.storage_permission_title,
|
||||
* R.string.write_storage_permission_rationale);
|
||||
*
|
||||
* PermissionUtils.checkPermissionsAndPerformAction(activity,
|
||||
* Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
* () -> initiateCameraUpload(activity),
|
||||
* () -> showMessage(),
|
||||
* R.string.storage_permission_title,
|
||||
* R.string.write_storage_permission_rationale);
|
||||
*
|
||||
*
|
||||
* @param activity activity requesting permissions
|
||||
* @param permission the permission being requests
|
||||
* @param activity activity requesting permissions
|
||||
* @param permissions the permissions array being requested
|
||||
* @param onPermissionGranted the runnable to be executed when the permission is granted
|
||||
* @param onPermissionDenied the runnable to be executed when the permission is denied(but not permanently)
|
||||
* @param rationaleTitle rationale title to be displayed when permission was denied
|
||||
* @param rationaleMessage rationale message to be displayed when permission was denied
|
||||
* @param onPermissionDenied the runnable to be executed when the permission is denied(but not
|
||||
* permanently)
|
||||
* @param rationaleTitle rationale title to be displayed when permission was denied
|
||||
* @param rationaleMessage rationale message to be displayed when permission was denied
|
||||
*/
|
||||
public static void checkPermissionsAndPerformAction(Activity activity, String permission,
|
||||
public static void checkPermissionsAndPerformAction(Activity activity, String[] permissions,
|
||||
Runnable onPermissionGranted, Runnable onPermissionDenied, @StringRes int rationaleTitle,
|
||||
@StringRes int rationaleMessage) {
|
||||
Dexter.withActivity(activity)
|
||||
.withPermission(permission)
|
||||
.withListener(new BasePermissionListener() {
|
||||
@Override public void onPermissionGranted(PermissionGrantedResponse response) {
|
||||
onPermissionGranted.run();
|
||||
}
|
||||
|
||||
@Override public void onPermissionDenied(PermissionDeniedResponse response) {
|
||||
if (response.isPermanentlyDenied()) {
|
||||
.withPermissions(permissions)
|
||||
.withListener(new MultiplePermissionsListener() {
|
||||
@Override
|
||||
public void onPermissionsChecked(MultiplePermissionsReport report) {
|
||||
if (report.areAllPermissionsGranted()) {
|
||||
onPermissionGranted.run();
|
||||
}
|
||||
if (report.isAnyPermissionPermanentlyDenied()) {
|
||||
// permission is denied permanently, we will show user a dialog message.
|
||||
DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle),
|
||||
activity.getString(rationaleMessage),
|
||||
activity.getString(R.string.navigation_item_settings), null,
|
||||
|
|
@ -128,7 +150,7 @@ public class PermissionUtils {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionRationaleShouldBeShown(PermissionRequest permission,
|
||||
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions,
|
||||
PermissionToken token) {
|
||||
if (rationaleTitle == -1 && rationaleMessage == -1) {
|
||||
token.continuePermissionRequest();
|
||||
|
|
@ -144,7 +166,7 @@ public class PermissionUtils {
|
|||
false);
|
||||
}
|
||||
})
|
||||
.onSameThread()
|
||||
.check();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue