转自:http://blog.csdn.net/uana_777/article/details/54136255

Part One

权限区分 
Android 6.0 为了保护用户隐私,将一些权限的申请放在了应用运行的时候去申请, 比如以往的开发中,开发人员只需要将需要的权限在清单文件中配置即可,安装后用户可以在设置中的应用信息中看到:XX应用以获取**权限。用户点击可以选择给应用相应的权限。此前的应用权限用户可以选择允许、提醒和拒绝。在安装的时候用户是已经知道应用需要的权限的。但是这样存在一个问题,就是用户在安装的时候,应用需要的权限十分的多(有些开发者为了省事,会请求一些不必要的权限或者请求全部的权限),这个时候用户在安装应用的时候也许并没有发现某些侵犯自己隐私的权限请求,安装之后才发现自己的隐私数据被窃取。其实Android6.0 动态权限一方面是为了广大用户考虑,另一方面其实是Google为了避免一些不必要的官司。但是这样做可实在是苦了程序员了。不过还好,权限不是所有的都需要动态申请,下面就说一下Android6.0对权限的分割: 
一、普通权限 
这类的权限不需要动态申请,需要这个权限的时候还是按照以往的做法,在清单文件中申请相应的权限即可,在安装的时候会展示给用户,用户同意安装就获取相应的权限。写法举例如下: 
清单文件中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.deepai.paipai"> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
........
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

下面是对权限的总结: 
android.permission.EXPAND_STATUS_BAR 允许一个程序扩展收缩在状态栏,android开发网提示应该是一个类似Windows Mobile中的托盘程序 
android.permission.FACTORY_TEST 作为一个工厂测试程序,运行在root用户 
android.permission.FLASHLIGHT 访问闪光灯,android开发网提示HTC Dream不包含闪光灯 
android.permission.FORCE_BACK 允许程序强行一个后退操作是否在顶层activities 
android.permission.FOTA_UPDATE 暂时不了解这是做什么使用的,android开发网分析可能是一个预留权限. 
android.permission.GET_ACCOUNTS 访问一个帐户列表在Accounts Service中 
android.permission.GET_PACKAGE_SIZE 允许一个程序获取任何package占用空间容量 
android.permission.GET_TASKS 允许一个程序获取信息有关当前或最近运行的任务,一个缩略的任务状态,是否活动等等 
android.permission.HARDWARE_TEST 允许访问硬件 
android.permission.INJECT_EVENTS 允许一个程序截获用户事件如按键、触摸、轨迹球等等到一个时间流,android开发网提醒算是hook技术吧 
android.permission.INSTALL_PACKAGES 允许一个程序安装应用 
android.permission.INTERNAL_SYSTEM_WINDOW 允许打开窗口使用系统用户界面 
android.permission.ACCESS_CHECKIN_PROPERTIES 允许读写访问“properties”表在checkin数据库中,改值可以修改上传。 
android.permission.ACCESS_COARSE_LOCATION 允许一个程序访问CellID或WiFi热点来获取粗略的位置 
android.permission.ACCESS_FINE_LOCATION 允许一个程序访问精良位置(如GPS) 
android.permission.WRITE_CONTACTS 允许程序写入但不读取用户联系人数据 
android.permission.WRITE_GSERVICES 允许程序修改Google服务地图 
android.permission.WRITE_OWNER_DATA 允许一个程序写入但不读取所有者数据 
android.permission.WRITE_SETTINGS 允许程序读取或写入系统设置 
android.permission.WRITE_SMS 允许程序写短信 
android.permission.WRITE_SYNC_SETTINGS 允许程序写入同步设置 
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 允许应用程序访问额外的位置提供命令 
android.permission.ACCESS_MOCK_LOCATION 允许程序创建模拟位置提供用于测试 
android.permission.ACCESS_NETWORK_STATE 允许程序访问有关GSM网络信息 
android.permission.ACCESS_SURFACE_FLINGER 允许程序使用SurfaceFlinger底层特性 
android.permission.ACCESS_WIFI_STATE 允许程序访问Wi-Fi网络状态信息 
android.permission.ADD_SYSTEM_SERVICE 允许程序发布系统级服务 
android.permission.BATTERY_STATS 允许程序更新手机电池统计信息 
android.permission.BLUETOOTH 允许程序连接到已配对的蓝牙设备 
android.permission.BLUETOOTH_ADMIN 允许程序发现和配对蓝牙设备 
android.permission.BROADCAST_PACKAGE_REMOVED 允许程序广播一个提示消息在一个应用程序包已经移除后 
android.permission.BROADCAST_STICKY 允许一个程序广播常用intents 
android.permission.CALL_PHONE 允许一个程序初始化一个电话拨号不需通过拨号用户界面需要用户确认 
android.permission.DELETE_CACHE_FILES 允许程序删除缓存文件 
android.permission.DELETE_PACKAGES 允许一个程序删除包 
android.permission.DEVICE_POWER 允许访问底层电源管理 
android.permission.DIAGNOSTIC 允许程序RW诊断资源 
android.permission.DISABLE_KEYGUARD 允许程序禁用键盘锁 
android.permission.DUMP 允许程序返回状态抓取信息从系统服务 
android.permission.CALL_PRIVILEGED 允许一个程序拨打任何号码,包含紧急号码无需通过拨号用户界面需要用户确认 
android.permission.CAMERA 请求访问使用照相设备 
android.permission.CHANGE_COMPONENT_ENABLED_STATE 允许一个程序是否改变一个组件或其他的启用或禁用 
android.permission.CHANGE_CONFIGURATION 允许一个程序修改当前设置,如本地化 
android.permission.CHANGE_NETWORK_STATE 允许程序改变网络连接状态 
android.permission.CHANGE_WIFI_STATE 允许程序改变Wi-Fi连接状态 
android.permission.CLEAR_APP_CACHE 允许一个程序清楚缓存从所有安装的程序在设备中 
android.permission.CLEAR_APP_USER_DATA 允许一个程序清除用户设置 
android.permission.CONTROL_LOCATION_UPDATES 允许启用禁止位置更新提示从无线模块 
android.permission.REBOOT 请求能够重新启动设备 
android.permission.RECEIVE_BOOT_COMPLETED 允许一个程序接收到ACTION_BOOT_COMPLETED 广播在系统完成启动 
android.permission.RECEIVE_MMS 允许一个程序监控将收到MMS彩信,记录或处理 
android.permission.RECEIVE_SMS 允许程序监控一个将收到短信息,记录或处理 
android.permission.RECEIVE_WAP_PUSH 允许程序监控将收到WAP PUSH信息 
android.permission.RECORD_AUDIO 允许程序录制音频 
android.permission.REORDER_TASKS 允许程序改变Z轴排列任务 
android.permission.RESTART_PACKAGES 允许程序重新启动其他程序 
android.permission.SEND_SMS 允许程序发送SMS短信 
android.permission.INTERNET 允许程序打开网络套接字 
android.permission.MANAGE_APP_TOKENS 允许程序管理(创建、催后、 z-order默认向z轴推移)程序引用在窗口管理器中 
android.permission.MASTER_CLEAR 目前还没有明确的解释,android开发网分析可能是清除一切数据,类似硬格机 
android.permission.MODIFY_AUDIO_SETTINGS 允许程序修改全局音频设置 
android.permission.MODIFY_PHONE_STATE 允许修改话机状态,如电源,人机接口等 
android.permission.MOUNT_UNMOUNT_FILESYSTEMS 允许挂载和反挂载文件系统可移动存储 
android.permission.PERSISTENT_ACTIVITY 允许一个程序设置他的activities显示 
android.permission.PROCESS_OUTGOING_CALLS 允许程序监视、修改有关播出电话 
android.permission.READ_CALENDAR 允许程序读取用户日历数据 
android.permission.READ_CONTACTS 允许程序读取用户联系人数据 
android.permission.READ_FRAME_BUFFER 允许程序屏幕波或和更多常规的访问帧缓冲数据 
android.permission.READ_INPUT_STATE 允许程序返回当前按键状态 
android.permission.READ_LOGS 允许程序读取底层系统日志文件 
android.permission.READ_OWNER_DATA 允许程序读取所有者数据 
android.permission.READ_SMS 允许程序读取短信息 
android.permission.READ_SYNC_SETTINGS 允许程序读取同步设置 
android.permission.READ_SYNC_STATS 允许程序读取同步状态 
android.permission.SET_ACTIVITY_WATCHER 允许程序监控或控制activities已经启动全局系统中 
android.permission.SET_ALWAYS_FINISH 允许程序控制是否活动间接完成在处于后台时 
android.permission.SET_ANIMATION_SCALE 修改全局信息比例 
android.permission.SET_DEBUG_APP 配置一个程序用于调试 
android.permission.SET_ORIENTATION 允许底层访问设置屏幕方向和实际旋转 
android.permission.SET_PREFERRED_APPLICATIONS 允许一个程序修改列表参数PackageManager.addPackageToPreferred()和PackageManager.removePackageFromPreferred()方法 
android.permission.SET_PROCESS_FOREGROUND 允许程序当前运行程序强行到前台 
android.permission.SET_PROCESS_LIMIT 允许设置最大的运行进程数量 
android.permission.SET_TIME_ZONE 允许程序设置时间区域 
android.permission.SET_WALLPAPER 允许程序设置壁纸 
android.permission.SET_WALLPAPER_HINTS 允许程序设置壁纸hits 
android.permission.SIGNAL_PERSISTENT_PROCESSES 允许程序请求发送信号到所有显示的进程中 
android.permission.STATUS_BAR 允许程序打开、关闭或禁用状态栏及图标Allows an application toopen, close, or disable the status bar and its icons. 
android.permission.SUBSCRIBED_FEEDS_READ 允许一个程序访问订阅RSS Feed内容提供 
android.permission.SUBSCRIBED_FEEDS_WRITE 系统暂时保留改设置,android开发网认为未来版本会加入该功能。 
android.permission.SYSTEM_ALERT_WINDOW 允许一个程序打开窗口使用TYPE_SYSTEM_ALERT,显示在其他所有程序的顶层 
android.permission.VIBRATE 允许访问振动设备 
android.permission.WAKE_LOCK 允许使用PowerManager的 WakeLocks保持进程在休眠时从屏幕消失 
android.permission.WRITE_APN_SETTINGS 允许程序写入API设置 
android.permission.WRITE_CALENDAR 允许一个程序写入但不读取用户日历数据

