android动态权限获取

  Android6.0采用新的权限模型,只有在需要权限的时候,才告知用户是否授权,是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候,需要先检查是否有所需要的权限申请。这样的用户的自主性提高很多,比如用户可以给APP赋予摄像的权限,但是可以拒绝记录设备位置的权限,就是怕位置信息上传等等。

PROTECTION_NORMAL类权限

当用户安装或更新应用时,系统将授予应用所请求的属于 PROTECTION_NORMAL 的所有权限(安装时授权的一类基本权限)。这类权限包括:

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT

只需要在AndroidManifest.xml中简单声明这些权限就好,安装时就授权。不需要每次使用时都检查权限,而且用户不能取消以上授权。

权限组

新的权限模型中还提出了一个权限组的概念,可以简单理解为如果一个权限组内的某个权限被获取了,那么这个组中剩余的权限也会被自动获取。

例如:Android.permission-group.CALENDAR中的android.permission.WRITE_CALENDAR 权限被获取,那么应用会自动获取android.permission.READ_CALENDAR权限。

动态权限获取:

判断是否已经拥有某项权限,如果没有则申请该权限。 并通过重载onRequestPermissionsResult()函数,监听权限申请的结果。通过requestCode判断是那一次的权限申请。

grantResult[0] 是否等于PackageManager.PERMISSION_GRANTED来判断 权限获取的成功与否。

 private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
insertDummyContact();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 123:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
Toast.makeText(this,"权限申请成功",Toast.LENGTH_SHORT).show();
} else {
// Permission Denied
Toast.makeText(MainActivity.this, "权限申请失败", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
 

requestPermission中第二个参数,为请求码。

shouldShowRequestPermissionRationale : 
  安装app后第一次调用权限申请: 返回false
第一次 禁止权限但是没有勾选下次不再提醒: 返回true
  如果第一次禁止权限并且勾选不再提醒: 返回 false 一般通过此函数,当返回true时 ,弹出对话框提醒用户 该权限的作用
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
showMessage("请允许应用对SD卡进行读写操作",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
Toast.makeText(this,"该权限必须获得才能实现某功能,请开通",LENGTH_SHORT).show;
}
});
return;
}
requestPermissions(
new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
REQUEST_CODE_ASK_PERMISSIONS);
}
private void showMessage(String message,
DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this).setMessage(message)
.setPositiveButton("OK", okListener).create().show();
}

用兼容库使代码兼容旧版

当把 minSDK设置成 13 targetSDK设置成 25时,不能调用requestPermission函数,报错:call requires api level 23 。

为了兼容minSDK 23以下在调用以上这三个接口时,可以增加一个判断:

 if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M )
