Android--6.0运行时权限处理
来源:互联网 发布:seo是做什么 编辑:程序博客网 时间:2024/06/05 02:20
一、概述
Andorid6.0版本自发布以来,相信不少开发者对于Android6.0版本来说,最大的手头工作无非就是做好6.0申请权限的工作,我们一旦没动态申请权限的话,那么将会报出一系列异常。当然有些权限的需要我们去动态申请的,而有些是不需要的,那么,这里估计会有人问:哪些需要或者哪些不需要?其实说白了,需要我们动态去申请的权限是属于危险权限,而我们不需要去动态申请的权限则是普通权限。下面我们将会介绍。所以,我们开发者有务必对6.0新版本sdk带来权限机制的变化。好的,那么今天我们将介绍Andorid6.0带来的运行时权限的一些处理。
二、运行时权限的变化
新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions正常的权限,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等,这类权限也是属于我们文章中概述介绍的非6.0该有申请的权限;另一类是Dangerous Permission危险的权限,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等,这类权限正好是我们6.0新版本所需要申请的权限。
三、Normal Permissions权限和Dangerous Permissions列表
Normal Permissions:
ACCESS_LOCATION_EXTRA_COMMANDSACCESS_NETWORK_STATEACCESS_NOTIFICATION_POLICYACCESS_WIFI_STATEBLUETOOTHBLUETOOTH_ADMINBROADCAST_STICKYCHANGE_NETWORK_STATECHANGE_WIFI_MULTICAST_STATECHANGE_WIFI_STATEDISABLE_KEYGUARDEXPAND_STATUS_BARGET_PACKAGE_SIZEINSTALL_SHORTCUTINTERNETKILL_BACKGROUND_PROCESSESMODIFY_AUDIO_SETTINGSNFCREAD_SYNC_SETTINGSREAD_SYNC_STATSRECEIVE_BOOT_COMPLETEDREORDER_TASKSREQUEST_INSTALL_PACKAGESSET_ALARMSET_TIME_ZONESET_WALLPAPERSET_WALLPAPER_HINTSTRANSMIT_IRUNINSTALL_SHORTCUTUSE_FINGERPRINTVIBRATEWAKE_LOCKWRITE_SYNC_SETTINGS
Dangerous Permissions:
group:android.permission-group.CONTACTS permission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTSgroup: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_VOICEMAILgroup:android.permission-group.CALENDAR permission:android.permission.READ_CALENDAR permission:android.permission.WRITE_CALENDARgroup:android.permission-group.CAMERA permission:android.permission.CAMERAgroup:android.permission-group.SENSORS permission:android.permission.BODY_SENSORSgroup:android.permission-group.LOCATION permission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATIONgroup:android.permission-group.STORAGE permission:android.permission.READ_EXTERNAL_STORAGE permission:android.permission.WRITE_EXTERNAL_STORAGEgroup:android.permission-group.MICROPHONE permission:android.permission.RECORD_AUDIOgroup: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
PS:Normal Permissions普通权限是不需要我们在Andorid6.0去动态申请权限的,因为他属于普通权限,一般如果需要用到,我们直接在清单文件里面添加即可。Dangerous Permissions危险权限,则是需要我们在Android6.0中去动态申请权限的。看到Dangerous Permissions危险权限的时候,大家有没有发现都是一组一组的,没错,正是如此!其实之所以一组一组的,是因为Google故意设计的。
那么估计会有人问到,分组的权限机智对于我们开发者有影响吗,确实是有的,好比你现在拿一只安卓6.0版本的手机在运行程序,如果你申请某个危险的权限,假设你的app早已被用户授权了同一组的某个危险权限,那么系统会立即授权,而不需要用户去点击授权。比如你的app对READ_CONTACTS
已经授权了,当你的app申请WRITE_CONTACTS
时,系统会直接授权通过。此外,对于申请时弹出的dialog上面的文本说明也是对整个权限组的说明,而不是单个权限(ps:这个dialog是不能进行定制的)。
最后值得注意的是:我们在Android6.0申请危险权限的时候,我们要根据需求从而申请对应的权限列表,不能申请错误的权限列表哦!否则会出现一些错误,有关对应的权限名称,可自行上网百度。
四、相关的API以及动态申请权限的步骤
大概的步骤分为:检查权限--申请权限--处理申请权限的回调事件,其中,还有一个申请权限时的拒绝事件,也就是说点击了拒绝申请权限的事件,通常这个容易开开发者忽略,不过下面我们将会讲到。首先我们先来看看申请权限的几个基本步骤:
1、检查权限
if (ContextCompat.checkSelfPermission(MainActivity.this, CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {}这里主要涉及到了一个API: ContextCompat.checkSelfPermission主要是用于检测当前某个权限是否已经被赋予了。如果当前权限不被PackageManager.PERMISSION_GRANTED所赋予了,我们就需要对他进行权限的申请。
2、申请权限
ActivityCompat.requestPermissions(MainActivity.this, new String[]{CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);该方法是用来申请权限的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。也就是我们自己定义的一个结果码,可以从方法名
requestPermissions
以及第二个参数看出,是支持一次性申请多个权限的,因为他是数组,系统会通过对话框逐一询问用户是否授权。3、处于申请权限回调事件
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_CALL_PHONE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { CallPhone(); } else { Toast.makeText(this, "授权失败!", Toast.LENGTH_LONG).show(); } break; } } }对于申请权限的回调事件,我们首先先判断一个和我们申请权限的结果码是否一致,如果一致的话,才能对我们申请的结果进行处理,这里的CallPhone方法我们主要是模拟打电话。具体代码下面会给出。
4、最后有一个API值得提醒一下,就是文章中所说的拒绝回调事件,不知道大家记起来了没有,在文章中曾说过,没记得没关系,下面我将为大家隆重介绍。
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, CALL_PHONE)) {}该方法就是我们讲的拒绝权限申请回调事件,比如用户现在点击拒绝了,他会立刻执行到申请回调事件中的失败事件,在该事件中我们一般提示用户一下申请拒绝就可以了。然后等到第二次申请权限的时候,就会立刻执行 shouldShowRequestPermissionRationale方法体,在这个方法体中你需要给用户一个解释,为什么要授权,则使用该方法。一般在开发当中,我们可以在该方法体中用Toast提示用户说--请同意授权后,
才能拨打电话,这是常见的用法之一,但是还有一种比较流氓的手法,就是直接打开手机的设置面板,让用户手动开启该权限,这种做法确实比较流氓的,哈哈....下面最终案例里面会有涉及到这种用法,这么说一来,我确实也是流氓的
好了,相关的API以及动态申请权限的步骤我已经介绍到这里。下面让我们一起来看看简单的例子。
五、简单的例子
这里我们将模拟打电话,大家也知道电话权限是属于危险权限的,在6.0版本中需要我们动态去申请该权限,所以我正好拿来这里做讲解,大家顺便看看6.0打电话是如何处理动态申请权限的。
当然我们这里代码也是非常简单的,无非就是检查权限,申请权限,处理权限回调事件。
MainActivity文件
import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Bundle;import android.provider.Settings;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.Toast;import static android.Manifest.permission.CALL_PHONE;public class MainActivity extends AppCompatActivity { //初始按钮控件和申请权限结果码 private Button call_phone; private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); call_phone = (Button) this.findViewById(R.id.call_phone); call_phone.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //这里我们将模拟申请打电话权限 TellPhone(); } }); } private void TellPhone() { //检查当前是否有CALL_PHONE电话这个权限 if (ContextCompat.checkSelfPermission(MainActivity.this, CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { //用户拒绝申请该权限的回调事件 if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, CALL_PHONE)) { //提示该用户拒绝了权限信息 Toast.makeText(MainActivity.this, "请同意授权后,才能拨打电话", Toast.LENGTH_LONG).show(); // 帮跳转到该应用的设置界面,让用户手动同意打开电话授权(这里采用了流氓做法....) Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); Log.i("申请拒绝", "申请拒绝"); } else { Log.i("正在申请", "正在申请"); ActivityCompat.requestPermissions(MainActivity.this, new String[]{CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE); } } else { Log.i("申请成功", "申请成功"); CallPhone(); } } //拨打电话 private void CallPhone() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); // 设置动作 Uri data = Uri.parse("tel:" + 10086); // 设置数据 intent.setData(data); startActivity(intent); } //处理权限申请的回调事件 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { //如果当前跟我们申请权限的结果码一致,则立刻执行 case MY_PERMISSIONS_REQUEST_CALL_PHONE: { //申请权限成功 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { CallPhone(); } else { //申请权限失败 Toast.makeText(this, "申请权限失败", Toast.LENGTH_LONG).show(); } break; } } }}布局文件我就不贴了,没什么撒,就只有一个Button而已。
当我们在安卓6.0机器上运行的时候,点击按钮后会立刻弹出权限窗口,这时候你可以选择拒绝或者同意。
当你选择拒绝后会提示申请回调事件中的申请权限失败信息,此时我们还执行不到拒绝回调事件当中。拒绝回调事件会在拒绝后第二次打开时候才执行的。
当你选择同意后会立刻执行CallPhone方法拨打电话。
例子很简单,但是以后遇到6.0危险权限的时候,我们记得动态去申请对应的权限。好了,今天关于Andorid--6.0运行时权限的处理讲解到这里,希望对大家有所帮助!
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 Marshmallow运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Android 6.0 运行时权限处理
- Golang gc演进
- angular2实现统一的http请求头
- 正则表达式排除特定字符串
- 免费个人博客搭建教程(详细-图文)--Hexo+OSChina
- 23种设计模式(22)-调停者模式
- Android--6.0运行时权限处理
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
- 约束
- POJ 3667 Hotel(线段树区间合并查询)
- Linux内核高性能优化【生产环境实例】
- 数据结构--堆和队列&&C语言的内存分配--堆和栈
- PPT控件Aspose.Slides V17.7发布 | 支持在文本框中添加列
- Hadoop
- SSH 首次登录太慢问题