可以看出Android中对资源以及服务的访问都非常严格,另外,在程序打包成APK的时候也需要对软件进行签名。

定位相关权限

获取精确位置    android.permission.ACCESS_FINE_LOCATION       通过GPS芯片接收卫星的定位信息,定位精度达10米以内  

访问定位额外命令    android.permission.ACCESS_LOCATION_EXTRA_COMMANDS   允许程序访问额外的定位提供者指令 

获取模拟定位信息    android.permission.ACCESS_MOCK_LOCATION 获取模拟定位信息,一般用于帮助开发者调试应用  

控制定位更新    android.permission.CONTROL_LOCATION_UPDATES       允许获得移动网络定位信息改变      

安装定位提供    android.permission.INSTALL_LOCATION_PROVIDER  安装定位提供 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

网络状态

访问网络    android.permission.INTERNET     访问网络连接,可能产生GPRS流量    

获取网络状态    android.permission.ACCESS_NETWORK_STATE       获取网络信息状态,如当前的网络连接是否有效 

获取WiFi状态    android.permission.ACCESS_WIFI_STATE    获取当前WiFi接入的状态以及WLAN热点的信息 

改变网络状态    android.permission.CHANGE_NETWORK_STATE           改变网络状态如是否能联网

改变WiFi多播状态    android.permission.CHANGE_WIFI_MULTICAST_STATE    改变WiFi多播状态

改变WiFi状态    android.permission.CHANGE_WIFI_STATE        改变WiFi状态 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

账户管理

账户管理    android.permission.ACCOUNT_MANAGER      获取账户验证信息,主要为GMail账户信息,只有系统级进程才能访问的权限    

验证账户    android.permission.AUTHENTICATE_ACCOUNTS        允许一个程序通过账户验证方式访问账户管理ACCOUNT_MANAGER相关信息   

访问账户Gmail列表    android.permission.GET_ACCOUNTS  访问GMail账户列表    

管理账户    android.permission.MANAGE_ACCOUNTS      允许程序管理AccountManager中的账户列表  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

底层操作相关权限

访问Surface Flinger    android.permission.ACCESS_SURFACE_FLINGER      Android平台上底层的图形显示支持,一般用于游戏或照相机预览界面和底层模式的屏幕截图  

变成砖头    android.permission.BRICK                能够禁用手机,非常危险,顾名思义就是让手机变成砖头  

