在Android6.0以后开始,对于部分敏感的“危险”权限,需要在应用运行时向用户申请,只有用户允许的情况下这个权限才会被授予给应用。这对于用户来说,无疑是一个提升安全性的做法。那么对于开发者,应该怎么做呢?

Android6.0规定的危险权限有下面这些:

Permission Group Permissions
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE

从一个例子入手吧。假如在App中需要进行拨打电话的操作,当点击按钮,直接拨出一个电话,代码如下:

Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:10086"));
startActivity(intent);

但是如果你的编译版本是23或者以上,那么Android Studio就会报出一个错误

提示我们要进行权限请求。

如果我们直接对这个错误进行自动修复,会在startActivity方法之前增加一段代码用于权限检查,如果当前没有赋予该权限,则直接return结束方法:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}

如果这个时候直接运行,你的APP照样是没有得到这个权限的,因为默认安装的时候,这个权限会被关闭到,所以方法直接就返回了。要是需要在点击按钮的时候,直接向用户请求权限,可以使用下面的方法:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUESTCODE);

这个时候,再重新运行App,会得到下面的一个界面来请求用户权限:

允许:以后不再弹出请求框,直接允许应用获得该权限

拒绝:下次需要时会重新弹出,直到用户选择允许,否则会不断出现

那么问题就来了,如果用户勾选了不再询问拒绝了请求会怎样呢?答案是以后不会再弹出,并且默认拒绝权限请求,也就是说,应用再也不能获得这个权限,除非用户主动进入应用设置中重新授权。

为了更好的用户体验,可以在用户选择了不再询问和拒绝之后,创建一个AlertDialog来询问用户是否需要重新授予权限,是的话,跳转到应用设置界面。

当我们调用requestPermissions方法的时候,无论成功与否,都会将结果回调给Activity中的onRequestPermissionsResult方法中,我们可以通过重写这个方法来处理结果:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUESTCODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
AskForPermission();
}
}
}
}

先判断请求是否为我们所申请的,接着判断SDK的版本是否高于或等于AndroidM(6.0),如果是,则调用shouldShowRequestPermissionRationale方法来检查权限申请框是否会显示,因为如果用户选择了不再询问,则申请框会不出现,这个方法会返回false,如果申请框没有出现,则创建一个AlertDialog来询问用户:

private void AskForPermission() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Need Permission!");
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { }
});
builder.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName())); // 根据包名打开对应的设置界面
startActivity(intent);
}
});
builder.create().show();
}

Android开发学习之路-Android6.0运行时权限的更多相关文章

  1. Android6.0运行时权限(基于RxPermission开源库)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 在6.0以前的系统,都是权限一刀切的处理方式,只要用户安装,Manifest申请的权限都会被赋予,并且安装后权限也撤销不了. And ...

  2. Android6.0运行时权限管理

    自从Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifest设置就可以任意获取权限,而是更加的注重用户的隐私和体验,不会再强迫用户因拒绝不该拥有的权限而导致的无法安装 ...

  3. Android6.0运行时权限的处理Demo

    MainActivity.java package com.loaderman.permissionsdemo; import android.Manifest; import android.con ...

  4. Android权限管理之Android 6.0运行时权限及解决办法

    前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...

  5. Android 6.0+ 运行时权限

    1.权限被分为了普通和危险两种 2.打电话的Demo import android.Manifest; import android.app.Activity; import android.cont ...

  6. Android开发学习之路--Android Studio cmake编译ffmpeg

      最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...

  7. Android开发学习之路--网络编程之xml、json

    一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...

  8. Android开发学习之路--Activity之初体验

    环境也搭建好了,android系统也基本了解了,那么接下来就可以开始学习android开发了,相信这么学下去肯定可以把android开发学习好的,再加上时而再温故下linux下的知识,看看androi ...

  9. Android开发学习之路--Android系统架构初探

    环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...

随机推荐

  1. 动态SQL 学习

    <select id="findUser" parameterType="Map" resultType="User">     ...

  2. ASP.NET 给作为隐藏域的TextBox赋值之后提交表单,无响应?

    操作步骤: 给页面隐藏TextBox赋值,然后触发ASP.NET change事件,调用ASP.NET后台方法,调用后执行客户端脚本this.RegisterClientScriptBlock(Dat ...

  3. 《DSP using MATLAB》第6章开始了

    看到第6章了,标记一下,全书近一半,继续加油 构建滤波器的三种元件: 下面是函数floor和size的部分帮助截图

  4. LINQ 左右连接

    LINQ 左右连接:DefaultIfEmpty() incomeList = (from p in db.Incomes join m in db.Items on p.ItemID equals ...

  5. Mac使用总结

    显示隐藏文件 终端输入:defaults write com.apple.finder AppleShowAllFiles -bool true; KillAll Finder 添加SSHKey Ma ...

  6. python基本图像操作与处理

    # -*- coding: utf-8 -*- from PIL import Image from pylab import * #添加中文支持 from matplotlib.font_manag ...

  7. Python for Infomatics 第14章 数据库和SQL应用三(译)

    14.5 SQL 总结 到目前为止,我们在Python示例程序中使用了SQL,并且涉及了许多SQL基础.在这一小节中,我们特别审视SQL语言,并对其语法进行回顾. 虽然有很多不同的数据库供应商,但因S ...

  8. 本周PSP流程进度

    一计划 (1)估计这个任务需要多少时间:8天 二开发 (1)需求分析:作为一名观众,我希望了解每一场的比赛成绩,以便加深对自己喜爱球队的了解,以及赛况. (2)生成设计文档: (3)设计复审(和同学交 ...

  9. A library of generic data structures

    A library of generic data structures including a list, array, hashtable, deque etc.. https://github. ...

  10. Javascript的自执行函数

    自执行函数其实也就是"立即执行的函数",它有四个特点:提高性能.利于压缩.避免冲突.依赖加载: 1.减少作用域查找 JS代码: // Anonymous function that ...