转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6690152.html

网上运行时权限的例子、Demo无计其数,但是和Google官方出品的比起来,都显得很啰嗦。作为Android开发人员应该以Google的实例为样本。官方出品,必属精品!!!

Google官方Runtime Permissions Demo地址:https://github.com/googlesamples/android-RuntimePermissions

Demo如下(这里强调一下,Google推荐使用Snackbar代替Toast)

在 Android M 版本(即6.0以后的版本),多了一个特殊权限处理。开发者的开发工具Android Studio 如果是 Android API 23 Platform或以上版本,需要在调用特殊权限的地方手动将权限打开,在 AndroidManifest 直接说明是不好用的。

那么都有哪些权限是需要特殊处理的呢。下面我就把这些特殊权限按类罗列出来,并告诉你如何在代码中进行手动调用。

需要单独申请的权限共分为9组,每组只要有一个权限申请成功,默认整组权限都可以使用了。

①使用您的通讯录

group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS

②拨打电话和管理通话

group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL

③访问您的日历

group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR

④拍摄照片和录制视频

group:android.permission-group.CAMERA
permission:android.permission.CAMERA

⑤访问与您的生命体征相关的传感器数据

group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS

⑥使用此设备的位置信息

group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION

⑦访问您设备上的照片、媒体内容和文件

group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE

⑧录制音频

group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO

⑨发送和查看短信

group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS

废话不多说,让我们一探究竟Google是如何处理Android M以上运行时权限的。

以"联系人权限"为例做演示,其他的权限大同小异。

1.创建一个工具类PermissionUtil

Google对这个工具类作出的解释是 Utility class that wraps access to the runtime permissions API in M and provides basic helper methods.

即:在M中包含对运行时权限API的访问的实用程序类,并提供基本的帮助方法。

public abstract class PermissionUtil {

    /**
* 检查所有给定的权限是否通过验证给定数组中的每个条目都具有该值*/
public static boolean verifyPermissions(int[] grantResults) {
// 至少检查一个结果
if (grantResults.length < 1) {
return false;
} // 验证是否已授予每个必需的权限,否则返回false
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
} }

2.联系人权限已在Android M及以上版本中声明。 它们在旧平台上不可用,因此我们隐藏按钮以访问联系人数据库。这显示了如何添加新的运行时权限,不适用于较旧的平台版本。 这对于其他权限可能会提示用户进行升级的自动更新非常有用。

public class RuntimePermissionsFragment extends Fragment {

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main, null);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
root.findViewById(R.id.button_contacts).setVisibility(View.GONE);
}
return root;
}
}

3.主类