requestPermissions(new String[] {Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_CODE);

这样做非常麻烦,我们可以使用 v4兼容库,已对这个做过兼容,用以下方法代替:

ContextCompat.checkSelfPermission()
被授权函数返回PERMISSION_GRANTED,否则返回PERMISSION_DENIED ,在所有版本都是如此。
ActivityCompat.requestPermissions()
这个方法在M之前版本调用,OnRequestPermissionsResultCallback 直接被调用,带着正确的 PERMISSION_GRANTED或者 PERMISSION_DENIED 。
ActivityCompat.shouldShowRequestPermissionRationale()
在M之前版本调用,永远返回false。
用v4包的这三方法,完美兼容所有版本!这个方法需要额外的参数,Context or Activity。别的就没啥特别的了。下面是代码:

参考:  https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

代码:git@github.com:lsfzlj/testDynamicPermission.git

android动态权限获取的更多相关文章

  1. checkSelfPermission 找不到 Android 动态权限问题

    checkSelfPermission 找不到 Android 动态权限问题  最近写了一个Demo,以前好好地.后来手机更新了新系统以后,不能用总是闪退.而且我的小伙伴的是android 7.0系统 ...

  2. Android M 动态权限获取

    新的权限获取方式除了要求像之前版本号一样在AndroidManifest文件里静态申请之外,应用还需依据须要请求权限,方式採用向用户显示一个请求权限的对话框. 这些被动态申请的权限能够在系统设置中被手 ...

  3. Android动态权限申请

    Android系统中,目前Dangerous级别的权限都需要动态申请.步骤如下: 1.AndroidManfiest.xml中申明需要的动态权限 <?xml version="1.0& ...

  4. Android 动态权限申请

    package com.dragon.android.permissionrequest; import android.Manifest; import android.content.Dialog ...

  5. Android平台targetSdkVersion设置及动态权限

    --关于Android动态权限和targetSdkVersion Android系统自6.0开始,提供动态权限机制,对于敏感权限(存储,定位,录音,拍照,录像等),需要在APP运行过程中动态向用户申请 ...

  6. 【Unity游戏开发】Android6.0以上的动态权限申请问题

    一.引子 最近公司的游戏在做安全性测试,期间也暴露出了不少安全上的问题.虽然我们今天要说的权限申请和安全性相关不大,但是也会影响到游戏的使用体验等,所以本篇博客中马三就想和大家谈谈Android6.0 ...

  7. Android动态获取权限

    android权限的变化 在Android6.0以前的版本的时候,Android的权限都是在安装的时候全部的配置完成的.然而这往往会造成一些安全的问题. Google的解决办法: 将Android中的 ...

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

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

  9. 如何兼容所有Android版本选择照片或拍照然后裁剪图片--基于FileProvider和动态权限的实现

    我们知道, Android操作系统一直在进化. 虽然说系统是越来越安全, 可靠, 但是对于开发者而言, 开发难度是越来越大的, 需要注意的兼容性问题, 也越来越多. 就比如在Android平台上拍照或 ...

随机推荐

  1. PHP中的mb_convert_encoding与iconv函数介绍

    php传输乱码 mb_convert_encoding这个函数是用来转换编码的.原来一直对程序编码这一概念不理解,不过现在好像有点开窍了. 不过英文一般不会存在编码问题,只有中文数据才会有这个问题.比 ...

  2. I/O Planning

    同一个BANK的电压必须是一样的,而电气特性则可以不同. 最近GTX调不出来,原来是电平不对 电源的影响 示波器看电源纹波 VCCO是为BANK的IO输出供电.比如LVCMOS33的信号,这个BANK ...

  3. struts 拦截器

    my-default.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts ...

  4. (并查集)Travel -- hdu -- 5441(2015 ACM/ICPC Asia Regional Changchun Online )

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 Travel Time Limit: 1500/1000 MS (Java/Others)    Memo ...

  5. This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed(在64位模式下运行安装了32位的Oracle客户端组件时,会发生此问题)

    部署win服务时出现下面的问题: 在事件查看器中看到如下错误: 日志名称: Application来源: ***调度服务日期: 2014/5/21 12:53:21事件 ID: 0任务类别: 无级别: ...

  6. 理解Struts2的Action中的setter方法是怎么工作的

    接触过webwork和Struts2的同行都应该知道, 提交表单的时候,只要Action中的属性有setter 方法,这些表单数据就可以正确赋值到Action中属性里:另外对于Spring配置文件中声 ...

  7. Internal Server Error - http code 500

    Eror Example 1 :  

  8. EBS Archiving and Purging: You Know you need to

    A number of trends in the IT industry have contributed to the increasing size of ERP application dat ...

  9. [翻译]Writing Custom Wizards 编写自定义的向导

    Writing Custom Wizards  编写自定义的向导   You can extend FastReport's functionality with the help of custom ...

  10. spring获取webapplicationcontext,applicationcontext几种方法详解(转)

    方法一:在初始化时保存ApplicationContext对象 代码: ApplicationContext ac = new FileSystemXmlApplicationContext(&quo ...