硬件测试    android.permission.HARDWARE_TEST        访问硬件辅助设备,用于硬件测试  

底层访问权限    android.permission.CWJ_GROUP  允许CWJ账户组访问底层信息 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

蓝牙 通话 拍照

使用蓝牙    android.permission.BLUETOOTH            允许程序连接配对过的蓝牙设备  

蓝牙管理    android.permission.BLUETOOTH_ADMIN          允许程序进行发现和配对新的蓝牙设备  

拨打电话    android.permission.CALL_PHONE       允许程序从非系统拨号器里输入电话号码

通话权限    android.permission.CALL_PRIVILEGED      允许程序拨打电话,替换系统的拨号器界面    

拍照权限    android.permission.CAMERA           允许访问摄像头进行拍照  

使用闪光灯    android.permission.FLASHLIGHT      允许访问闪光灯        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

清理缓存 应用数据 应用操作

应用删除时广播    android.permission.BROADCAST_PACKAGE_REMOVED 当一个应用在删除时触发一个广播    

删除缓存文件    android.permission.DELETE_CACHE_FILES 允许应用删除缓存文件   

删除应用    android.permission.DELETE_PACKAGES      允许程序删除应用    

清除应用缓存    android.permission.CLEAR_APP_CACHE        清除应用缓存 

清除用户数据    android.permission.CLEAR_APP_USER_DATA        清除应用的用户数据  

结束后台进程    android.permission.KILL_BACKGROUND_PROCESSES  允许程序调用killBackgroundProcesses(String).方法结束后台进程 

安装应用程序    android.permission.INSTALL_PACKAGES       允许程序安装应用  

强制后退    android.permission.FORCE_BACK       允许程序强制使用back后退按键,无论Activity是否在顶层  

改变配置    android.permission.CHANGE_CONFIGURATION         允许当前应用改变配置,如定位   

应用诊断    android.permission.DIAGNOSTIC       允许程序到RW到诊断资源   

手机优化大师扩展权限    android.permission.CELL_PHONE_MASTER_EX       手机优化大师扩展权限  

获取应用大小    android.permission.GET_PACKAGE_SIZE   获取应用的文件大小 

获取任务信息    android.permission.GET_TASKS      允许程序获取当前或最近运行的应用  

允许全局搜索    android.permission.GLOBAL_SEARCH      允许程序使用全局搜索功能    

注射事件    android.permission.INJECT_EVENTS        允许访问本程序的底层事件,获取按键、轨迹球的事件流    

内部系统窗口    android.permission.INTERNAL_SYSTEM_WINDOW     允许程序打开内部窗口,不对第三方应用程序开放此权限   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

电量 状态栏 壁纸

电量统计    android.permission.BATTERY_STATS        获取电池电量统计信息 

电源管理    android.permission.DEVICE_POWER     允许访问底层电源管理    

状态栏控制    android.permission.EXPAND_STATUS_BAR   允许程序扩展或收缩状态栏  

绑定壁纸    android.permission.BIND_WALLPAPER       必须通过WallpaperService服务来请求,只有系统才能用    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

其他

绑定小插件    android.permission.BIND_APPWIDGET      允许一个程序告诉appWidget服务需要访问小插件的数据库,只有非常少的应用才用到此权限   

绑定设备管理    android.permission.BIND_DEVICE_ADMIN      请求系统管理员接收者receiver,只有系统才能使用    

绑定输入法    android.permission.BIND_INPUT_METHOD       请求InputMethodService服务,只有系统才能使用    

绑定RemoteView    android.permission.BIND_REMOTEVIEWS     必须通过RemoteViewsService服务来请求,只有系统才能用  

收到短信时广播    android.permission.BROADCAST_SMS     当收到短信时触发一个广播   

连续广播    android.permission.BROADCAST_STICKY         允许一个程序收到广播后快速收到下一个广播    

WAP PUSH广播    android.permission.BROADCAST_WAP_PUSH     WAPPUSH服务收到后触发一个广播    

改变组件状态    android.permission.CHANGE_COMPONENT_ENABLED_STATE     改变组件是否启用状态 

禁用键盘锁    android.permission.DISABLE_KEYGUARD    允许程序禁用键盘锁    

转存系统信息    android.permission.DUMP       允许程序获取系统dump信息从系统服务    

工厂测试模式    android.permission.FACTORY_TEST       允许程序运行工厂测试模式    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Part Two

普通权限的总结:

ACCESS_LOCATION_EXTRA_COMMANDS 定位权限 
ACCESS_NETWORK_STATE 网络状态权限 
ACCESS_NOTIFICATION_POLICY 通知 APP通知显示在状态栏 
ACCESS_WIFI_STATE WiFi状态权限 
BLUETOOTH 使用蓝牙权限 
BLUETOOTH_ADMIN 控制蓝牙开关 
BROADCAST_STICKY 粘性广播 
CHANGE_NETWORK_STATE 改变网络状态 
CHANGE_WIFI_MULTICAST_STATE 改变WiFi多播状态,应该是控制手机热点(猜测) 
CHANGE_WIFI_STATE 控制WiFi开关,改变WiFi状态 
DISABLE_KEYGUARD 改变键盘为不可用 
EXPAND_STATUS_BAR 扩展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 删除快捷方式 
以上这些只是普通权限,我们开发的时候,正常使用就行了,需要的权限在清单文件配置即可。

危险权限

这类权限需要在需要的时候,需要我们动态申请,比如:当我们需要打开相机拍摄照片的时候需要我们通过代码的方式在需要的地方去申请权限。Android6.0中权限问题中我们需要注意的是:

1:由于权限API的问题,我们的Actiivty最好是AppCompatActivity类型的,也就是说在你的BaseActivity需要继承AppCompatActivity 
2:权限是分组的,同一组的权限申请其中一个,同组的权限就全部都申请了

特殊权限 组:

CALENDAR    日历
CAMERA 相机
CONTACTS 联系人
LOCATION 定位
MICROPHONE 麦克相关,比如录音
PHONE 手机状态
SENSORS 传感器
SMS 短信
STORAGE 存储权限
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

具体的权限分组情况如下表: 

Part Three

请求权限实现:

使用的API:

