Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PermissionsUtil#requestPermissions(...) to provide the ability to request multiple permissions at a time #89260

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

Expand All @@ -67,12 +71,74 @@ private PermissionsUtil() {
}

/**
* Request a dangerous permission. name must be specified in <a href="https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml">this</a>
* @param permissionName the name of the requested permission.
* Request a list of dangerous permissions. The requested permissions must be included in the app's AndroidManifest
* @param permissions list of the permissions to request.
* @param activity the caller activity for this method.
* @return true/false. "true" if permissions are already granted, "false" if a permissions request was dispatched.
*/
public static boolean requestPermissions(Activity activity, List<String> permissions) {
if (activity == null) {
return false;
}

if (permissions == null || permissions.isEmpty()) {
return true;
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Not necessary, asked on install already
return true;
}

Set<String> requestedPermissions = new HashSet<>();
for (String permission : permissions) {
try {
if (permission.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
Log.d(TAG, "Requesting permission " + permission);
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse(String.format("package:%s", activity.getPackageName())));
activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
} catch (Exception ignored) {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
}
}
} else {
PermissionInfo permissionInfo = getPermissionInfo(activity, permission);
int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Requesting permission " + permission);
requestedPermissions.add(permission);
}
}
} catch (PackageManager.NameNotFoundException e) {
// Skip this permission and continue.
Log.w(TAG, "Unable to identify permission " + permission, e);
}
}

if (requestedPermissions.isEmpty()) {
// If list is empty, all of dangerous permissions were granted.
return true;
}

activity.requestPermissions(requestedPermissions.toArray(new String[0]), REQUEST_ALL_PERMISSION_REQ_CODE);
return true;
}

/**
* Request a dangerous permission. The requested permission must be included in the app's AndroidManifest
* @param permissionName the name of the permission to request.
* @param activity the caller activity for this method.
* @return true/false. "true" if permission is already granted, "false" if a permission request was dispatched.
*/
public static boolean requestPermission(String permissionName, Activity activity) {
if (activity == null || TextUtils.isEmpty(permissionName)) {
return false;
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Not necessary, asked on install already
return true;
Expand Down Expand Up @@ -137,60 +203,33 @@ public static boolean requestManifestPermissions(Activity activity) {
* @return true/false. "true" if all permissions were already granted, returns "false" if permissions requests were dispatched.
*/
public static boolean requestManifestPermissions(Activity activity, @Nullable Set<String> excludes) {
if (activity == null) {
return false;
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}

String[] manifestPermissions;
List<String> manifestPermissions;
try {
manifestPermissions = getManifestPermissions(activity);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}

if (manifestPermissions.length == 0)
if (manifestPermissions.isEmpty()) {
return true;

List<String> requestedPermissions = new ArrayList<>();
for (String manifestPermission : manifestPermissions) {
if (excludes != null && excludes.contains(manifestPermission)) {
continue;
}
try {
if (manifestPermission.equals(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
Log.d(TAG, "Requesting permission " + manifestPermission);
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse(String.format("package:%s", activity.getPackageName())));
activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
} catch (Exception ignored) {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
activity.startActivityForResult(intent, REQUEST_MANAGE_EXTERNAL_STORAGE_REQ_CODE);
}
}
} else {
PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Requesting permission " + manifestPermission);
requestedPermissions.add(manifestPermission);
}
}
} catch (PackageManager.NameNotFoundException e) {
// Skip this permission and continue.
Log.w(TAG, "Unable to identify permission " + manifestPermission, e);
}
}

if (requestedPermissions.isEmpty()) {
// If list is empty, all of dangerous permissions were granted.
return true;
if (excludes != null && !excludes.isEmpty()) {
for (String excludedPermission : excludes) {
manifestPermissions.remove(excludedPermission);
}
}

activity.requestPermissions(requestedPermissions.toArray(new String[0]), REQUEST_ALL_PERMISSION_REQ_CODE);
return false;
return requestPermissions(activity, manifestPermissions);
}

/**
Expand All @@ -199,15 +238,16 @@ public static boolean requestManifestPermissions(Activity activity, @Nullable Se
* @return granted permissions list
*/
public static String[] getGrantedPermissions(Context context) {
String[] manifestPermissions;
List<String> manifestPermissions;
try {
manifestPermissions = getManifestPermissions(context);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return new String[0];
}
if (manifestPermissions.length == 0)
return manifestPermissions;
if (manifestPermissions.isEmpty()) {
return new String[0];
}

List<String> grantedPermissions = new ArrayList<>();
for (String manifestPermission : manifestPermissions) {
Expand Down Expand Up @@ -256,12 +296,12 @@ public static boolean hasManifestPermission(Context context, String permission)
* @return manifest permissions list
* @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found.
*/
private static String[] getManifestPermissions(Context context) throws PackageManager.NameNotFoundException {
public static List<String> getManifestPermissions(Context context) throws PackageManager.NameNotFoundException {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
if (packageInfo.requestedPermissions == null)
return new String[0];
return packageInfo.requestedPermissions;
return Collections.emptyList();
return Arrays.asList(packageInfo.requestedPermissions);
}

/**
Expand Down
Loading