使用系统权限

为了保护系统的完整性和用户隐私权,Android 在访问受限的沙盒中运行每款应用。如果应用需要使用其沙盒以外的资源或信息,则必须明确请求权限。根据应用请求的权限类型,系统可能会自动授予权限,也可能会要求用户授予权限。

向清单添加权限

要声明您的应用需要权限,请将 元素置于您的应用清单中,作为顶级 元素的子项。例如,需要发送短信的应用可在清单中添加以下代码行:

<manifest xmlns:android=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
package=<span class="hljs-string">"com.example.snazzyapp"</span>> <uses-permission android:name=<span class="hljs-string">"android.permission.SEND_SMS"</span>/> <application <span class="hljs-keyword">...</span>>
<span class="hljs-keyword">...</span>
</application> </manifest>
`</pre> 系统在您声明权限之后的行为取决于权限的敏感性。如果权限不影响用户隐私权,系统会自动授权。如果权限可能涉及对敏感用户信息的访问,系统将要求用户审批请求。要了解有关不同种类权限的详细信息,请参阅正常权限和危险权限。 ### 检查权限 如果您的应用需要危险权限,则每次执行需要这一权限的操作时您都必须检查自己是否具有该权限。用户始终可以自由调用此权限,因此,即使应用昨天使用了相机,它不能假设自己今天仍具有该权限。 要检查您是否具有某项权限,请调用 ContextCompat.checkSelfPermission() 方法。例如,以下代码段显示了如何检查 Activity 是否具有在日历中进行写入的权限: <pre>`<span class="hljs-comment">// Assume thisActivity is the current activity</span>
<span class="hljs-keyword">int</span> permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);
`</pre> 如果应用具有此权限,方法将返回 PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限,方法将返回 PERMISSION_DENIED,且应用必须明确向用户要求权限。 ### 请求权限 如果您的应用需要应用清单中列出的危险权限,那么,它必须要求用户授予该权限。Android 为您提供了多种权限请求方式。调用这些方法将显示一个标准的 Android 对话框,不过,您不能对它们进行自定义。 如果应用尚无所需的权限,则应用必须调用一个 requestPermissions() 方法,以请求适当的权限。应用将传递其所需的权限,以及您指定用于识别此权限请求的整型请求代码。此方法异步运行:它会立即返回,并且在用户响应对话框之后,系统会使用结果调用应用的回调方法,将应用传递的相同请求代码传递到 requestPermissions()。 以下代码可以检查应用是否具备读取用户联系人的权限,并根据需要请求该权限: <pre>`<span class="hljs-comment">// Here, thisActivity is the current activity</span>
<span class="hljs-keyword">if</span> (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) { <span class="hljs-comment">// Should we show an explanation?</span>
<span class="hljs-keyword">if</span> (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) { <span class="hljs-comment">// Show an expanation to the user *asynchronously* -- don't block</span>
<span class="hljs-comment">// this thread waiting for the user's response! After the user</span>
<span class="hljs-comment">// sees the explanation, try again to request the permission.</span> } <span class="hljs-keyword">else</span> { <span class="hljs-comment">// No explanation needed, we can request the permission.</span> ActivityCompat.requestPermissions(thisActivity,
<span class="hljs-keyword">new</span> <span class="hljs-built_in">String</span>[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS); <span class="hljs-comment">// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an</span>
<span class="hljs-comment">// app-defined int constant. The callback method gets the</span>
<span class="hljs-comment">// result of the request.</span>
}
}
`</pre><pre>`注:当您的应用调用 <span class="hljs-function"><span class="hljs-title">requestPermissions</span><span class="hljs-params">()</span></span> 时,系统将向用户显示一个标准对话框。您的应用无法配置或更改此对话框。如果您需要为用户提供任何信息或解释,您应在调用 <span class="hljs-function"><span class="hljs-title">requestPermissions</span><span class="hljs-params">()</span></span> 之前进行,如解释应用为什么需要权限中所述。
`</pre> ### 处理权限请求响应 当应用请求权限时,系统将向用户显示一个对话框。当用户响应时,系统将调用应用的 onRequestPermissionsResult() 方法,向其传递用户响应。您的应用必须替换该方法,以了解是否已获得相应权限。回调会将您传递的相同请求代码传递给 requestPermissions()。例如,如果应用请求 READ_CONTACTS 访问权限,则它可能采用以下回调方法: <pre>`<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onRequestPermissionsResult</span><span class="hljs-params">(<span class="hljs-keyword">int</span> requestCode,
String permissions[], <span class="hljs-keyword">int</span>[] grantResults)</span> </span>{
<span class="hljs-keyword">switch</span> (requestCode) {
<span class="hljs-keyword">case</span> MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
<span class="hljs-comment">// If request is cancelled, the result arrays are empty.</span>
<span class="hljs-keyword">if</span> (grantResults.length > <span class="hljs-number">0</span>
&& grantResults[<span class="hljs-number">0</span>] == PackageManager.PERMISSION_GRANTED) { <span class="hljs-comment">// permission was granted, yay! Do the</span>
<span class="hljs-comment">// contacts-related task you need to do.</span> } <span class="hljs-keyword">else</span> { <span class="hljs-comment">// permission denied, boo! Disable the</span>
<span class="hljs-comment">// functionality that depends on this permission.</span>
}
<span class="hljs-keyword">return</span>;
} <span class="hljs-comment">// other 'case' lines to check for other</span>
<span class="hljs-comment">// permissions this app might request</span>
}
}
`</pre> 系统显示的对话框说明了您的应用需要访问的权限组;它不会列出具体权限。例如,如果您请求 READ_CONTACTS 权限,系统对话框只显示您的应用需要访问设备的联系人。用户只需要为每个权限组授予一次权限。如果您的应用请求该组中的任何其他权限(已在您的应用清单中列出),系统将自动授予应用这些权限。当您请求此权限时,系统会调用您的 onRequestPermissionsResult() 回调方法,并传递 PERMISSION_GRANTED,如果用户已通过系统对话框明确同意您的权限请求,系统将采用相同方式操作。 <pre>`注:您的应用仍需要明确请求其需要的每项权限,即使用户已向应用授予该权限组中的其他权限。此外,权限分组在将来的 Android 版本中可能会发生变化。您的代码不应依赖特定权限属于或不属于相同组这种假设。

