从Android6.0开始,权限分成两种,第一种是普通权限,不涉及用户隐私,只需要在Manifest中声明即可,比如网络、蓝牙、NFC等;第二种是危险权限(即运行时权限,下面统称为运行时权限),涉及到用户隐私信息,需要用户授权后才可使用,比如SD卡读写、联系人、短信读写等。
(1)普通权限:如果应用程序在manifest中声明了普通权限,系统会自动授予这些权限。
(2)运行时权限:如果应用程序在manifest中声明了运行时权限(也就是说,这些权限可能会影响用户隐私和设备的普通操作),如表9-1所示,应用程序在运行时会明确地让用户决定是否授予这些权限。系统请求用户授予这些权限的方式是由当前应用运行的系统版本来决定的。安装器会决定是否授予它所声明的权限,这有时候会询问用户。只有权限被授予,这个应用才能使用受保护的特性,否则,访问失败并且不会通知用户。
表9-1 危险权限列表
这里以CALL_PHONE这个权限作为实例进行说明。
(1)在布局文件activity_main.xml中增加一个按钮,如图9-2所示。
图9-2 RuntimePermission项目布局
(2)在AndroidManifest.xml中添加权限,代码如下。
(3)在MainActivity的Button监听事件中增加拨打电话的代码。
(4)运行程序,在低于Android 6.0系统的手机上运行是正常的,但是如果在6.0以上高版本中运行,单击Make Call按钮将没有任何效果,这时观察logcat的打印信息,会看到如图9-3所示的信息。
图9-3 项目运行日志信息(www.xing528.com)
信息中提示Permission Denial,这是由于权限禁止造成的,因为在6.0以上版本的系统中,使用危险权限必须在运行时做出处理。
在Android 6.0系统及以上的源代码编辑中,Android Studio环境也会出现权限的提示,如图9-4所示。
图9-4 权限代码提示
下面修复这个问题,修改MainActivity的代码如下。
如果执行的操作需要一个dangerous permission,那么每次在执行操作的地方都必须检查是否有这个permission,因为用户可以在应用设置里随意地更改授权情况,所以必须每次在使用前都检查是否有权限。
检查权限的方法为ContextCompat.checkSelfPermission(),其两个参数分别是Context和权限名,返回值是PERMISSION_GRANTED或PERMISSION_DENIED。
如果已经授权,将直接拨打电话,如果没有,则调用ActivityCompat.requestPermissions()申请授权,requestPermissions()方法3个参数,Activity、permission名字的数组和一个整型的requestcode。
调用requestPermissions()方法,会弹出一个对话框,用户可选择同意或拒绝权限申请,不论哪种结果,授权的结果会封装在grantResults参数中,如果用户同意将调用call()方法,如果不同意,则放弃操作。
现在重新运行程序,单击Make Call按钮,结果如图9-5所示,如果用户同意授权,结果如图9-6所示。
图9-5 申请电话权限对话框
图9-6 用户同意申请
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。