如何*正确*请求权限?

How to *correctly* ask for permissions?

我正在开发一个 Android 应用程序,它在启动时需要 3 个权限。我必须等到用户在对话框中做出响应,否则应用程序会崩溃,因为权限是强制性的。

请求这些权限的正确方法是什么?我写了下面的代码,但应用程序在响应第一个权限(拒绝或接受)时冻结。

这是我做的:

    String[] perms = {"Manifest.permission.READ_PHONE_STATE", "Manifest.permission.ACCESS_COARSE_LOCATION","Manifest.permission.CALL_PHONE"};

    int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_PHONE_STATE);
    int result2 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION);
    int result3 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CALL_PHONE);

    if ((result1 == PackageManager.PERMISSION_GRANTED) && (result2 == PackageManager.PERMISSION_GRANTED) && (result3 == PackageManager.PERMISSION_GRANTED)) {
        onPermissionGranted();
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(perms, PERMISSION_REQUEST_CODE);
        } else {
            ActivityCompat.requestPermissions(this, perms, PERMISSION_REQUEST_CODE);
        }

    }

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                onPermissionGranted();
                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {
                Toast.makeText(MainActivity.this, R.string.permission_required, Toast.LENGTH_LONG).show();
                // permission denied, boo! Disable the
                // functionality that depends on this permission.


            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

最简单的方法是使用一些库。例如,您可以使用 TedPersmission。真的好用。

如果你想自己实现逻辑而不使用任何库,那么你应该请求许可,当许可已经granted/denied时有一个监听器(onRequestPermissionsResult),如果它被拒绝然后通知用户并且不要让他继续。如果被授予,则请求第二个权限,并让第二个侦听器查看用户是否授予此权限,依此类推,直到用户拥有 granted/denied 您需要的所有权限。

根据official docs请求权限首先检查是否授予权限:

if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.ACCESS_COARSE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
    // Permission is not granted
}

如果未获准请求:

ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);

最后使用此代码处理请求结果:

@Override
public void onRequestPermissionsResult(int requestCode,
        String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay!
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request.
    }
}

为了 android 获得权限,您需要进入 android 清单,然后添加您的权限

<uses-permission android:name="android.permission.INTERNET"/>

像这样

无需使用 Thread#sleep 或 while 循环进行阻塞,因为权限请求是异步的。以下是您的 Activity 应该如何流动:

首先,定义需要权限的逻辑,以便运行:

private void onPermissionGranted() {
   //code to execute
}

然后,在 onCreate() 中,检查您是否拥有这些权限。如果这样做,请执行您的代码。如果不这样做,请请求许可:

if (ContextCompat.checkSelfPermission(this,/*permissions*/) == PackageManager.PERMISSION_GRANTED) {
    onPermissionGranted();
} else {
   ActivityCompat.requestPermissions(this, /*permissions*/, /*request_code*/); 
}

权限状态更新后,它会调用 onRequestPermissionsResult。如果获得许可,则在此处执行操作。否则,请执行其他操作(重新显示对话框或完成 activity)。

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case /*our request code from before*/: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                onPermissionGranted();
            } else {
                Toast.makeText(this, "Permissions are required in order to run this app!", Toast.LENGTH_SHORT).show();
                finish();
            }
            return;
        }
    }
}

转到 android 清单并添加 这适用于 xamarin 和 unity