例如,假设您在应用清单中列出了 READ_CONTACTS 和 WRITE_CONTACTS。如果您请求 READ_CONTACTS 且用户授予了此权限,那么,当您请求 WRITE_CONTACTS 时,系统将立即授予您该权限,不会与用户交互。

如果用户拒绝了某项权限请求,您的应用应采取适当的操作。例如,您的应用可能显示一个对话框,解释它为什么无法执行用户已经请求但需要该权限的操作。

当系统要求用户授予权限时,用户可以选择指示系统不再要求提供该权限。这种情况下,无论应用在什么时候使用 requestPermissions() 再次要求该权限,系统都会立即拒绝此请求。系统会调用您的 onRequestPermissionsResult() 回调方法,并传递 PERMISSION_DENIED,如果用户再次明确拒绝了您的请求,系统将采用相同方式操作。这意味着当您调用 requestPermissions() 时,您不能假设已经发生与用户的任何直接交互。

参考资料:

官方文档(中文版)Working with System Permissions

Android 6.0 运行时权限处理完全解析

最新文章

  1. 01 java开发前小知识
  2. 检索 COM 类工厂中 CLSID 为 {820280E0-8ADA-4582-A1D9-960A83CE8BB5} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))。
  3. Linux磁盘管理之日志文件系统和非日志文件系统08
  4. salt基本原理
  5. oracle本机登录不上dba的权限不足错误
  6. ios 异步处理耗时操作
  7. OracleApps 什么是Back to Back Order?
  8. Google protobuf的安装及使用
  9. Intrusion Detection of Specific Area Based on Video
  10. mysql中判断字段为空
  11. poj 1860 (Bellman_Ford判断正环)
  12. ffmpeg结构体以及函数介绍(一)
  13. mybatis的使用
  14. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案
  15. 【长期更新】迈向现代化的 .Net 配置指北
  16. HTML和CSS前端教程03-CSS文本样式
  17. ZJOI-2017 R2 游记
  18. python3+qqBot+图灵机器人实现qq聊天机器人
  19. 用户不在sudoers文件中,此事将被报告
  20. python基础一 ------如何统计一个列表元素的频度

热门文章

  1. Python入门 [输出,注释,列表,元祖,集合,字典,if,while,for]
  2. Spring mvc Json 的正确返回姿势
  3. P3811 乘法逆元
  4. Spring-framework应用程序启动loadtime源码分析笔记(三)——@KafkaListener
  5. NodeJs递归删除非空文件夹
  6. php的方法
  7. Scrapy学习篇(三)之创建项目和Scrapy的安装
  8. MySQL8.0.12版本密码修改策略问题
  9. C# 中使用锁防止多线程冲突
  10. 09 shell脚本程序练习