Tôi đã có cùng một vấn đề và tôi đã tìm ra nó. Để làm cho cuộc sống đơn giản hơn nhiều, tôi đã viết một lớp tiện dụng để xử lý các quyền thời gian chạy.
public class PermissionUtil {
/*
* Check if version is marshmallow and above.
* Used in deciding to ask runtime permission
* */
public static boolean shouldAskPermission() {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
}
private static boolean shouldAskPermission(Context context, String permission){
if (shouldAskPermission()) {
int permissionResult = ActivityCompat.checkSelfPermission(context, permission);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
public static void checkPermission(Context context, String permission, PermissionAskListener listener){
/*
* If permission is not granted
* */
if (shouldAskPermission(context, permission)){
/*
* If permission denied previously
* */
if (((Activity) context).shouldShowRequestPermissionRationale(permission)) {
listener.onPermissionPreviouslyDenied();
} else {
/*
* Permission denied or first time requested
* */
if (PreferencesUtil.isFirstTimeAskingPermission(context, permission)) {
PreferencesUtil.firstTimeAskingPermission(context, permission, false);
listener.onPermissionAsk();
} else {
/*
* Handle the feature without permission or ask user to manually allow permission
* */
listener.onPermissionDisabled();
}
}
} else {
listener.onPermissionGranted();
}
}
/*
* Callback on various cases on checking permission
*
* 1. Below M, runtime permission not needed. In that case onPermissionGranted() would be called.
* If permission is already granted, onPermissionGranted() would be called.
*
* 2. Above M, if the permission is being asked first time onPermissionAsk() would be called.
*
* 3. Above M, if the permission is previously asked but not granted, onPermissionPreviouslyDenied()
* would be called.
*
* 4. Above M, if the permission is disabled by device policy or the user checked "Never ask again"
* check box on previous request permission, onPermissionDisabled() would be called.
* */
public interface PermissionAskListener {
/*
* Callback to ask permission
* */
void onPermissionAsk();
/*
* Callback on permission denied
* */
void onPermissionPreviouslyDenied();
/*
* Callback on permission "Never show again" checked and denied
* */
void onPermissionDisabled();
/*
* Callback on permission granted
* */
void onPermissionGranted();
}
}
Và các phương pháp PreferenceUtil như sau.
public static void firstTimeAskingPermission(Context context, String permission, boolean isFirstTime){
SharedPreferences sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE;
sharedPreference.edit().putBoolean(permission, isFirstTime).apply();
}
public static boolean isFirstTimeAskingPermission(Context context, String permission){
return context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).getBoolean(permission, true);
}
Bây giờ, tất cả những gì bạn cần là sử dụng phương thức checkPermission với các đối số thích hợp.
Đây là một ví dụ,
PermissionUtil.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE,
new PermissionUtil.PermissionAskListener() {
@Override
public void onPermissionAsk() {
ActivityCompat.requestPermissions(
thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
REQUEST_EXTERNAL_STORAGE
);
}
@Override
public void onPermissionPreviouslyDenied() {
//show a dialog explaining permission and then request permission
}
@Override
public void onPermissionDisabled() {
Toast.makeText(context, "Permission Disabled.", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionGranted() {
readContacts();
}
});
Trường hợp 1: Ứng dụng không có quyền và người dùng chưa được yêu cầu quyền trước đó. Trong trường hợp này, nênShowRequestPermissionRationale () sẽ trả về false vì đây là lần đầu tiên chúng tôi hỏi người dùng.
Trường hợp 2: Người dùng đã từ chối quyền và chọn "Đừng hỏi lại", trong trường hợp này cũng vậy nênShowRequestPermissionRationale () sẽ trả về false.
Tôi muốn gửi người dùng đến trang cài đặt của Ứng dụng trong Trường hợp 2. Làm thế nào để tôi phân biệt hai trường hợp này?
Bạn sẽ nhận được cuộc gọi lại trên onPermissionAsk cho trường hợp 1 và onPermissionDisables cho trường hợp 2.
Chúc mừng mã hóa :)