6.0的运行时权限,我们最终都是要支持的,通常我们需要使用如下的API 
int checkSelfPermission(String permission) 用来检测应用是否已经具有权限,这个方法是在API23中才有的,为了兼容低版本,建议使用v4包中的ContextCompat.checkSelfPermission,在下面的注意事项中有解释,这里就不在赘述了 
void requestPermissions(String[] permissions, int requestCode) 进行请求单个或多个权限,第一个参数是请求的权限集合,第二个参数是请求码,在回调监听中可以用来判断是哪个权限请求的结果 
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 用户对请求作出响应后的回调,请求成功或者失败的监听 
shouldShowRequestPermissionRationale这个API可以帮我们判断接下来的对话框是否包含”不再询问“选择框。在6.0之前的版本永远返回的是fasle 
比如我们请求CAMERA权限:

@Override
public void onClick(View v) { // 一个按钮的点击事件
if (!(checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)) { // 检查权限
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) { // 6.0之前的手机返回的都是true(清单文件配置了的前提下)
Toast.makeText(this, "Please grant the permission this time", Toast.LENGTH_LONG).show();
}
requestReadContactsPermission();
} else {
Log.i(LOGTAG, "onClick granted");
}
} private static final int REQUEST_PERMISSION_CAMERA_CODE = 1;
private void requestCameraPermission() {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CAMERA_CODE);
} /*
* 结果回调
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_CAMERA_CODE) {
int grantResult = grantResults[0];
boolean granted = grantResult == PackageManager.PERMISSION_GRANTED; // 请求权限的结果 true代表用户同意了
Log.i(LOGTAG, "onRequestPermissionsResult granted=" + granted);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

以上是Android提供给我们的申请一个权限时的方式。如果我们想同时申请多个权限就应该写为如下方式:

private static final int REQUEST_CODE = 1;
private void requestMultiplePermissions() {
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE};
requestPermissions(permissions, REQUEST_CODE);
}
  • 1
  • 2
  • 3
  • 4
  • 5

上面的方式是Android提供给我们的请求方式,这种方式的好处是完全使用Android提供的api没有引入别的依赖,如果公司对应用安装包的大小比较在意的话,建议使用原生的。

使用RxJava动态请求权限

首先app的build.gradle添加依赖:

dependencies {
compile 'com.tbruyelle.rxpermissions:rxpermissions:0.7.0@aar'
compile 'io.reactivex:rxjava:1.1.6'
}
  • 1
  • 2
  • 3
  • 4

然后就是使用

public void requestPermission(){
RxPermissions.getInstance(this)
.request(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)//这里申请了两组权限
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean granted) {
if (granted) {
//同意
...
} else {
//不同意
Toast.makeText(LaunchActivity.this, "请同意**的权限,才能继续提供服务", Toast.LENGTH_LONG).show();
}
}
});
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Part Four

注意事项

API问题

由于checkSelfPermission和requestPermissions从API 23才加入,低于23版本,需要在运行时判断 或者使用Support Library v4中提供的方法

ContextCompat.checkSelfPermission 
ActivityCompat.requestPermissions 
ActivityCompat.shouldShowRequestPermissionRationale

多系统问题

当我们支持了6.0必须也要支持4.4,5.0这些系统,所以需要在很多情况下,需要有两套处理。比如Camera权限

if (isMarshmallow()) {
requestPermission();//然后在回调中处理
} else {
useCamera();//低于6.0直接使用Camera
}
  • 1
  • 2
  • 3
  • 4
  • 5

两个特殊权限

特殊权限,顾名思义,就是一些特别敏感的权限,在Android系统中,主要由两个

SYSTEM_ALERT_WINDOW,设置悬浮窗,进行一些黑科技 
WRITE_SETTINGS 修改系统设置

关于上面两个特殊权限的授权,做法是使用startActivityForResult启动授权界面来完成。

请求SYSTEM_ALERT_WINDOW

private static final int REQUEST_CODE = 1;
private void requestAlertWindowPermission() {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
Log.i(LOGTAG, "onActivityResult granted");
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上述代码需要注意的是 
使用Action Settings.ACTION_MANAGE_OVERLAY_PERMISSION启动隐式Intent 
使用”package:” + getPackageName()携带App的包名信息 
使用Settings.canDrawOverlays方法判断授权结果

请求WRITE_SETTINGS

private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
private void requestWriteSettings() {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
if (Settings.System.canWrite(this)) {
Log.i(LOGTAG, "onActivityResult write settings granted" );
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上述代码需要注意的是 
使用Action Settings.ACTION_MANAGE_WRITE_SETTINGS 启动隐式Intent 
使用”package:” + getPackageName()携带App的包名信息 
使用Settings.System.canWrite方法检测授权结果

最后

注意:关于上面这两个特殊权限,一般不建议应用申请。

Part One

权限区分 
Android 6.0 为了保护用户隐私,将一些权限的申请放在了应用运行的时候去申请, 比如以往的开发中,开发人员只需要将需要的权限在清单文件中配置即可,安装后用户可以在设置中的应用信息中看到:XX应用以获取**权限。用户点击可以选择给应用相应的权限。此前的应用权限用户可以选择允许、提醒和拒绝。在安装的时候用户是已经知道应用需要的权限的。但是这样存在一个问题,就是用户在安装的时候,应用需要的权限十分的多(有些开发者为了省事,会请求一些不必要的权限或者请求全部的权限),这个时候用户在安装应用的时候也许并没有发现某些侵犯自己隐私的权限请求,安装之后才发现自己的隐私数据被窃取。其实Android6.0 动态权限一方面是为了广大用户考虑,另一方面其实是Google为了避免一些不必要的官司。但是这样做可实在是苦了程序员了。不过还好,权限不是所有的都需要动态申请,下面就说一下Android6.0对权限的分割: 
一、普通权限 
这类的权限不需要动态申请,需要这个权限的时候还是按照以往的做法,在清单文件中申请相应的权限即可,在安装的时候会展示给用户,用户同意安装就获取相应的权限。写法举例如下: 
清单文件中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.deepai.paipai"> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
........
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

下面是对权限的总结: 
android.permission.EXPAND_STATUS_BAR 允许一个程序扩展收缩在状态栏,android开发网提示应该是一个类似Windows Mobile中的托盘程序 
android.permission.FACTORY_TEST 作为一个工厂测试程序,运行在root用户 
android.permission.FLASHLIGHT 访问闪光灯,android开发网提示HTC Dream不包含闪光灯 
android.permission.FORCE_BACK 允许程序强行一个后退操作是否在顶层activities 
android.permission.FOTA_UPDATE 暂时不了解这是做什么使用的,android开发网分析可能是一个预留权限. 
android.permission.GET_ACCOUNTS 访问一个帐户列表在Accounts Service中 
android.permission.GET_PACKAGE_SIZE 允许一个程序获取任何package占用空间容量 
android.permission.GET_TASKS 允许一个程序获取信息有关当前或最近运行的任务,一个缩略的任务状态,是否活动等等 
android.permission.HARDWARE_TEST 允许访问硬件 
android.permission.INJECT_EVENTS 允许一个程序截获用户事件如按键、触摸、轨迹球等等到一个时间流,android开发网提醒算是hook技术吧 
android.permission.INSTALL_PACKAGES 允许一个程序安装应用 
android.permission.INTERNAL_SYSTEM_WINDOW 允许打开窗口使用系统用户界面 
android.permission.ACCESS_CHECKIN_PROPERTIES 允许读写访问“properties”表在checkin数据库中,改值可以修改上传。 
android.permission.ACCESS_COARSE_LOCATION 允许一个程序访问CellID或WiFi热点来获取粗略的位置 
android.permission.ACCESS_FINE_LOCATION 允许一个程序访问精良位置(如GPS) 
android.permission.WRITE_CONTACTS 允许程序写入但不读取用户联系人数据 
android.permission.WRITE_GSERVICES 允许程序修改Google服务地图 
android.permission.WRITE_OWNER_DATA 允许一个程序写入但不读取所有者数据 
android.permission.WRITE_SETTINGS 允许程序读取或写入系统设置 
android.permission.WRITE_SMS 允许程序写短信 
android.permission.WRITE_SYNC_SETTINGS 允许程序写入同步设置 
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 允许应用程序访问额外的位置提供命令 
android.permission.ACCESS_MOCK_LOCATION 允许程序创建模拟位置提供用于测试 
android.permission.ACCESS_NETWORK_STATE 允许程序访问有关GSM网络信息 
android.permission.ACCESS_SURFACE_FLINGER 允许程序使用SurfaceFlinger底层特性 
android.permission.ACCESS_WIFI_STATE 允许程序访问Wi-Fi网络状态信息 
android.permission.ADD_SYSTEM_SERVICE 允许程序发布系统级服务 
android.permission.BATTERY_STATS 允许程序更新手机电池统计信息 
android.permission.BLUETOOTH 允许程序连接到已配对的蓝牙设备 
android.permission.BLUETOOTH_ADMIN 允许程序发现和配对蓝牙设备 
android.permission.BROADCAST_PACKAGE_REMOVED 允许程序广播一个提示消息在一个应用程序包已经移除后 
android.permission.BROADCAST_STICKY 允许一个程序广播常用intents 
android.permission.CALL_PHONE 允许一个程序初始化一个电话拨号不需通过拨号用户界面需要用户确认 
android.permission.DELETE_CACHE_FILES 允许程序删除缓存文件 
android.permission.DELETE_PACKAGES 允许一个程序删除包 
android.permission.DEVICE_POWER 允许访问底层电源管理 
android.permission.DIAGNOSTIC 允许程序RW诊断资源 
android.permission.DISABLE_KEYGUARD 允许程序禁用键盘锁 
android.permission.DUMP 允许程序返回状态抓取信息从系统服务 
android.permission.CALL_PRIVILEGED 允许一个程序拨打任何号码,包含紧急号码无需通过拨号用户界面需要用户确认 
android.permission.CAMERA 请求访问使用照相设备 
android.permission.CHANGE_COMPONENT_ENABLED_STATE 允许一个程序是否改变一个组件或其他的启用或禁用 
android.permission.CHANGE_CONFIGURATION 允许一个程序修改当前设置,如本地化 
android.permission.CHANGE_NETWORK_STATE 允许程序改变网络连接状态 
android.permission.CHANGE_WIFI_STATE 允许程序改变Wi-Fi连接状态 
android.permission.CLEAR_APP_CACHE 允许一个程序清楚缓存从所有安装的程序在设备中 
android.permission.CLEAR_APP_USER_DATA 允许一个程序清除用户设置 
android.permission.CONTROL_LOCATION_UPDATES 允许启用禁止位置更新提示从无线模块 
android.permission.REBOOT 请求能够重新启动设备 
android.permission.RECEIVE_BOOT_COMPLETED 允许一个程序接收到ACTION_BOOT_COMPLETED 广播在系统完成启动 
android.permission.RECEIVE_MMS 允许一个程序监控将收到MMS彩信,记录或处理 
android.permission.RECEIVE_SMS 允许程序监控一个将收到短信息,记录或处理 
android.permission.RECEIVE_WAP_PUSH 允许程序监控将收到WAP PUSH信息 
android.permission.RECORD_AUDIO 允许程序录制音频 
android.permission.REORDER_TASKS 允许程序改变Z轴排列任务 
android.permission.RESTART_PACKAGES 允许程序重新启动其他程序 
android.permission.SEND_SMS 允许程序发送SMS短信 
android.permission.INTERNET 允许程序打开网络套接字 
android.permission.MANAGE_APP_TOKENS 允许程序管理(创建、催后、 z-order默认向z轴推移)程序引用在窗口管理器中 
android.permission.MASTER_CLEAR 目前还没有明确的解释,android开发网分析可能是清除一切数据,类似硬格机 
android.permission.MODIFY_AUDIO_SETTINGS 允许程序修改全局音频设置 
android.permission.MODIFY_PHONE_STATE 允许修改话机状态,如电源,人机接口等 
android.permission.MOUNT_UNMOUNT_FILESYSTEMS 允许挂载和反挂载文件系统可移动存储 
android.permission.PERSISTENT_ACTIVITY 允许一个程序设置他的activities显示 
android.permission.PROCESS_OUTGOING_CALLS 允许程序监视、修改有关播出电话 
android.permission.READ_CALENDAR 允许程序读取用户日历数据 
android.permission.READ_CONTACTS 允许程序读取用户联系人数据 
android.permission.READ_FRAME_BUFFER 允许程序屏幕波或和更多常规的访问帧缓冲数据 
android.permission.READ_INPUT_STATE 允许程序返回当前按键状态 
android.permission.READ_LOGS 允许程序读取底层系统日志文件 
android.permission.READ_OWNER_DATA 允许程序读取所有者数据 
android.permission.READ_SMS 允许程序读取短信息 
android.permission.READ_SYNC_SETTINGS 允许程序读取同步设置 
android.permission.READ_SYNC_STATS 允许程序读取同步状态 
android.permission.SET_ACTIVITY_WATCHER 允许程序监控或控制activities已经启动全局系统中 
android.permission.SET_ALWAYS_FINISH 允许程序控制是否活动间接完成在处于后台时 
android.permission.SET_ANIMATION_SCALE 修改全局信息比例 
android.permission.SET_DEBUG_APP 配置一个程序用于调试 
android.permission.SET_ORIENTATION 允许底层访问设置屏幕方向和实际旋转 
android.permission.SET_PREFERRED_APPLICATIONS 允许一个程序修改列表参数PackageManager.addPackageToPreferred()和PackageManager.removePackageFromPreferred()方法 
android.permission.SET_PROCESS_FOREGROUND 允许程序当前运行程序强行到前台 
android.permission.SET_PROCESS_LIMIT 允许设置最大的运行进程数量 
android.permission.SET_TIME_ZONE 允许程序设置时间区域 
android.permission.SET_WALLPAPER 允许程序设置壁纸 
android.permission.SET_WALLPAPER_HINTS 允许程序设置壁纸hits 
android.permission.SIGNAL_PERSISTENT_PROCESSES 允许程序请求发送信号到所有显示的进程中 
android.permission.STATUS_BAR 允许程序打开、关闭或禁用状态栏及图标Allows an application toopen, close, or disable the status bar and its icons. 
android.permission.SUBSCRIBED_FEEDS_READ 允许一个程序访问订阅RSS Feed内容提供 
android.permission.SUBSCRIBED_FEEDS_WRITE 系统暂时保留改设置,android开发网认为未来版本会加入该功能。 
android.permission.SYSTEM_ALERT_WINDOW 允许一个程序打开窗口使用TYPE_SYSTEM_ALERT,显示在其他所有程序的顶层 
android.permission.VIBRATE 允许访问振动设备 
android.permission.WAKE_LOCK 允许使用PowerManager的 WakeLocks保持进程在休眠时从屏幕消失 
android.permission.WRITE_APN_SETTINGS 允许程序写入API设置 
android.permission.WRITE_CALENDAR 允许一个程序写入但不读取用户日历数据

可以看出Android中对资源以及服务的访问都非常严格,另外,在程序打包成APK的时候也需要对软件进行签名。

定位相关权限

获取精确位置    android.permission.ACCESS_FINE_LOCATION       通过GPS芯片接收卫星的定位信息,定位精度达10米以内  

访问定位额外命令    android.permission.ACCESS_LOCATION_EXTRA_COMMANDS   允许程序访问额外的定位提供者指令 

获取模拟定位信息    android.permission.ACCESS_MOCK_LOCATION 获取模拟定位信息,一般用于帮助开发者调试应用  

控制定位更新    android.permission.CONTROL_LOCATION_UPDATES       允许获得移动网络定位信息改变      

安装定位提供    android.permission.INSTALL_LOCATION_PROVIDER  安装定位提供 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

网络状态

访问网络    android.permission.INTERNET     访问网络连接,可能产生GPRS流量    

获取网络状态    android.permission.ACCESS_NETWORK_STATE       获取网络信息状态,如当前的网络连接是否有效 

获取WiFi状态    android.permission.ACCESS_WIFI_STATE    获取当前WiFi接入的状态以及WLAN热点的信息 

改变网络状态    android.permission.CHANGE_NETWORK_STATE           改变网络状态如是否能联网

改变WiFi多播状态    android.permission.CHANGE_WIFI_MULTICAST_STATE    改变WiFi多播状态

改变WiFi状态    android.permission.CHANGE_WIFI_STATE        改变WiFi状态 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

账户管理

账户管理    android.permission.ACCOUNT_MANAGER      获取账户验证信息,主要为GMail账户信息,只有系统级进程才能访问的权限    

验证账户    android.permission.AUTHENTICATE_ACCOUNTS        允许一个程序通过账户验证方式访问账户管理ACCOUNT_MANAGER相关信息   

访问账户Gmail列表    android.permission.GET_ACCOUNTS  访问GMail账户列表    

管理账户    android.permission.MANAGE_ACCOUNTS      允许程序管理AccountManager中的账户列表  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

底层操作相关权限

访问Surface Flinger    android.permission.ACCESS_SURFACE_FLINGER      Android平台上底层的图形显示支持,一般用于游戏或照相机预览界面和底层模式的屏幕截图  

变成砖头    android.permission.BRICK                能够禁用手机,非常危险,顾名思义就是让手机变成砖头  

硬件测试    android.permission.HARDWARE_TEST        访问硬件辅助设备,用于硬件测试  

底层访问权限    android.permission.CWJ_GROUP  允许CWJ账户组访问底层信息 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

蓝牙 通话 拍照

使用蓝牙    android.permission.BLUETOOTH            允许程序连接配对过的蓝牙设备  

蓝牙管理    android.permission.BLUETOOTH_ADMIN          允许程序进行发现和配对新的蓝牙设备  

拨打电话    android.permission.CALL_PHONE       允许程序从非系统拨号器里输入电话号码

通话权限    android.permission.CALL_PRIVILEGED      允许程序拨打电话,替换系统的拨号器界面    

拍照权限    android.permission.CAMERA           允许访问摄像头进行拍照  

使用闪光灯    android.permission.FLASHLIGHT      允许访问闪光灯        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

清理缓存 应用数据 应用操作

应用删除时广播    android.permission.BROADCAST_PACKAGE_REMOVED 当一个应用在删除时触发一个广播    

删除缓存文件    android.permission.DELETE_CACHE_FILES 允许应用删除缓存文件   

删除应用    android.permission.DELETE_PACKAGES      允许程序删除应用    

清除应用缓存    android.permission.CLEAR_APP_CACHE        清除应用缓存 

清除用户数据    android.permission.CLEAR_APP_USER_DATA        清除应用的用户数据  

结束后台进程    android.permission.KILL_BACKGROUND_PROCESSES  允许程序调用killBackgroundProcesses(String).方法结束后台进程 

安装应用程序    android.permission.INSTALL_PACKAGES       允许程序安装应用  

强制后退    android.permission.FORCE_BACK       允许程序强制使用back后退按键,无论Activity是否在顶层  

改变配置    android.permission.CHANGE_CONFIGURATION         允许当前应用改变配置,如定位   

应用诊断    android.permission.DIAGNOSTIC       允许程序到RW到诊断资源   

手机优化大师扩展权限    android.permission.CELL_PHONE_MASTER_EX       手机优化大师扩展权限  

获取应用大小    android.permission.GET_PACKAGE_SIZE   获取应用的文件大小 

获取任务信息    android.permission.GET_TASKS      允许程序获取当前或最近运行的应用  

允许全局搜索    android.permission.GLOBAL_SEARCH      允许程序使用全局搜索功能    

注射事件    android.permission.INJECT_EVENTS        允许访问本程序的底层事件,获取按键、轨迹球的事件流    

内部系统窗口    android.permission.INTERNAL_SYSTEM_WINDOW     允许程序打开内部窗口,不对第三方应用程序开放此权限   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

电量 状态栏 壁纸

电量统计    android.permission.BATTERY_STATS        获取电池电量统计信息 

电源管理    android.permission.DEVICE_POWER     允许访问底层电源管理    

状态栏控制    android.permission.EXPAND_STATUS_BAR   允许程序扩展或收缩状态栏  

绑定壁纸    android.permission.BIND_WALLPAPER       必须通过WallpaperService服务来请求,只有系统才能用    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

其他

绑定小插件    android.permission.BIND_APPWIDGET      允许一个程序告诉appWidget服务需要访问小插件的数据库,只有非常少的应用才用到此权限   

绑定设备管理    android.permission.BIND_DEVICE_ADMIN      请求系统管理员接收者receiver,只有系统才能使用    

绑定输入法    android.permission.BIND_INPUT_METHOD       请求InputMethodService服务,只有系统才能使用    

绑定RemoteView    android.permission.BIND_REMOTEVIEWS     必须通过RemoteViewsService服务来请求,只有系统才能用  

收到短信时广播    android.permission.BROADCAST_SMS     当收到短信时触发一个广播   

连续广播    android.permission.BROADCAST_STICKY         允许一个程序收到广播后快速收到下一个广播    

WAP PUSH广播    android.permission.BROADCAST_WAP_PUSH     WAPPUSH服务收到后触发一个广播    

改变组件状态    android.permission.CHANGE_COMPONENT_ENABLED_STATE     改变组件是否启用状态 

禁用键盘锁    android.permission.DISABLE_KEYGUARD    允许程序禁用键盘锁    

转存系统信息    android.permission.DUMP       允许程序获取系统dump信息从系统服务    

工厂测试模式    android.permission.FACTORY_TEST       允许程序运行工厂测试模式    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Part Two

普通权限的总结:

ACCESS_LOCATION_EXTRA_COMMANDS 定位权限 
ACCESS_NETWORK_STATE 网络状态权限 
ACCESS_NOTIFICATION_POLICY 通知 APP通知显示在状态栏 
ACCESS_WIFI_STATE WiFi状态权限 
BLUETOOTH 使用蓝牙权限 
BLUETOOTH_ADMIN 控制蓝牙开关 
BROADCAST_STICKY 粘性广播 
CHANGE_NETWORK_STATE 改变网络状态 
CHANGE_WIFI_MULTICAST_STATE 改变WiFi多播状态,应该是控制手机热点(猜测) 
CHANGE_WIFI_STATE 控制WiFi开关,改变WiFi状态 
DISABLE_KEYGUARD 改变键盘为不可用 
EXPAND_STATUS_BAR 扩展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 删除快捷方式 
以上这些只是普通权限,我们开发的时候,正常使用就行了,需要的权限在清单文件配置即可。

危险权限

这类权限需要在需要的时候,需要我们动态申请,比如:当我们需要打开相机拍摄照片的时候需要我们通过代码的方式在需要的地方去申请权限。Android6.0中权限问题中我们需要注意的是:

1:由于权限API的问题,我们的Actiivty最好是AppCompatActivity类型的,也就是说在你的BaseActivity需要继承AppCompatActivity 
2:权限是分组的,同一组的权限申请其中一个,同组的权限就全部都申请了

特殊权限 组:

CALENDAR    日历
CAMERA 相机
CONTACTS 联系人
LOCATION 定位
MICROPHONE 麦克相关,比如录音
PHONE 手机状态
SENSORS 传感器
SMS 短信
STORAGE 存储权限
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

具体的权限分组情况如下表: 

Part Three

请求权限实现:

使用的API:

6.0的运行时权限,我们最终都是要支持的,通常我们需要使用如下的API 
int checkSelfPermission(String permission) 用来检测应用是否已经具有权限,这个方法是在API23中才有的,为了兼容低版本,建议使用v4包中的ContextCompat.checkSelfPermission,在下面的注意事项中有解释,这里就不在赘述了 
void requestPermissions(String[] permissions, int requestCode) 进行请求单个或多个权限,第一个参数是请求的权限集合,第二个参数是请求码,在回调监听中可以用来判断是哪个权限请求的结果 
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 用户对请求作出响应后的回调,请求成功或者失败的监听 
shouldShowRequestPermissionRationale这个API可以帮我们判断接下来的对话框是否包含”不再询问“选择框。在6.0之前的版本永远返回的是fasle 
比如我们请求CAMERA权限:

@Override
public void onClick(View v) { // 一个按钮的点击事件
if (!(checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)) { // 检查权限
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) { // 6.0之前的手机返回的都是true(清单文件配置了的前提下)
Toast.makeText(this, "Please grant the permission this time", Toast.LENGTH_LONG).show();
}
requestReadContactsPermission();
} else {
Log.i(LOGTAG, "onClick granted");
}
} private static final int REQUEST_PERMISSION_CAMERA_CODE = 1;
private void requestCameraPermission() {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CAMERA_CODE);
} /*
* 结果回调
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_CAMERA_CODE) {
int grantResult = grantResults[0];
boolean granted = grantResult == PackageManager.PERMISSION_GRANTED; // 请求权限的结果 true代表用户同意了
Log.i(LOGTAG, "onRequestPermissionsResult granted=" + granted);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

以上是Android提供给我们的申请一个权限时的方式。如果我们想同时申请多个权限就应该写为如下方式:

private static final int REQUEST_CODE = 1;
private void requestMultiplePermissions() {
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE};
requestPermissions(permissions, REQUEST_CODE);
}
  • 1
  • 2
  • 3
  • 4
  • 5

上面的方式是Android提供给我们的请求方式,这种方式的好处是完全使用Android提供的api没有引入别的依赖,如果公司对应用安装包的大小比较在意的话,建议使用原生的。

使用RxJava动态请求权限

首先app的build.gradle添加依赖:

dependencies {
compile 'com.tbruyelle.rxpermissions:rxpermissions:0.7.0@aar'
compile 'io.reactivex:rxjava:1.1.6'
}
  • 1
  • 2
  • 3
  • 4

然后就是使用

public void requestPermission(){
RxPermissions.getInstance(this)
.request(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)//这里申请了两组权限
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean granted) {
if (granted) {
//同意
...
} else {
//不同意
Toast.makeText(LaunchActivity.this, "请同意**的权限,才能继续提供服务", Toast.LENGTH_LONG).show();
}
}
});
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Part Four

注意事项

API问题

由于checkSelfPermission和requestPermissions从API 23才加入,低于23版本,需要在运行时判断 或者使用Support Library v4中提供的方法

ContextCompat.checkSelfPermission 
ActivityCompat.requestPermissions 
ActivityCompat.shouldShowRequestPermissionRationale

多系统问题

当我们支持了6.0必须也要支持4.4,5.0这些系统,所以需要在很多情况下,需要有两套处理。比如Camera权限

if (isMarshmallow()) {
requestPermission();//然后在回调中处理
} else {
useCamera();//低于6.0直接使用Camera
}
  • 1
  • 2
  • 3
  • 4
  • 5

两个特殊权限

特殊权限,顾名思义,就是一些特别敏感的权限,在Android系统中,主要由两个

SYSTEM_ALERT_WINDOW,设置悬浮窗,进行一些黑科技 
WRITE_SETTINGS 修改系统设置

关于上面两个特殊权限的授权,做法是使用startActivityForResult启动授权界面来完成。

请求SYSTEM_ALERT_WINDOW

private static final int REQUEST_CODE = 1;
private void requestAlertWindowPermission() {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
Log.i(LOGTAG, "onActivityResult granted");
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上述代码需要注意的是 
使用Action Settings.ACTION_MANAGE_OVERLAY_PERMISSION启动隐式Intent 
使用”package:” + getPackageName()携带App的包名信息 
使用Settings.canDrawOverlays方法判断授权结果

请求WRITE_SETTINGS

private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
private void requestWriteSettings() {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
if (Settings.System.canWrite(this)) {
Log.i(LOGTAG, "onActivityResult write settings granted" );
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上述代码需要注意的是 
使用Action Settings.ACTION_MANAGE_WRITE_SETTINGS 启动隐式Intent 
使用”package:” + getPackageName()携带App的包名信息 
使用Settings.System.canWrite方法检测授权结果

最后

注意:关于上面这两个特殊权限,一般不建议应用申请。

Android 6.0动态权限(转)的更多相关文章

  1. android 6.0 动态权限

    Android 6.0 动态权限: 除了要在AndroidManifest.xml中申请外,还需使用时,请求用户允许授权. 以下是需要单独申请的权限,共分为9组,每组只要有一个权限申请成功了,就默认整 ...

  2. Android 6.0动态权限申请

    转载(Android 6.0 动态权限申请简单简洁优雅的处理方式): https://blog.csdn.net/lin_dianwei/article/details/79025324

  3. Android 6.0 - 动态权限管理的解决方案(转)

    转自:http://www.cnblogs.com/dubo-/p/6018262.html Android 6.0 - 动态权限管理的解决方案   转载请标注 Android 6.0版本(Api 2 ...

  4. android 6.0+ 动态权限 拒绝不再询问后跳转设置应用详情页面

    android 6.0+ 的权限 需要动态申请 这里的权限针对的是 敏感权限: SMS(短信) SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEI ...

  5. Android 6.0 动态权限申请注意事项

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/uana_777/article/details/54136255 Part One 权限区分 And ...

  6. Android 6.0 - 动态权限管理的解决方案

    Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...

  7. Android 6.0 动态权限申请

    1. 概述 Android 6.0 (API 23) 之前应用的权限在安装时全部授予,运行时应用不再需要询问用户.在 Android 6.0 或更高版本对权限进行了分类,对某些涉及到用户隐私的权限可在 ...

  8. Android 6.0动态权限申请教程

    转载请标明出处: http://www.cnblogs.com/why168888/p/6580396.html 本文出自:[Edwin博客园] PermissionManage 介绍 如果设备运行的 ...

  9. Android 6.0的权限问题

    Android 6.0的权限获取不同于别的版本,具体的实例如下: if (ContextCompat.checkSelfPermission(this, Manifest.permission.REA ...

随机推荐

  1. C++之友元机制(友元函数和友元类)

    一.为什么引入友元机制? 总的来说就是为了让非成员函数即普通函数或其他类可以访问类的私有成员,这确实破坏了类的封装性和数据的隐蔽性,但为什么要这么做呢? (c++ primer:尽管友元被授予从外部访 ...

  2. 自己实现c++中string 类

    class String { public: String(const char *str = NULL);// 普通构造函数 String(const String &other);// 拷 ...

  3. 洛谷P4092树——并查集

    题目:https://www.luogu.org/problemnew/show/P4092 利用并查集,倒序离线,那么从倒序来看被撤销标记的点就再也不会被标记,所以用并查集跳过: 莫名其妙的WA,调 ...

  4. 第一行代码笔记的思维导图(http://images2015.cnblogs.com/blog/1089110/201704/1089110-20170413160323298-819915364.png)

  5. 动态规划专题 多阶段决策问题 蓝桥杯 K好数

    问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.20.22 ...

  6. 3.16 使用Zookeeper对HDFS HA配置自动故障转移及测试

    一.说明 从上一节可看出,虽然搭建好了HA架构,但是只能手动进行active与standby的切换: 接下来看一下用zookeeper进行自动故障转移: # 在启动HA之后,两个NameNode都是s ...

  7. java 中判断字符串相等

    今天写Java代码时遇到一个问题,就是关于判断两个字符串是否相等的问题.(刚尝试用SSH框架) 在大多编程中,通常比较两个字符串是否相同的表达式是“==”,但在java中不能这么写.在java中,用的 ...

  8. Jmeter调用JAVA jar包传参

    http://blog.csdn.net/xiazdong/article/details/7873767#

  9. Spring Boot 学习系列(08)—自定义servlet、filter及listener

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 传统的filter及listener配置 在传统的Java web项目中,servlet.filter和li ...

  10. Git小白到老鸟的进阶之路

    点"计算机视觉life"关注,置顶更快接收消息! 小白:师兄,师兄,上次你教我的操作,我傻乎乎的执行了一遍,可是那个Git究竟是什么那? 师兄:小白莫慌,Git就是一种版本控制,小 ...