Android6.0及以上申请权限(特殊权限和普通权限)整理

Android6.0及以上申请权限(特殊权限和普通权限)整理Android6.0 为了保护用户隐私,将一些权限的申请放在了应用运行的时候去申请。在Android6.0以前的开发中,开发人员只需要将需要的权限在AndroidManifest.xml文件中声明,有的APP一股脑声明了各种各样的权限,用户可能没有细看就安装了,于是这些APP就…

一、为什么要动态申请权限

Android6.0 为了保护用户隐私,将一些权限的申请放在了应用运行的时候去申请。在Android6.0以前的开发中,开发人员只需要将需要的权限在AndroidManifest.xml文件中声明,有的APP一股脑声明了各种各样的权限,用户可能没有细看就安装了,于是这些APP就可以为所欲为,偷鸡摸狗,无法无天。Android6.0把权限分成正常权限和危险权限,AndroidManifest中声明的正常权限系统会自动授予,而危险权限则需要在使用的时候用户明确授予。

换句话说,就是Android 6.0以上的系统在第一次使用危险权限的时候,需要向用户申请,征得用户的同意。如果还是在没有权限的情况下执行操作,系统就会Crash,错误日志为java.lang.SecurityException: Permission Denial。因此,用户对危险权限的申请 ,需要相应的处理。

二、特殊权限(危险权限)

这类权限需要在使用的时候用户动态申请。比如:当用户打开相机拍摄照片的时候,需要开发人员通过代码的方式在打开相机的地方去申请权限。Android6.0中权限问题中开发人员需要注意的是:

1、由于权限API的问题,我们的Actiivty最好是AppCompatActivity类型的,也就是说在你的BaseActivity需要继承AppCompatActivity。

2、权限是分组的,同一组的权限申请其中一个,同组的权限就全部都申请了。比如,应用被授予READ_EXTERNAL_STORAGE权限之后,如果再申请WRITE_EXTERNAL_STORAGE权限,系统会立即授予该权限,不会再弹出权限授予询问的对话框。

(一)特殊权限组(共9组)

CALENDAR 日历
CAMERA 相机
CONTACTS 联系人
LOCATION 定位
MICROPHONE 麦克相关,比如录音
PHONE 手机状态
SENSORS 传感器
SMS 短信
STORAGE 存储权限

Android6.0及以上申请权限(特殊权限和普通权限)整理

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

#### 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.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNT
permission:android.permission.READ_CONTACTS

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

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

#### 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.SENSORS
permission:android.permission.BODY_SENSORS

#### 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

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

(二)申请权限的正确姿势

第一步:将targetSdkVersion设置为23,如果将targetSdkVersion设置为>=23,则必须按照谷歌的要求,动态的申请权限。

第二步:需要申请的所有权限在AndroidManifest文件中声明,包括普通权限特殊权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

第三步:使用时检查权限,没有权限则申请,共两个过程:

  • 过程1

检查是否开启此权限checkSelfPermission(),如果拥有此权限,则直接做你想做的事情;有没此权限,则向系统申请此权限;

 if (ContextCompat.checkSelfPermission(getApplication(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
    //拥有权限,做你想做的事情
    doyourSelfSomething();
 }else{
    //没有开启权限,向系统申请权限
    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MyApplication.CODE_FOR_WRITE_PERMISSION);
}
  • 过程2

如果未开启,去向系统申请权限requestPermissions()。用户同意开启权限,则继续执行自己想做的事情。

用户不同意开启权限,则向用户展示该权限作用的文字描述。用户点击OK按钮,继续向系统申请该权限,有种循环授权的味道,不开启该权限,不让使用该功能。

用户不同意开启权限有以下三种情况,用shouldShowRequestPermissionRationale方法判断。

shouldShowRequestPermissionRationale方法返回值分几种情况:
1、第一次请求该权限,返回false2、请求过该权限并被用户拒绝,返回true。(例子是这种情况,一般都是该种情况,只要不勾选不再提醒,就会一直询问权限是否开通)
3、请求过该权限,但用户拒绝的时候勾选不再提醒,返回false
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        //通过requestCode来识别是否同一个请求
        if (requestCode == MyApplication.CODE_FOR_WRITE_PERMISSION){
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //用户同意开启权限,执行操作
                doyourSelfSomething();
                
            }else{
                //用户不同意,向用户展示该权限作用和必要性,用户点击OK,继续向系统申请权限。
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                      new AlertDialog.Builder(TestActivity.this)
                            .setMessage("这个权限用于缓存首页的图片到你的本地,下次再使用图片时无需网络请求了")
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    ActivityCompat.requestPermissions(this, 
                                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                    MyApplication.CODE_FOR_WRITE_PERMISSION);
                                }
                            })
                            .setNegativeButton("Cancel", null)
                            .create()
                            .show();
                }else {
                   //这种情况是,shouldShowRequestPermissionRationale的情况1和3,默认不做处理,根据开发需求的需要吧
                }
           }
      }
}

(三)需要注意的地方

1.checkSelfPermission:检查是否开启权限。

2.requestPermissions:请求开启权限,会弹出一个系统对话框,询问用户是否开启这个权限。

3.shouldShowRequestPermissionRationale:Android原生系统中,弹出权限申请的对话框,如果第一次拒绝,第二次会出现“以后不再弹出”的提示框。如果用户勾选了,用户再次申请权限,shouldShowRequestPermissionRationale返回true,意思是说要给用户一个解释,告诉用户为什么要这个权限。

然而,在实际开发中,很多手机对原生系统做了修改,比如小米、华为等某些机型的6.0的shouldShowRequestPermissionRationale就一直返回false,在申请权限时,如果用户选择了拒绝,则下次不会再弹出对话框了,为了防止让用户反感。我的小米6手机7.0,在申请权限时,如果用户选择了拒绝,则下次会再弹出申请权限的对话框。所以同一品牌手机,不同版本之间厂商也做了不同的处理。

我的解决方法是,在回调里面处理,如果用户拒绝了这个权限,则弹框提示说明该权限的作用,然后打开本应用信息界面,由用户自己手动开启这个权限 或者 用代码再次申请权限。

4.建议每个应用都有自己的权限管理界面,里面有本应用申请的权限以及各种状态,即使用户已经同意了你申请的权限,他也随时可以关闭。

5.可以使用申请权限的第三方库,网上应该有。

三、普通权限

以下这些只是普通权限,开发的时候正常使用就行了,需要的权限在清单文件配置即可。

ACCESS_LOCATION_EXTRA_COMMANDS 定位权限
ACCESS_NETWORK_STATE 网络状态权限
ACCESS_NOTIFICATION_POLICY 通知 APP通知显示在状态栏
ACCESS_WIFI_STATE WiFi状态权限
BLUETOOTH 使用蓝牙权限
BLUETOOTH_ADMIN 控制蓝牙开关
BROADCAST_STICKY 粘性广播
CHANGE_NETWORK_STATE 改变网络状态
CHANGE_WIFI_MULTICAST_STATE 改变WiFi多播状态,应该是控制手机热点(猜测)
CHANGE_WIFI_STATE 控制WiFi开关,改变WiFi状态
DISABLE_KEYGUARD 改变键盘为不可用
EXPAND_STATUS_BAR 扩展bar的状态
GET_PACKAGE_SIZE 获取应用安装包大小
INTERNET 网络权限
KILL_BACKGROUND_PROCESSES 杀死后台进程
MODIFY_AUDIO_SETTINGS 改变音频输出设置
NFC 支付
READ_SYNC_SETTINGS 获取手机设置信息
READ_SYNC_STATS 数据统计
RECEIVE_BOOT_COMPLETED 监听启动广播
REORDER_TASKS 创建新栈
REQUEST_INSTALL_PACKAGES 安装应用程序
SET_TIME_ZONE 允许应用程序设置系统时间区域
SET_WALLPAPER 设置壁纸
SET_WALLPAPER_HINTS 设置壁纸上的提示信息,个性化语言
TRANSMIT_IR 红外发射
USE_FINGERPRINT 指纹识别
VIBRATE 震动
WAKE_LOCK 锁屏
WRITE_SYNC_SETTINGS 改变设置
SET_ALARM 设置警告提示
INSTALL_SHORTCUT 创建快捷方式
UNINSTALL_SHORTCUT 删除快捷方式

今天的文章Android6.0及以上申请权限(特殊权限和普通权限)整理分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18157.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注