Android6.0动态权限控制
在Android6.0(M)之前,在用户安装应用的时候会产生一个权限列表,只有用户允许这些权限后,应用才可以正常的安装,这就会产生一个问题,这些权限对用户是不具有感知性的,也就是说用户都不知道你要这些权限干什么,我明明装的是一个阅读类型的应用,你却要我拨打电话的权限,你想干嘛呢?当然绝大部分的开发者是善意的,但也避免不了一些特殊人群利用这些“漏洞”做一些不好的事情。
而在Android6.0(M)之后,用户是可以不管权限直接安装应用的,当应用需要调用某些权限的时候,会给予用户一个通知与说明,我要这些权限干什么,这样下来可以让用户有更加清醒的权限分配意识,也在一定程度上更加人性化的保护了用户的隐私,避免了“权限一刀切”。
权限分组
在Android6.0(M)之后,对权限进行了分类,大致有这三种:
普通权限
也就是正常权限,是对手机的一些正常操作,对用户的隐私没有太大影响的权限,比如手机的震动,网络访问,蓝牙等权限,这些权限会在应用被安装的时候默认授予,用户不能拒绝,也不能取消。
详细请参考:https://developer.android.com/guide/topics/permissions/normal-permissions.html
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
REQUEST_INSTALL_PACKAGES
SET_ALARM
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
对于上面这些权限,和Android6.0(M)之前的系统一样,在AndroidManifest.xml声明即可。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.snazzyapp">
<uses-permission android:name="android.permission.SEND_SMS"/>
<application ...>
...
</application>
</manifest>
危险权限
详细请参考文档:https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
其实就是运行中需要处理的权限,也是我们最需要注意的权限,这些权限会关系到用户的隐私或影响到其他应用的运行,这些危险权限,谷歌还做了一个权限组,以分组的形式来呈现:
由于运行权限机制的出现,变得我们需要对新开发的应用去做适配,如果是6.0之前开发的谷歌做了良好的适配:当你的应用targetSdkVersion小于23的时候,就算你运行在Android6.0系统上,它也会默认采用以前的权限管理机制,也就是一刀切。当你的targetSdkVersion大于等于23的时候且在Andorid6.0(M)系统上,它才会采用新的这套权限管理机制。
所以如果你想逃开这个“麻烦”,只要把targetSdkVersion的版本设置为低于23就可以了,不过不建议采用这种方案,该来的总是要来的,随着国产手机ROM的更新,比如小米,华为等也开始有部分机型进行了系统升级,所以这是种趋势。
说了这么多,那么来看下怎么进行Android6.0(M)的权限管理适配吧,其实很简单,只需要记住下面几个API方法就可以:(API23之后提供)
//用来检测应用是否已经具有权限
int checkSelfPermission(String permission)
//进行请求单个或多个权限
void requestPermissions(String[] permissions, int requestCode)
//请求权限结果回调
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
运行时权限请求
如果您的应用需要危险权限,则每次执行需要这一权限的操作时您都必须检查自己是否具有该权限。用户始终可以自由调用此权限,因此,即使应用昨天使用了相机权限,它不能确定今天仍具有该权限。
检查权限
要检查您是否具有某项权限,请调用 ContextCompat.checkSelfPermission() 方法。例如,以下代码段显示了如何检查 Activity 是否具有在日历中进行写入的权限。
View.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {