我正在阅读关于Android M中新Permissions模型的官方文档.它讨论了如果应用程序先前已请求此权限并且用户拒绝该请求shouldShowRequestPermissionRationale(),则返回的函数true.如果用户过去拒绝了权限请求并选择了"不再询问"选项,则此方法返回false.
但是我们如何区分以下两种情况呢?
案例1:该应用程序没有权限,之前未向用户询问过该权限.在这种情况下,shouldShowRequestPermissionRationale()将返回false,因为这是我们第一次询问用户.
情况2:用户已拒绝该权限并选择"不再询问",在这种情况下,shouldInShowRequestPermissionRationale()也将返回false.
我想将用户发送到案例2中的应用程序设置页面.我如何区分这两种情况?
根据Google的说法,当谈到M Developer Preview运行时权限时:
如果您之前从未要求过某种许可,那就请求它
如果您之前询问过,并且用户说"不",然后用户尝试执行需要被拒绝权限的操作,则应该在再次请求权限之前提示用户解释您需要权限的原因
如果您之前曾多次询问,并且用户已经说"不,并且停止询问"(通过运行时权限对话框上的复选框),您应该停止打扰(例如,禁用需要权限的UI)
但是,我们只有一个方法,shouldShowRequestPermissionRationale()返回a boolean,我们有三个状态.我们需要一种方法来区分从未问过的状态和停止询问状态,就像我们false从shouldShowRequestPermissionRationale()两者中得到的那样.
对于首次运行应用程序时请求的权限,这不是一个大问题.有很多方法可以确定这可能是您的应用程序的第一次运行(例如,boolean值SharedPreferences),因此您假设如果它是您的应用程序的第一次运行,那么您处于从未问过的状态.
但是,运行时权限的一部分愿景是您可能不会事先要求所有这些权限.当用户点击需要该权限的内容时,您可能仅在稍后要求的边缘功能上绑定权限.在这里,应用程序可能已运行多次,持续数月,之后我们突然需要再次请求权限.
在这些情况下,我们是否应该跟踪我们是否自己要求获得许可?或者Android M API中是否有我遗漏的东西告诉我们之前是否询问过?
我正在研究新的权限模型(Android 6.0 Marshmallow),我想知道有没有办法以编程方式打开应用程序的权限窗口?
不仅是申请细节
我设法用这样的东西打开第二个屏幕
private void goToSettings() {
Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(myAppSettings);
}
Run Code Online (Sandbox Code Playgroud)
但我不知道如何打开第一个.
非常感谢您的帮助:)
permissions android android-settings android-6.0-marshmallow
我只在使用模拟器时遇到了一个奇怪的错误.我发现一个问题在9个月前有同样的问题,根本没有答案......
我正在使用谷歌播放服务位置来获取我的应用程序中的位置,我确定我的清单权限,一切都在我的手机上完美运行,只在使用模拟器时出现问题,我在我的iMac上尝试了不同的模拟器Windows机器.
我怀疑仿真器不支持这个基本功能!
这是我的清单代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.orderme.ordermeandroid" >
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Run Code Online (Sandbox Code Playgroud)
这里是异常触发的地方:
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,mLocationRequest,this);
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
08-26 14:01:19.699 10157-10157/com.orderme.ordermeandroid E/AndroidRuntime? FATAL EXCEPTION: main
Process: com.orderme.ordermeandroid, PID: 10157
java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.google.android.gms.location.internal.zzg$zza$zza.zza(Unknown Source)
at com.google.android.gms.location.internal.zzi.zza(Unknown Source)
at com.google.android.gms.location.internal.zzj.zza(Unknown Source)
at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source)
at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source)
at com.google.android.gms.common.api.zzc$zza.zzb(Unknown Source)
at com.google.android.gms.common.api.zzf.zza(Unknown Source)
at com.google.android.gms.common.api.zzf.zzb(Unknown Source)
at com.google.android.gms.common.api.zzi.zzb(Unknown Source) …Run Code Online (Sandbox Code Playgroud) 这是通过Scoped Directory Access授予权限的更简单方法,但Dialog将显示一个名为"Do not ask again"的复选框.如果用户选择不再询问并拒绝该请求,则将自动拒绝您应用中对给定目录的所有未来请求,并且不会向用户显示请求UI.如果用户后悔或错误地点击了该复选框,应用程序如何解决?应用无法获得权限对话框.
我们怎么办呢?
由于在 Android 11 ( https://developer.android.com/about/versions/11/privacy/location )上引入了新的位置权限更改,因此需要更仔细地处理权限。我们现在只能请求后台位置权限两次
我想向用户显示一个取决于其位置权限状态的对话框。
问题是系统处理对话框外部的单击与拒绝权限相同,但显然不将其计入PermissionsUtil.shouldShowRequestStoragePermissionRationale限制。因此很难区分用户处于哪种状态。
我最初的问题是:如何处理这种具体情况?
但我想更有用的是一般问题:
如何识别用户是在系统权限对话框之外按下还是直接拒绝了权限?。
我想知道存储"永不再问"复选框布尔标志的位置以及如何清除它的值?不一定是以编程方式,而是手动 - 通过设置,命令或某些工具.尝试清除应用程序数据,卸载,卸载和清除,尝试手动切换权限来回打开/关闭,尝试甚至为模拟器设置较新的Marshmallow图像,但没有运气!
shouldShowRequestPermissionRationale 第一次返回 false。
此代码位于 Fragment 中:
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
requestPermissions(new String[]{READ_CONTACTS}, 0);
} else {
Toast.makeText(getActivity(), "FALSE", Toast.LENGTH_SHORT).show();
snackBarInfo.dismiss();
}
Run Code Online (Sandbox Code Playgroud)
有人遇到过这个吗?
请求权限后,ActivityCompat.OnRequestPermissionsResultCallback有时包含多个grantResults,只检查第一个是否安全?
该培训文档检查这样的帕拉姆:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
Run Code Online (Sandbox Code Playgroud)
但它不清楚,没有找到文件.
在Shot:中,在onRequestPermissionsResult某些设备上的GrantResults中,PackageManager.PERMISSION_DENIED当用户拒绝该权限时,该设备返回空值,并且某些设备具有值。
基于/sf/answers/2234802391/的答案,我采用了一种解决方案,用于识别用户已选择接受,拒绝和拒绝,而无需再次询问运行时权限。
根据我看到的许多文档,如果用户拒绝权限,则返回grantResults空
我使用的代码else if (grantResults[0] == PackageManager.PERMISSION_DENIED)在else if某种程度上会引发Arrayindexoutofbound异常
当用户拒绝权限
grantResults不是我的情况时,我已经测试了代码,但是我在Fabric控制台上看到了崩溃报告,grantResults原因是arrayindexoutofbound,
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PermissionManager.MY_PERMISSIONS_REQUEST_LOCATION_ACCESS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
DefineLocationService.start(this);
startNextActivity(0);
} else if …Run Code Online (Sandbox Code Playgroud) android permission-denied android-permissions runtime-permissions