Android M权限:对shouldShowRequestPermissionRationale()函数的使用感到困惑

我正在翻阅关于Android m中新的权限模型的官方文档。它讨论了shouldShowRequestPermissionRationale()函数,如果应用程序之前请求此权限并且用户拒绝请求,该函数将返回true。如果用户在过去拒绝了权限请求并选择了Don't ask again选项,此方法将返回false

但是我们如何区分以下两种情况呢?

案例1:应用程序没有权限,用户之前没有被请求权限。在这种情况下,shouldShowRequestPermissionRationale()将返回false,因为这是我们第一次请求用户。

案例2:用户已经拒绝了权限并选择了“不要再问了”,在这种情况下shouldShowRequestPermissionRationale()将返回false。

我想把用户发送到案例2中的应用设置页面。我怎么微分这两种情况呢?

101384 次浏览

更新

我相信下面CanC的回答是正确的,应该遵循。唯一确定的方法是在onRequestPermissionResult回调中使用shouldShowPermissionRationale来验证这一点。

= =

我最初的回答是:

我发现的唯一方法是自己跟踪这是否是第一次(例如使用共享的偏好)。如果不是第一次,则使用shouldShowRequestPermissionRationale()进行区分。

也请参见:Android M -检查运行时权限-如何确定用户是否检查了“永不再问”?

我理解它的方式,shouldShowRequestPermissionRationale()在底层运行许多用例,并通知应用程序是否显示正在请求的权限的解释。

运行时权限背后的思想是,大多数情况下,用户将对权限请求说Yes。这样用户就只需要点击一次。当然,这个请求应该在正确的上下文中使用——即在按下“摄像”按钮时请求摄像许可。

如果用户拒绝请求,但经过一段时间后,再次按下“相机”按钮,shouldShowRequestPermissionRationale()将返回true,因此应用程序可以显示一些有意义的解释为什么请求权限,以及为什么应用程序将不能正常工作没有它。通常情况下,您将在该对话框窗口中显示一个按钮来再次拒绝/稍后决定,以及一个按钮来授予权限。原理对话框中的授予权限按钮,应该再次启动权限请求。这一次,用户还会看到一个“永不再次显示”复选框。如果他决定选择它,并再次拒绝权限,它将通知Android系统,用户和应用程序不在同一页面上。该操作将有两个后果- shouldShowRequestPermissionRationale()将总是返回false, requestPermissions()方法将不显示任何对话框,但将直接返回拒绝onRequestPermissionsResult回调。

但是还有另一种可能的场景,可以使用onRequestPermissionsResult。例如,一些设备可能有禁用摄像头的设备策略(为CIA、DARPA等工作)。在这些设备上,onRequestPermissionsResult将总是返回false,并且requestPermissions()方法将无声地拒绝请求。

这是我听Ben Poiesz的播客收集到的,Ben Poiesz是Android框架的产品经理 http://androidbackstage.blogspot.jp/2015/08/episode-33-permission-mission.html < / p >

在M Preview 1之后,如果对话框显示为第一次,则没有不要再问了复选框。

如果用户拒绝权限请求,在权限对话框中会有一个不要再问了复选框。

所以逻辑应该是这样的:

  1. < p >请求许可:

    if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
    } else {
    //Do the stuff that requires permission...
    }
    
  2. Check if the permission was denied or granted in onRequestPermissionsResult.

    If the permission was denied previously, this time there will be a Never ask again checkbox in the permission dialog.

    Call shouldShowRequestPermissionRationale to see if the user checked Never ask again. shouldShowRequestPermissionRationale method returns false only if the user selected Never ask again or device policy prohibits the app from having that permission:

    if (grantResults.length > 0){
    if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    //Do the stuff that requires permission...
    }else if (grantResults[0] == PackageManager.PERMISSION_DENIED){
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
    //Show permission explanation dialog...
    }else{
    //Never ask again selected, or device policy prohibits the app from having that permission.
    //So, disable that feature, or fall back to another situation...
    }
    }
    }
    