public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {

    private static final String TAG = "MainActivity";

    /**
* 用于标识请求联系人权限的Id
*/
private static final int REQUEST_CONTACTS = 0; /**
* 联系人读、写所需的权限
*/
private static String[] PERMISSIONS_CONTACT = {
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
}; /**
* Activity的根布局
*/
private View mLayout; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLayout = findViewById(R.id.content_fragment); if (savedInstanceState == null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
RuntimePermissionsFragment fragment = new RuntimePermissionsFragment();
transaction.replace(R.id.content_fragment, fragment);
transaction.commit();
}
} /**
* 当点击“显示联系人”按钮时调用
* 回调在布局文件中定义
*/
public void showContacts(View v) {
Log.i(TAG, "Show contacts button pressed. Checking permissions."); // 验证是否已授予所需的联系人权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // 尚未被授予联系人权限
Log.i(TAG, "Contact permissions has NOT been granted. Requesting permissions."); requestContactsPermissions();
} else {
// 联系权限已被授予。 显示联系人片段
Log.i(TAG, "Contact permissions have already been granted. Displaying contact details.");
}
} /**
* 请求联系人权限
* 如果以前已经拒绝许可,SnackBar将提示用户授予权限,否则直接请求
*/
private void requestContactsPermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_CONTACTS)) { // 显示一个带有说明和按钮的SnackBar来触发请求
Snackbar.make(mLayout, R.string.permission_contacts_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_CONTACT, REQUEST_CONTACTS);
}
}).show();
} else {
// 联系人权限尚未被授予,直接请求
ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS);
}
} @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_CONTACTS) {
Log.i(TAG, "Received response for contact permissions request."); // 已经为联系人请求了权限,因此这些权限都需要检查
if (PermissionUtil.verifyPermissions(grantResults)) {
// 已授予所有必需的权限,显示联系人片段
Snackbar.make(mLayout, R.string.permision_available_contacts, Snackbar.LENGTH_SHORT).show();
} else {
Log.i(TAG, "Contacts permissions were NOT granted.");
Snackbar.make(mLayout, R.string.permissions_not_granted, Snackbar.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}

4.在AndroidManifest加上需要申请的权限

<!-- 仅当设备在M或更高版本上时,才需要以下权限。在较旧的平台上,这些权限不被请求,并且将不可用。 -->
<uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS" />
<uses-permission-sdk-23 android:name="android.permission.WRITE_CONTACTS" />

以上就是Google官方提供的完整而且简洁的运行时权限Demo

关注我的新浪微博,获取更多Android开发资讯!
关注科技评论家,领略科技、创新、教育以及最大化人类智慧与想象力!

Android M以上运行时权限(Google官方出品)的更多相关文章

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

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

  2. Android M Permission 运行时权限 学习笔记

    Android M Permission 运行时权限 学习笔记 从Android 6.0开始, 用户需要在运行时请求权限, 本文对运行时权限的申请和处理进行介绍, 并讨论了使用运行时权限时新老版本的一 ...

  3. Android PermissionUtils:运行时权限工具类及申请权限的正确姿势

    Android PermissionUtils:运行时权限工具类及申请权限的正确姿势 ifadai 关注 2017.06.16 16:22* 字数 318 阅读 3637评论 1喜欢 6 Permis ...

  4. Android 6.0 运行时权限处理完全解析

    一.概述 随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化.对于6.0的几个主要的变化,查看查看官网的这篇文章http:// ...

  5. 谈谈Android 6.0运行时权限理解

    前言 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6. ...

  6. Android 6.0运行时权限

    一.Runtime Permissions Android 6.0在手机安全方面做的一个处理就是增加了运行时权限(Runtime Permissions). 新的权限机制更好的保护了用户的隐私,Goo ...

  7. Android 6.0 运行时权限处理问题

    序 自从升级到Android M以来,最大的改变就是增加了运行时权限RuntimePermission,6.0以上的系统如果没有做适配,运行了targetSDK=23的App时就会报权限错误.我们知道 ...

  8. Android 6.0 运行时权限处理完全解析 (摘抄)

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/50709663: 本文出自:[张鸿洋的博客] 一.概述 随着Android 6. ...

  9. Android数据存储之Android 6.0运行时权限下文件存储的思考

    前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以 ...

随机推荐

  1. IDEA下创建Maven项目,并整合使用Spring、Spring MVC、Mybatis框架

    项目创建 本项目使用的是IDEA 2016创建. 首先电脑安装Maven,接着打开IDEA新建一个project,选择Maven,选择图中所选项,下一步. 填写好GroupId和ArtifactId, ...

  2. MongoDB【第一篇】安装

    第一步:准备 1. 操作系统 CentOS-7-x86_64-Everything-1511 2. MongoDB 版本 mongodb-linux-x86_64-rhel70-3.4.2 3. 设置 ...

  3. SpringMVC4+MyBatis3+SQLServer 2014 整合(包括增删改查分页)

    前言 说起整合自然离开ssm,我本身并不太喜欢ORM,尤其是MyBatis,把SQL语句写在xml里,尤其是大SQL,可读性不高,出错也不容易排查. 开发环境 idea2016.SpringMVC4. ...

  4. 每天一个Linux命令(06)--rmdir命令

    终于忙完了公司的事,可以安静的充充电了. 今天学习一下Linux中命令:rmdir 命令,rmdir是常用的命令,该命令的功能是删除空目录,一个目录被删除之前必须是空的.(注意,rm -r dir 命 ...

  5. gulp快速入门&初体验

    前言 一句话先 gulp 是一个可以简单和自动化"管理"前端文件的构建工具 先说我以前的主要工作,我主要是做游戏服务端的,用c++/python,所以我对东西的概念理解难免要套到自 ...

  6. Javascript把数据从一个页面的层传递到另一个页面层里面

    背景:昨天头脑发热投了某一家国企的计算机类岗位(说是有前端岗位),通过找同学内推,虽然也笔试了一大堆题目(行测题,计算机网络,http协议,英译汉,古诗文默写,自己把品质排序并且进行200字以上的阐述 ...

  7. AlloyTouch.js 源码 学习笔记及原理说明

    alloyTouch这个库其实可以做很多事的, 比较抽象, 需要我们用户好好的思考作者提供的实例属性和一些回调方法(touchStart, change, touchMove, pressMove, ...

  8. .NET 知识整理笔记

    本文纯属自己理解着写的,如果有什么错误或者不全面希望读者能够加以补充!~ 1.Web.Config配置文件的节点操作. 在Web.Config中写入. <configuration> &l ...

  9. js实现Mac触摸板双指事件(上、下、左、右、放大、缩小)

    前言 这几天在修复一个web问题时,需要捕获Mac触摸板双指事件(上.下.左.右.放大.缩小),但发现并没有现成的轮子,还是要自己造. 例如:jquery.mousewheel.js(添加跨浏览器的鼠 ...

  10. Eclipse:The selection cannot be launched,and there are no recent launches

    刚刚装上eclipse,于是就想写个Java程序来试试.结果写好之后不管是点击 run  还是  debug 结果都会弹出一个窗口,内容为: The selection cannot be launc ...