根据Google的说法,当涉及M开发人员预览运行时权限时
但是,我们只有一个返回boolean
的方法shouldShowRequestPermissionRationale()
,并且我们有三个状态。我们需要一种方法来区分从未询问状态和停止询问状态,因为我们从shouldShowRequestPermissionRationale()
获取了这两种状态的false
。
有很多方法可以确定这可能是你的应用程序的第一次运行(例如,SharedPreferences
中的boolean
值),所以你假设如果这是你的应用程序的第一次运行,你就处于从未被询问的状态。
但是,运行时权限的部分愿景是,您可能不会预先请求所有权限。与边缘功能相关的权限,您可能只会在稍后用户点击需要该权限的内容时才要求该权限。在这里,这个应用程序可能已经运行了很多次,在我们突然需要请求另一个许可之前,已经运行了几个月。
在这种情况下,我们是否应该跟踪自己是否请求了许可?或者,Android M API中有没有我遗漏的东西,告诉我们我们之前是否问过了?
发布于 2015-08-11 05:02:37
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == REQUEST_CAMERA) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
doThing();
//STORE FALSE IN SHAREDPREFERENCES
} else {
//STORE TRUE IN SHAREDPREFERENCES
}
}
如上所述,将一个布尔值存储在SharedPreferences中,并将key作为权限代码和值,以指示该首选项以前是否已被拒绝。
不幸的是,你可能不能在你的应用程序运行时检查已经被接受然后又被拒绝的首选项。最终的规范不可用,但你的应用程序可能会重新启动,或者在下一次启动之前获得模拟值。
发布于 2016-02-19 08:49:45
我知道我发得很晚,但详细的例子可能会对某些人有帮助。
我注意到的是,如果我们将shouldShowRequestPermissionRationale()标志签入到onRequestPermissionsResult()回调方法中,它只显示两种状态。
状态1:-Return true:--任何时候用户点击Deny permissions (拒绝权限)(包括第一次。
状态2 :-返回false:-如果用户选择“s”,则不再询问。
下面是一个包含多个权限请求的示例:-
应用程序在启动时需要2个权限。SEND_SMS和ACCESS_FINE_LOCATION (在manifest.xml中都有提到)。
一旦应用程序启动,它就会一起请求多个权限。如果两个权限都被授予,则正常流程继续。
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(checkAndRequestPermissions()) {
// carry on the normal flow, as the case of permissions granted.
}
}
private boolean checkAndRequestPermissions() {
int permissionSendMessage = ContextCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS);
int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.SEND_SMS);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
如果没有授予一个或多个权限,activityCompat.requestPermissions()将请求权限,并且控制转到onRequestPermissionsResult()回调方法。
您应该在onRequestPermissionsResult()回调方法中检查shouldShowRequestPermissionRationale()标志的值。
只有两种情况:
情况1:-Any用户单击拒绝权限(包括第一次)时,将返回true。因此,当用户拒绝时,我们可以显示更多的解释,并继续询问。
案例2:-Only如果用户选择“never asks”,则返回false。在这种情况下,我们可以继续使用有限的功能,并引导用户从设置中激活更多功能的权限,或者如果权限对应用程序来说微不足道,我们也可以完成设置。
案例- 1
案例- 2
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
Log.d(TAG, "Permission callback called-------");
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
// Initialize the map with both permissions
perms.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
// Fill with actual results from user
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for both permissions
if (perms.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "sms & location services permission granted");
// process the normal flow
//else any one or both the permissions are not granted
} else {
Log.d(TAG, "Some permissions are not granted ask again ");
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// // shouldShowRequestPermissionRationale will return true
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.SEND_SMS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
showDialogOK("SMS and Location Services Permission required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
.show();
// //proceed with logic by disabling the related features or quit the app.
}
}
}
}
}
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
发布于 2015-09-16 18:03:25
不,你不需要跟踪你是否请求了许可,你也不需要区分Never-Asked和Stop- and。
对于app开发者来说,状态1和3是一样的:你需要权限和ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED
,然后你只需要通过ActivityCompat.requestPermissions()
请求权限,无论你请求了多少次,只要用户点击了需要权限的功能。用户最终将“允许”它,或“拒绝”它,并选中“永不再问”。该设计不会阻止您多次弹出权限请求对话框。
然而,这个设计确实鼓励你在某些时候解释权限的目的-你的状态2。shouldShowRequestPermissionRationale()
不是用来决定你是否应该请求权限,它是用来在你请求权限之前决定你是否应该显示解释。
关于状态3,还有几个解释:
shouldShowRequestPermissionRationale()
.ActivityCompat.requestPermissions()
将不再弹出对话框。shouldShowRequestPermissionRationale()
之后禁用UI。https://stackoverflow.com/questions/31928868
复制相似问题