在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. JS—事件对象

    在触发DOM上的某个事件时,会产生一个事件对象event.这个对象中包含着所有与事件有关的信息.包括导致事件的元素,事件的类型以及其他与特定事件相关的信息. 举例鼠标操作导致的事件对象中,会包含鼠标位 ...

  2. AJAX 同步异步笔记

    就在刚才,做一个很简单的Demo, 预览MP4视频文件 这就是一个video标签嘛,然后再动态的给src赋值嘛.这还不是so easy? 好,说做就做.先简单的测试一下.先给src赋值一下. 嗯,可以 ...

  3. myeclipse 无法启动

    1.对项目中的一个文件重新命名,导致卡死,结束myeclipse进程不管用,重启不管用. 删除工程下的文件  以  .markers.snap 和  marker开头的两个文件   位置: 工作空间\ ...

  4. DirectX9 Sample_Empty Project

    作为第一个程序,EmpytProject仅仅示范了如何绑定DXUTstate结构中的回调函数. 回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当 ...

  5. 2015 ACM/ICPC EC-Final

    A. Boxes and Balls 二分找到最大的不超过$n$的$\frac{x(x+1)}{2}$形式的数即可. #include <bits/stdc++.h> using name ...

  6. Codeforces Round #260 (Div. 2)

    A. Laptops 题目意思: 给定n台电脑,第i台电脑的价格是ai ,质量是bi ,问是否存在一台电脑价格比某台电脑价格底,但质量确比某台电脑的质量高,即是否存在ai < aj 且 bi & ...

  7. 【Telerik】弹出对话框RadWindow,确认删除信息

    要做一个删除功能,但是删除前正常都要弹出对话框确认一下是否删除信息,防止误删信息.

  8. Essential controls for web app

    AUTO-COMPLETE/AUTO-SUGGEST Auto-complete using Vaadin Offer auto-suggest or auto-complete to help yo ...

  9. jsfl脚本设置导出AS链接名遇到的奇怪问题

    今天写jsfl脚本发现一个奇怪的问题,脚本用于对库对象设置AS链接名,代码如下: var item = fl.getDocumentDOM().library.items[0];var exportN ...

  10. idea 根据数据库表自动创建持久化类

    一.点击最右边的Database: 二.点击,再点DataSource选择数据库类型,配置数据库信息: 三.打开项目结构,选择,找到你的项目,点击,添加hibernate: 四.如果有现成的cfg.x ...