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. freeRadius与NetGear WNAP210的简使用

    1.下载安装freeRadius for win 2.2 2.配置client.cnf文件 加入 client 192.168.0.0/16{ secret=1111122222 shortname= ...

  2. C语言之控制台读取上下左右方向键指令

    首先,可以检测任何按键键值 // 首先,检测任何按键的代码 #include<stdio.h> #include<conio.h> int main() { char ch; ...

  3. Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut aaa

    这个错误是说,找不到这个注释: 解决方案: 1.更改自己本机的jdk版本(我的更改了无效): 在工程选择框内点击右键--->build path----->Library--->ad ...

  4. Bug中的中的小问题编程需要注意

    Bug中的中的小问题编程需要注意 1. 关于局部变量与全局变量是否同名问题 如果参数传递的是一个数组,且全局变量与参数数据同名,则局部变量作用域中,这两个同名的数据可能会引起冲突. 如下:如果一开始是 ...

  5. RandomForest in Spark MLLib

    决策树类模型 ml中的classification和regression主要基于以下几类: classification:决策树及其相关的集成算法,Logistics回归,多层感知模型: regres ...

  6. [ACM_动态规划] hdu1003 Max Sum [最大连续子串和]

    Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum ...

  7. 关于C_Sharp集中处理异常

    1.写在前面 “异常意味着什么?”,想必不用对此做多余的解释,我们有理由相信在任何情况下任何应用程序都有可能出现异常,若在程序中没有对异常进行处理,则操作系统会以粗暴的方式处理掉它(弹出错误提示框), ...

  8. sql 中如何查询某一列的数据在另一个表中有没有?

    假设表table1,列a,表table2,列bselect a from table1where a not in(select b from table2)

  9. 使用n g r o k将本地主机URL暴露给互联网

    在本地开发对接第三方服务的时候,对方有的时候会要求我们提供一个线上的URL地址.例如微信登录 1.下载ngrok https://ngrok.com/download 顺便注册一个账号(使用GitHu ...

  10. (php)实现万年历

    <?php //修改页面编码 header("content-type:text/html;charset=utf-8"); //获取当前年 $year=$_GET['y'] ...