Android M新的运行时权限开发者需要知道的一切
2016-07-28 16:22
519 查看
如果permissions没有影响到用户的隐私,系统就会自动授权。如果权限可能会访问到敏感的用户信息,系统则会要求用户处理这种权限要求。
系统permissions被分为两类,normal和dangerous:
Normal permissions不会直接触及到用户的隐私,如果你的app已经在Manifest文件中列出了常规权限,系统则会自动授权。
dangerous的权限能够给app访问用户可信任的数据,如果你的app在Manifest中列出了常规权限,系统则会自动许可。如果你列出了危险权限,那么用户就必须明确地给你的app授权。
然而有效的声明是不同的,这需要依赖于系统的版本以及你的app的target SDK级别:
如果手机运行在android 5.1或者更低,或者你的app的target SDK是22或更低的情况:如果你把dangerous permission列在了Manifest中,则用户必须在安装的时候就要授权;如果他们没有授权权限,则系统就不能安装该应用。
如果手机运行在android 6.0或者更高,并且你的app的SDK是23或者更高的情况:app必须在Manifest列出这些permissions,并且它会在app运行的时候询问每一个它需要的dangerous permission。用户可以授权或者拒绝每一个权限,并且app能够在受限的情况下继续运行,即使用户拒绝了一个permission的请求。
Note:从android 6.0(API level23),用户能够在任何app任何时候取消permissions,即使apptargets 在一个更低的API level下。
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);
如果app拥有了该permission,则方法返回PackageManager.PERMISSION_GRANTED,app 能继续这种操作。如果app没有该permission,则方法返回PERMISSION_DENIED,并且app必须明确向用户要求给permission。
当用户已经拒绝了一个permission请求的时候,你可以使用的一个方法是提供一个解释。如果用户一直试图使用的功能需要一个permission的许可,但是又一直拒绝许可该permission的要求,这或许表明该用户不理解为什么app需要提供该功能。在这种情况下,给用户一个解释或许是个好的方法。
为了找到哪些用户可能需要的解释的情况,android提供了一个使用的方法,shouldShowRequestPermissionRationale().该方法返回true,如果应用程序要求这个许可之前,用户拒绝请求。
Note:如果用户在以前拒绝了permission的请求,并且在permission请求的系统对话框中选择了Don’t ask again的选项,这个方法返回false。如果手机政策禁止应用程序拥有该权限也会返回false。
下面的代码检查app是否有读取用户联系人的permission,并在必要时请求允许:
该系统显示的对话框中描述的app需要访问权限组;它没有列出具体的权限。例如,如果你要求READ_CONTACTS权限,系统对话框,只是说你的应用程序需要访问该设备的联系人。用户只需要为每个权限组授予权限一次。如果app请求组(即在app清单中列出)中任何其他权限,系统自动授权他们。当你请求该权限,系统调用你的onRequestPermissionsResult()回调方法,并传递PERMISSION_GRANTED,它会在用户已明确授予通过系统对话框,你的要求是一样的。
Note:此外,权限的组成组可能会在将来的Android版本中改变。你的代码不应该依赖于假设特定的权限,或不在同一组。
例如,假设你列出的应用程序清单既有READ_CONTACTS也有WRITE_CONTACTS。如果你请求READ_CONTACTS和用户授予权限,然后你要求WRITE_CONTACTS,系统自动授予你该权限,而不必再与用户交互了。
如果用户拒绝了权限要求,你的app应该采取适当的行动。例如,你的应用程序可能会显示一个对话框,解释为什么它不能执行用户的请求的操作需要该权限。
当系统要求用户授予权限,用户告知系统不要再问了该权限的选项。在这种情况下,任何时间的应用程序使用requestPermissions()再次要求该权限,系统会立即拒绝请求。该系统调用你的onRequestPermissionsResult()回调方法,并传递PERMISSION_DENIED,以同样的方式,将如果用户曾明确再次拒绝你的要求。这意味着,当你调用requestPermissions(),你不能假设与用户进行任何直接的互动已经发生。
参考: Android M新的运行时权限开发者需要知道的一切
https://developer.android.com/training/permissions/requesting.html#perm-request
系统permissions被分为两类,normal和dangerous:
Normal permissions不会直接触及到用户的隐私,如果你的app已经在Manifest文件中列出了常规权限,系统则会自动授权。
dangerous的权限能够给app访问用户可信任的数据,如果你的app在Manifest中列出了常规权限,系统则会自动许可。如果你列出了危险权限,那么用户就必须明确地给你的app授权。
然而有效的声明是不同的,这需要依赖于系统的版本以及你的app的target SDK级别:
如果手机运行在android 5.1或者更低,或者你的app的target SDK是22或更低的情况:如果你把dangerous permission列在了Manifest中,则用户必须在安装的时候就要授权;如果他们没有授权权限,则系统就不能安装该应用。
如果手机运行在android 6.0或者更高,并且你的app的SDK是23或者更高的情况:app必须在Manifest列出这些permissions,并且它会在app运行的时候询问每一个它需要的dangerous permission。用户可以授权或者拒绝每一个权限,并且app能够在受限的情况下继续运行,即使用户拒绝了一个permission的请求。
Note:从android 6.0(API level23),用户能够在任何app任何时候取消permissions,即使apptargets 在一个更低的API level下。
检查权限
检查是否有permission,调用ContextCompat.checkSelfPermission()方法。例如下面一段代码展示了怎样检查当activity有permission写日历的权限:// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);
如果app拥有了该permission,则方法返回PackageManager.PERMISSION_GRANTED,app 能继续这种操作。如果app没有该permission,则方法返回PERMISSION_DENIED,并且app必须明确向用户要求给permission。
请求权限
如果你的app需要一个dangerous permission,并且已经被列在了Manifest中,那么它必须要求用户去给该permission授权。Android提供了若干个方法,你能够使用它们去请求permission。调用这些方法会弹出一个你不能够自定义的标准android dialog。向用户解释为什么app需要permissions
在某些情况下,你也许想帮助用户理解为什么app需要permission。在你请求一个permission之前,你需要考虑给用户一个合理的解释。请记住,你不会希望用户被说明淹没的,如果你提供了太多的解释,用户或许会发现app令人沮丧,甚至删掉它。当用户已经拒绝了一个permission请求的时候,你可以使用的一个方法是提供一个解释。如果用户一直试图使用的功能需要一个permission的许可,但是又一直拒绝许可该permission的要求,这或许表明该用户不理解为什么app需要提供该功能。在这种情况下,给用户一个解释或许是个好的方法。
为了找到哪些用户可能需要的解释的情况,android提供了一个使用的方法,shouldShowRequestPermissionRationale().该方法返回true,如果应用程序要求这个许可之前,用户拒绝请求。
Note:如果用户在以前拒绝了permission的请求,并且在permission请求的系统对话框中选择了Don’t ask again的选项,这个方法返回false。如果手机政策禁止应用程序拥有该权限也会返回false。
请求你需要的permission
如果app已经没有它需要的permission,那么app必须调用一个requestPermissions()方法去请求适当的permission。App传递它想要的permissions,以及一个你指定识别此permission整数的request code 。这个方法有同步功能:它立即返回,并在用户响应了对话框后,系统会调用app与结果的的回调方法,通过该app传递给requestPermissions()相同request code。下面的代码检查app是否有读取用户联系人的permission,并在必要时请求允许:
// Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.READ_CONTACTS)) { // Show an expanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // app-defined int constant. The callback method gets the // result of the request. } }
处理permissions请求的响应
当你的app请求权限,系统就会向用户显示一个对话框。当用户相应了对对话框,系统就会调用app的onRequestPermissionsResult()方法,传递用户的响应。你的app必须重写该方法,并确定权限是否允许,回调被传递的request和requestPermissions()传递的request code是相同的。例如,如果app请求READ_CONTACTS访问 ,则需要如下的回调方法: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. } return; } // other 'case' lines to check for other // permissions this app might request } }" data-snippet-id="ext.2b67e9a7c17a78d31f2185e257422b42" data-snippet-saved="false" data-codota-status="done">[code]@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { // If request is cancelled, the result arrays are empty. 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. } return; } // other 'case' lines to check for other // permissions this app might request } }
该系统显示的对话框中描述的app需要访问权限组;它没有列出具体的权限。例如,如果你要求READ_CONTACTS权限,系统对话框,只是说你的应用程序需要访问该设备的联系人。用户只需要为每个权限组授予权限一次。如果app请求组(即在app清单中列出)中任何其他权限,系统自动授权他们。当你请求该权限,系统调用你的onRequestPermissionsResult()回调方法,并传递PERMISSION_GRANTED,它会在用户已明确授予通过系统对话框,你的要求是一样的。
Note:此外,权限的组成组可能会在将来的Android版本中改变。你的代码不应该依赖于假设特定的权限,或不在同一组。
例如,假设你列出的应用程序清单既有READ_CONTACTS也有WRITE_CONTACTS。如果你请求READ_CONTACTS和用户授予权限,然后你要求WRITE_CONTACTS,系统自动授予你该权限,而不必再与用户交互了。
如果用户拒绝了权限要求,你的app应该采取适当的行动。例如,你的应用程序可能会显示一个对话框,解释为什么它不能执行用户的请求的操作需要该权限。
当系统要求用户授予权限,用户告知系统不要再问了该权限的选项。在这种情况下,任何时间的应用程序使用requestPermissions()再次要求该权限,系统会立即拒绝请求。该系统调用你的onRequestPermissionsResult()回调方法,并传递PERMISSION_DENIED,以同样的方式,将如果用户曾明确再次拒绝你的要求。这意味着,当你调用requestPermissions(),你不能假设与用户进行任何直接的互动已经发生。
参考: Android M新的运行时权限开发者需要知道的一切
https://developer.android.com/training/permissions/requesting.html#perm-request
相关文章推荐
- Codeigniter中mkdir创建目录遇到权限问题和解决方法
- ORACLE 存储过程权限问题
- 拍照权限导致某些代码在6.0系统上崩溃
- win 7 db2 catalog 没有权限问题解决方法
- linux下的特殊权限问题。
- [每日一题] OCP1z0-047 :2013-08-23 SYNONYM(公有和私有同义词)――权限问题...................93
- RoseMirror权限问题,引起的写客户端配置文件出错
- iOS录音,调用麦克风话筒
- FeignClient 在 oauth2 中与 hystrix 线程策略冲突问题造成的权限问题
- 分布式部署下的报表调用 API调用 权限问题以及性能方案
- Permissions 0777 for ‘***’ are too open.
- Centos 创建新的用户并赋予sudo权限
- ubuntu14.04下的串口权限释放
- 关于手机权限问题
- 初学Linux第二周小记
- android 自定义控件 使用declare-styleable进行配置属性(源码角度)
- AndroidStudio debug
- Android中android:visibility的3中属性的剖析
- Android5.0 CollapsingToolbarLayout 基本使用
- 华为、酷派手机logcat不输出日志解决方案