So, you won't have to track if a user checked Never ask again or not.

可能对某人有用:——

我注意到的是,如果我们在onRequestPermissionsResult()回调方法中检查shouldshowrequestpermissionration理()标志,它只显示两种状态。

状态1:-返回true:——任何时候用户单击Deny permissions(包括第一次)。

状态2:-返回false:-如果用户选择“永不再问”。

链接到详细的工作示例

我也遇到过同样的问题,但我解决了。为了简化工作,我编写了一个util类来处理运行时权限。

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();
}
}

PreferenceUtil方法如下所示。

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);
}

现在,你所需要的就是使用方法checkPermission和适当的参数。

举个例子,

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();
}
});

情况1:应用程序没有权限,用户也没有权限 要求之前的许可。在这种情况下, shouldShowRequestPermissionRationale()将返回false 我们第一次问用户。

情况2:用户拒绝权限并选择“不要问” 再次”,在这种情况下,太shouldShowRequestPermissionRationale()将 返回false。< / p > 我想在情况2中将用户发送到应用程序的设置页面。 我怎么微分这两种情况呢?< / p >

对于情况1,你会得到onPermissionAsk上的回调,对于情况2,你会得到onPermissionDisabled上的回调。

快乐编码:)

如果有人喜欢,就发布另一种选择。你可以使用谷歌本身提供的EasyPermissions,如前所述,“简化Android M系统权限”。

然后你不必直接处理shouldShowRequestPermissionRationale

检查这个实现。对我来说还不错。基本上你在checkPermissions()方法中检查权限,传递一个权限列表。在onRequestPermissionsResult()上检查权限请求的结果。实现让你解决两种情况下,当用户选择“永不再问”或不。在这个实现中,如果se选择“never ask again”,对话框有一个选项将他带到应用程序设置活动。

所有这些代码都在我的片段中。我认为最好创建一个专门的类来做这件事,比如PermissionManager,但我不确定。

/**
* responsible for checking if permissions are granted. In case permissions are not granted, the user will be requested and the method returns false. In case we have all permissions, the method return true.
* The response of the request for the permissions is going to be handled in the onRequestPermissionsResult() method
* @param permissions list of permissions to be checked if are granted onRequestPermissionsResult().
* @param requestCode request code to identify this request in
* @return true case we already have all permissions. false in case we had to prompt the user for it.
*/
private boolean checkPermissions(List<String> permissions, int requestCode) {
List<String> permissionsNotGranted = new ArrayList<>();
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED)
permissionsNotGranted.add(permission);
}


//If there is any permission we don't have (it's going to be in permissionsNotGranted List) , we need to request.
if (!permissionsNotGranted.isEmpty()) {
requestPermissions(permissionsNotGranted.toArray(new String[permissionsNotGranted.size()]), requestCode);
return false;
}
return true;
}


