安卓API 6.0权限问题
来源:互联网 发布:视频图片合成软件 编辑:程序博客网 时间:2024/05/17 01:21
前言
谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6.0出来,使得用户权限授权变得合理。这可能也是参考IOS系统的,只有在用户需要使用权限的时候,才去授权请求,这样做的目的是提高用户体验,当然,用户感觉好了,受苦的是我们开发人员,原来的规则不适用了,现在我们去适应新的规则,毕竟是靠谷歌这颗大树吃饭的嘛。
原来权限模型
在Android 6.0版本之前,权限都是一条龙服务的,只要用户安装完,AndroidManifest清单上申请的权限都会被系统默认授权,并且授权后也撤销不了。这样的弊端在哪里呢?有些权限可能用户觉得不需要,比如他不想有通知的权限,不想受到通知的干扰,那么他就不能屏蔽通知,就是不需要的权限,他去不掉,自主权不在他那边。还有一些情况是,一些恶意程序,会利用这个权限默认授权,进行恶意获取用户数据和攻击。所以Android 6.0版本,一方面让用户更加容易的控制自己的隐私,一方面需要重新适配应用权限。
Android 6.0权限模型
采用新的权限模型,只有在需要权限的时候,才告知用户是否授权,是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候,需要先检查是否有所需要的权限申请。这样的用户的自主性提高很多,比如用户可以给APP赋予摄像的权限,但是可以拒绝记录设备位置的权限,就是怕位置信息上传等等。
权限流程
在API 23中,权限满足的标准流程:
但这里有个问题,那就是在系统授权弹窗环节,提醒框会有个不再提示的复选框,如果用户点击不太提示,并拒绝授权,那么再下次授权的时候,系统授权弹窗的提示框就不会在提示,所以我们很有必要需要自定义权限弹窗提示框,那么流程图就变成如下了。
权限类型
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
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
SET_ALARM
INSTALL_SHORTCUT
UNINSTALL_SHORTCUT
CALENDAR
READ_CALENDAR
WRITE_CALENDAR
CAMERA
CAMERA
CONTACTS
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
RECORD_AUDIO
PHONE
READ_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
SENSORS
BODY_SENSORS
SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
版本兼容
// Assume thisActivity is the current activityint permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR);
// Here, thisActivity is the current activityif (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. }}
@Overridepublic 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 }}
“android.permission.SYSTEM_ALERT_WINDOW”
“android.permission.WRITE_SETTINGS”这两个权限,实现方式跟上之前在工作中,碰到一种情况,如果是运行在6.0的版本上是需要走新的权限模型,如果是运行在老的版本上,则需要进行一个判断,此时碰到一个问题是,在谷歌官方推荐中,在判断app运行的系统是否在Android M上时,它的判断是如下: Build.VERSION.CODENAME.equals("MNC"); 可是在我实际适配中,发现这句却无效的,就改用Build.VERSION.SDK_INT >= 23。的,需要另外特殊处理。
ACTION_MANAGE_OVERLAY_PERMISSION
.这样一个动作,同时可以用Settings.canDrawOverlays() 方法进行判断之前是否已经授权过了。
ACTION_MANAGE_WRITE_SETTINGS 这样一个动作,同时可以用Settings.System.canWrite()
.
方法进行判断之前是否已经授权过了。
具体代码:
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);intent.setData(Uri.parse("package:" + getPackageName()));intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);
注意点
之前在工作中,碰到一种情况,如果是运行在6.0的版本上是需要走新的权限模型,如果是运行在老的版本上,则需要进行一个判断,此时碰到一个问题是,在谷歌官方推荐中,在判断app运行的系统是否在Android M上时,它的判断是如下: Build.VERSION.CODENAME.equals("MNC"); 可是在我实际适配中,发现这句却无效的,就改用Build.VERSION.SDK_INT >= 23。
总结
- 首先要知道6.0版本权限模型跟原来版本是不同的,不再是统一在manifest中默认系统授权,而是有需要的时候,向系统请求授权,提高用户体验。
- 了解权限检测流程,一点注意点是如果系统权限弹窗提示框被不再提醒了,需要我们自定义提示弹窗,引导用户去授权。
- 明白权限类型,分为normal和dangerous类型,同时,在dangerous中还需要注意一点,SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS这两个特殊授权请求方式,跟一般授权请求方式不同。
- 在判断APP是否运行在Android M上,可以用版本号来判断,可以准确点。
参考
- 安卓API 6.0权限问题
- 安卓6.0权限相关问题
- 安卓6.0注意的权限问题
- 安卓6.0以上动态权限问题
- 安卓权限配置问题
- 安卓webrtc权限问题
- 安卓的权限问题
- 安卓6.0权限
- 安卓6.0系统权限问题android.permission.WRITE_SETTINGS
- unity3d打包在安卓6.0上的权限问题
- 记录一下安卓6.0权限的问题
- 解决安卓6.0拨打电话时的权限问题
- 安卓M 6.0动态权限的问题
- 安卓6.0系统权限问题android.permission.WRITE_SETTINGS
- 安卓6.0动态权限申请问题,可见链接
- 安卓开发中的访问权限问题
- 安卓6.0权限管理
- 安卓6.0权限使用
- 详解python linecache模块读取文件的方法
- Toast工具类
- regularization 规范化(L1,L2等等):加惩罚函数降低过拟合
- Java初学
- hi
- 安卓API 6.0权限问题
- AngularJS ui-router (嵌套路由)
- java springmvc post和get中文乱码问题
- BZOJ2431 [HAOI2009]逆序对数列
- 修改浏览器默认的滚动条样式
- 从0开始,搭建SSM服务器框架
- Java for Web学习笔记(二七):JSTL(3)Core Tag(中)
- VS2010/MFC编程入门之前言
- SQLite 大数据量 新增 / 修改 提升效率的办法