/**
* called after permissions are requested to the user. This is called always, either
* has granted or not the permissions.
* @param requestCode  int code used to identify the request made. Was passed as parameter in the
*                     requestPermissions() call.
* @param permissions  Array containing the permissions asked to the user.
* @param grantResults Array containing the results of the permissions requested to the user.
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case YOUR_REQUEST_CODE: {
boolean anyPermissionDenied = false;
boolean neverAskAgainSelected = false;
// Check if any permission asked has been denied
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
anyPermissionDenied = true;
//check if user select "never ask again" when denying any permission
if (!shouldShowRequestPermissionRationale(permissions[i])) {
neverAskAgainSelected = true;
}
}
}
if (!anyPermissionDenied) {
// All Permissions asked were granted! Yey!
// DO YOUR STUFF
} else {
// the user has just denied one or all of the permissions
// use this message to explain why he needs to grant these permissions in order to proceed
String message = "";
DialogInterface.OnClickListener listener = null;
if (neverAskAgainSelected) {
//This message is displayed after the user has checked never ask again checkbox.
message = getString(R.string.permission_denied_never_ask_again_dialog_message);
listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//this will be executed if User clicks OK button. This is gonna take the user to the App Settings
startAppSettingsConfigActivity();
}
};
} else {
//This message is displayed while the user hasn't checked never ask again checkbox.
message = getString(R.string.permission_denied_dialog_message);
}
new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme)
.setMessage(message)
.setPositiveButton(getString(R.string.label_Ok), listener)
.setNegativeButton(getString(R.string.label_cancel), null)
.create()
.show();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}


/**
* start the App Settings Activity so that the user can change
* settings related to the application such as permissions.
*/
private void startAppSettingsConfigActivity() {
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + getActivity().getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
getActivity().startActivity(i);
}
这段代码要求用户在运行时请求权限, 如果用户允许,执行结果方法, 如果用户拒绝,它会用描述和用户拒绝再次询问(它会用说明再次询问), 但如果用户选择永远不会再问。 它处理永不再问,显示打开的设置选项,并附有说明
public String storagePermissions = Manifest.permission.READ_EXTERNAL_STORAGE;
private static final int REQUEST_ACCESS =101;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


setContentView(R.layout.activity_main);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(storagePermissions)== PackageManager.PERMISSION_GRANTED){
result();    // result  is your block of code
}else {
requestPermissions(new String[]{storagePermissions},REQUEST_ACCESS);
}


}
else{
result();    //so if user is lower than api verison M, no permission is requested
}


}


private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setTitle("Hi User..")
.setPositiveButton("Ok", okListener)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {        //idea calling showMessage funtion again
Snackbar mySnackbar = Snackbar.make( findViewById(R.id.coordinatorlayout),"You Press Cancel.. ", Snackbar.LENGTH_INDEFINITE);
mySnackbar.setAction("Exit", new cancelButton());
mySnackbar.show();


}
})
.create()
.show();
}




private void result(){
//your code
}


@RequiresApi(api = Build.VERSION_CODES.M)
public class NeverAskAgain implements View.OnClickListener{
@Override
public void onClick(View view)
{
goToSettings();
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void goToSettings() {
Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
finish();
myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(myAppSettings, REQUEST_APP_SETTINGS);
}
public class cancelButton implements View.OnClickListener{
@Override
public void onClick(View view){
Toast.makeText(MainActivity.this,"To use this app , you must grant storage permission",Toast.LENGTH_SHORT);
finish();
}
}




@Override
@RequiresApi(api = Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode,permissions,grantResults);


switch(requestCode) {
case REQUEST_ACCESS:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission is granted
result();
break;
}
else if (!shouldShowRequestPermissionRationale(permissions[0])){
showMessageOKCancel("You choose Never Ask Again,option",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Snackbar mySnackbar = Snackbar.make(findViewById(R.id.coordinatorlayout), "Permission=>Storage=>On", Snackbar.LENGTH_INDEFINITE);
mySnackbar.setAction("Settings", new NeverAskAgain());
mySnackbar.show();
}
});
break;
}
else {
showMessageOKCancel("You Denid permission Request..",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{storagePermissions}, REQUEST_ACCESS);
}
});
break;
}
}
}

我们可以这样做吗?

@Retention(RetentionPolicy.SOURCE)
@IntDef({GRANTED, DENIED, NEVER})
public @interface PermissionStatus {
}


public static final int GRANTED = 0;
public static final int DENIED = 1;
public static final int NEVER = 2;


@PermissionStatus
public static int getPermissionStatus(Activity activity, String permission) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
return DENIED;
} else {
if (ActivityCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED) {
return GRANTED;
} else {
return NEVER;
}
}
}

如果有人对Kotlin解决方案感兴趣,我将@muthuraj的答案重构为Kotlin。它也现代化了一点,有一个完成块,而不是监听器。

PermissionUtil

object PermissionUtil {
private val PREFS_FILE_NAME = "preference"


fun firstTimeAskingPermission(context: Context, permission: String, isFirstTime: Boolean) {
val sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE)
sharedPreference.preferences.edit().putBoolean(permission,
isFirstTime).apply()
}


fun isFirstTimeAskingPermission(context: Context, permission: String): Boolean {
val sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE)
return sharedPreference.preferences.getBoolean(permission,
true)
}
}

PermissionHandler

enum class CheckPermissionResult {
PermissionAsk,
PermissionPreviouslyDenied,
PermissionDisabled,
PermissionGranted
}


typealias PermissionCheckCompletion = (CheckPermissionResult) -> Unit




object PermissionHandler {


private fun shouldAskPermission(context: Context, permission: String): Boolean {
return ContextCompat.checkSelfPermission(context,
permission) != PackageManager.PERMISSION_GRANTED
}


fun checkPermission(context: Context, permission: String, completion: PermissionCheckCompletion) {
// If permission is not granted
if (shouldAskPermission(context, permission)) {
//If permission denied previously
if ((context as Activity).shouldShowRequestPermissionRationale(permission)) {
completion(CheckPermissionResult.PermissionPreviouslyDenied)
} else {
// Permission denied or first time requested
if (PermissionUtil.isFirstTimeAskingPermission(context,
permission)) {
PermissionUtil.firstTimeAskingPermission(context,
permission,
false)
completion(CheckPermissionResult.PermissionAsk)
} else {
// Handle the feature without permission or ask user to manually allow permission
completion(CheckPermissionResult.PermissionDisabled)
}
}
} else {
completion(CheckPermissionResult.PermissionGranted)
}
}
}

实现

PermissionHandler.checkPermission(activity,
Manifest.permission.CAMERA) { result ->
when (result) {
CheckPermissionResult.PermissionGranted -> {
// openCamera()
}
CheckPermissionResult.PermissionDisabled -> {
// displayAlert(noPermissionAlert)
}
CheckPermissionResult.PermissionAsk -> {
// requestCameraPermissions()
}
CheckPermissionResult.PermissionPreviouslyDenied -> {
// displayAlert(permissionRequestAlert)
}
}
}
public void requestPermission(View view){
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
if(ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)){


//The Alert Dialog before asking for the second time to help the user understand  why he needs to give permission.


AlertDialog alert = new AlertDialog.Builder(this).setMessage("Without the permissions you cannot run the application")
.setCancelable(false)
.setPositiveButton("Okay, I understand", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION);
}
}).setNegativeButton("No, Exit the App", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(2);
}
}).create();
alert.setTitle("ALERTY");
alert.show();
//End of the alert Dialog
}
else{
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION);
}
}
else {
textView.setText("Permission Is Already Granted");
}
}
/*
The shouldShowRequestPermissionRationale() function returns true if the app has requested this permission
previously and the user denied the request.If the user turned down the permission request in the past and chose
the Don't ask again option, this method returns false.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == REQUEST_FINE_LOCATION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
textView.setText("Hooray! on Request Permissions Granted");
}
else{
//Since the user has chosen the don't ask again option,
if(!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)){


//Alert Dialog that will take user to settings where he can manually give the permissions
AlertDialog alert = new AlertDialog.Builder(this).setMessage("You have permanently disabled the permission ")
.setPositiveButton("Go to Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
openSettings();
}
}).setNegativeButton("Don't Go",null).setCancelable(false).create();
alert.setTitle("Give permission manually");
alert.show();
// End of the Alert Dialog
}
else{
textView.setText("Permission has been denied the 1st time");
}
}
}
}

这是openSettings方法。

    public void openSettings(){
Intent intent = new Intent();


Uri uri = Uri.fromParts("package",this.getPackageName(),null);
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(uri);
startActivity(intent);
}

shouldShowRequestPermissionRationale的正确用法是onRequestPermissionsResult

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:gravity="center">
    

<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Camera"
android:textAllCaps="false"
android:background="@color/purple_200"
android:layout_marginTop="20dp"
>
</androidx.appcompat.widget.AppCompatButton>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_storage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Storage"
android:textAllCaps="false"
android:background="@color/purple_200"
android:layout_marginTop="30dp"
>
</androidx.appcompat.widget.AppCompatButton>
    

</androidx.appcompat.widget.LinearLayoutCompat>
enter code here

MainActivity.kt

package com.example.myapplication
import android.Manifest
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
private val TAG = "MainActivity"
lateinit var btnCamera: Button
private val cameraRequestCode = 100
lateinit var btnStorage: Button
private val storageRequestCode = 200
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnCamera = findViewById(R.id.btn_camera)
btnStorage = findViewById(R.id.btn_storage)
btnCamera.setOnClickListener {
checkPermission(android.Manifest.permission.CAMERA, cameraRequestCode)
}
btnStorage.setOnClickListener {
checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE, storageRequestCode)
}
}


private fun checkPermission(permissionName: String, requestCode: Int) {
/**
* if the permission is given means it will give the  permissionNumber = 0
* if the permission is not  given means it will give the  permissionNumber =-1
* It s same as we are checking for PackageManager.PERMISSION_DENIED =-1 & PackageManager.GRANTED=0
*/
val permissionNumber: Int =
ContextCompat.checkSelfPermission(this@MainActivity, permissionName)
if (permissionNumber == PackageManager.PERMISSION_GRANTED) {


} else if (permissionNumber == PackageManager.PERMISSION_DENIED) {
askpermission(permissionName, requestCode, permissionNumber)


}


}


private fun askpermission(permissionName: String, permissionCode: Int, permissionNumner: Int) {
ActivityCompat.requestPermissions(
this@MainActivity,
arrayOf(permissionName),
permissionCode
)
}


override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == cameraRequestCode) {
if (permissions.size > 0) {
if (permissions[0].toString().equals(Manifest.permission.CAMERA, ignoreCase = true)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(applicationContext,"Permission Granted",Toast.LENGTH_SHORT).show()


}else{
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
var permissionDeniedStatus= checkDeniedPermissionStatus(permissions[0]);
if(permissionDeniedStatus){
/**
* Permission Denied
*/
Toast.makeText(applicationContext,"Permission Denied",Toast.LENGTH_SHORT).show()
}else{
/**
* Permission Denied and Selected Don t ask again.
*/
showDialog("Permission Denied","Permission Denied Permanently\nOpen Setting to allow")
}
}
}
}
}
}else  if (requestCode == storageRequestCode) {
if(permissions[0].toString().equals(Manifest.permission.READ_EXTERNAL_STORAGE, ignoreCase = true)){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(applicationContext,"Permission Granted",Toast.LENGTH_SHORT).show()
}
}else{
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
var permissionDeniedStatus= checkDeniedPermissionStatus(permissions[0]);
if(permissionDeniedStatus){
/**
* Permission Denied
*/
Toast.makeText(applicationContext,"Permission Denied",Toast.LENGTH_SHORT).show()
}else{
/**
* Permission Denied and Selected Don t ask again.
*/
showDialog("Permission Denied","Permission Denied Permanently\nOpen Setting to allow")
}
}
}
}
}
}


private fun checkDeniedPermissionStatus(permissionName: String) :Boolean{
val permissionDeniedStatus: Boolean = ActivityCompat.shouldShowRequestPermissionRationale(this@MainActivity, permissionName)
return permissionDeniedStatus
}


private fun showDialog(title: String, message: String) {
val builder = AlertDialog.Builder(this)
builder.setTitle(title)
builder.setMessage(message)
builder.setPositiveButton(android.R.string.yes) { dialog, which ->


}


builder.setNegativeButton(android.R.string.no) { dialog, which ->


}
builder.show()
}
}