美高梅平台下载-美高梅娱乐平台登录

热门关键词: 美高梅平台下载,美高梅娱乐平台登录

也不能在App内到处申请权限,1 标准模式【美高梅

日期:2019-09-30编辑作者:美高梅平台下载

Android的棉花糖我们需要所有权限请求需要得到用户的许可(当我们的targetSdkVersion>=23时是必须动态获取权限申请)。所以这里,我们就需要去处理当用户拒绝了我们的权限申请,我们的代码该如何处理。

1、前言

自从Android6.0发布,增加了许多新的特性和功能,除了强化和完善了MD设计元素,Android的安全也得到了谷歌的重视。于是,Android6.0中出现了运行时权限的概念。许多程序员前赴后继,推出了大量的优秀的第三方库,来简化运行时权限的使用。但是,我觉得我们有必要从根本上学会使用运行时权限的申请,这能增加我们对Permission的理解。
本教程代码:https://github.com/sendtion/SDCPermission


最近APP里面要添加动态权限,网上找了不少例子并经过一定的测试,基本流程有了一定的认识,需要注意的地方记录下来以备以后查阅。

这里咱们代码配合效果图来演示具体效果。

2、运行时权限

当我们的targetSdkVersion>=23时,我们一定要注意权限的申请,否则App会因为没有获取权限而发生崩溃。当然,在API 23以下系统版本也可以判断一下权限是否得到,确保万无一失。
我们不能连续一次性申请多个权限,这会使用户感觉到不安全,感觉App有窃取隐私信息的可能,可能因此丧失一部分用户。也不能在App内到处申请权限,这会是用户感到烦躁和麻烦,这也会丧失一部分用户。

所以,我们申请权限的时候一定要注意一些原则:

a>尽量精简权限,剔除不必要的权限
大量的权限,只会让用户丧失安全感或者感到烦躁,得不偿失。

b>用户拒绝后再次请求一定要详细说明缘由
给用户详细说明,我们需要这个权限来干什么,用户才更容易接受。

c>在合理的位置申请权限
不要一次性申请所有的权限,这中感觉很不好,会让用户感觉自己被强X了。


一 各大手机厂商的适配

这里假设我需要去申请该权限:

3、系统权限有这些

Google将权限分为两类,一类是普通权限(Normal Permissions),这类权限一般不涉及用户隐私,也不需要用户进行授权,如网络访问,手机震动等,这些权限如下所示:

ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_ALARM
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS

另外一类是危险权限(Dangerous Permission),涉及用户隐私,需要用户授权,如对sd卡读取、访问用户手机通讯录等。如下所示:

android.permission-group.CALENDAR(日历数据) 
android.permission.READ_CALENDAR
android.permission.WRITE_CALENDAR

android.permission-group.CAMERA(相机) 
android.permission.CAMERA

android.permission-group.CONTACTS(联系人)  
android.permission.READ_CONTACTS
android.permission.WRITE_CONTACTS
android.permission.GET_ACCOUNTS

android.permission-group.LOCATION(位置)   
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION

android.permission-group.MICROPHONE(麦克风)    
android.permission.RECORD_AUDIO

android.permission-group.PHONE(电话)  
android.permission.READ_PHONE_STATE
android.permission.CALL_PHONE
android.permission.READ_CALL_LOG
android.permission.WRITE_CALL_LOG
com.android.voicemail.permission.ADD_VOICEMAIL
android.permission.USE_SIP
android.permission.PROCESS_OUTGOING_CALLS

android.permission-group.SENSORS(传感器)   
android.permission.BODY_SENSORS

android.permission-group.SMS(短信)    
android.permission.SEND_SMS
android.permission.RECEIVE_SMS
android.permission.READ_SMS
android.permission.RECEIVE_WAP_PUSH
android.permission.RECEIVE_MMS
android.permission.READ_CELL_BROADCASTS

android.permission-group.STORAGE(存储)    
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE

查看Dangerous Permission可以发现权限是分组的,这个和Android 6.0的授权机制有关。如果你申请某个危险的权限,假设你的app早已被用户授权了同一组的某个危险权限,那么系统会立即授权,而不需要用户去点击授权。比如你的app对READ_CONTACTS已经授权了,当你的app申请WRITE_CONTACTS时,系统会直接授权通过。此外,申请时弹出的dialog上面的文本说明也是对整个权限组的说明,而不是单个权限(ps:这个dialog是不能进行定制的)。

注:不要对权限组过多的依赖,尽可能对每个危险权限都进行正常流程的申请,因为在后期的版本中这个权限组可能会产生变化。


依据各大手机Rom的不同表现,可以分为三种不同的模式:标准模式,默认开启模式,特殊权限模式。

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

美高梅娱乐平台登录 ,4、权限申请方式

以请求读取联系人权限为例:
a> 在AndroidManifest.xml文件中声明所需要的权限
b> 检查是否授予了所需要的权限

ContextCompat.checkSelfPermission(this,Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED

ContextCompat.checkSelfPermission()主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。

美高梅平台下载 ,c> 如果没有授予权限,则请求授权

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

该方法是异步的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。可以从方法名requestPermissions以及第二个参数看出,是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。

d> 处理权限申请的结果

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults);
     //TODO
     if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
     //获得了权限
     } else {
     //拒绝了权限
     }
}

e> 如果用户拒绝了,下次申请给予解释

ActivityCompat.shouldShowRequestPermissionRationale(this, permission)

这个API主要用于给用户一个申请权限的解释,该方法只有在用户在上一次已经拒绝过你的这个权限申请。也就是说,用户已经拒绝一次了,你又弹个授权框,你需要给用户一个解释,为什么要授权,则使用该方法。

注:

  • 如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
  • 如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,此方法将返回 false。
  • 如果设备规范禁止应用具有该权限,此方法也会返回 false。

1 标准模式:代表华为Mate8,三星S6。

当我们第一次去点击READ PHONE STATE时就会弹出这个权限申请dialog,如果用户点击了允许,那恭喜你,万事大吉了,你就不用去担心需要权限的代码不能执行了。但是,如果用户点击了拒绝,那很不幸,你需要权限的代码是不能执行,如果你不加处理,非要执行那段代码的话,应用就会直接崩溃,崩溃日志就会告诉你,需要获取该权限。

5、优化

到这里算是处理完了,这么看起来并没有多麻烦,但是坑还是存在的。Android碎片化严重,大家都知道。国产的各种定制系统深度修改,好多底层API都有所改变,给我们Android开发者带来了极大的麻烦。诸如MIUI、Flyme、EMUI、FuntouchOS、ColorOS、SmartisanOS、CoolUI、H2OS等等等,各种各样,五花八门。

本教程的例子用的是小米5 MIUI8 7.0开发版,就遇到了很坑的事情。
小米默认是允许读写存储卡权限的,其他的权限都是询问状态。

美高梅娱乐平台登录 1

这里写图片描述

经测试,
默认询问,除了日历、录音、相机、存储卡会弹窗,你可以选择拒绝或者允许;其他权限不弹窗,checkSelfPermission直接返回0,也就是直接允许了,此时权限状态仍然为询问状态;
手动拒绝后不会再弹窗,相当于选中了不再询问,权限状态由询问变为拒绝,需要手动给予权限;
手动允许后,权限状态由询问变为允许;
MIUI上:shouldShowRequestPermissionRationale()返回一直是false,无法进行判断解释。

GitHub地址:https://github.com/sendtion/SDCPermission
完整的代码如下:

package com.sdc.sdcpermission;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Android 6.0原生系统运行时权限适配
 * 在联想乐檬X3测试通过
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";//快捷键logt

    private TextView tv_sdcard;
    private TextView tv_sms;
    private TextView tv_phone;
    private TextView tv_contacts;
    private TextView tv_location;
    private TextView tv_record;
    private TextView tv_camera;
    private TextView tv_calender;
    private TextView tv_sensor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
    }

    private void initViews() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        tv_contacts = (TextView) findViewById(R.id.tv_contacts);
        tv_sms = (TextView) findViewById(R.id.tv_sms);
        tv_phone = (TextView) findViewById(R.id.tv_phone);
        tv_location = (TextView) findViewById(R.id.tv_location);
        tv_sdcard = (TextView) findViewById(R.id.tv_sdcard);
        tv_record = (TextView) findViewById(R.id.tv_record);
        tv_calender = (TextView) findViewById(R.id.tv_calender);
        tv_camera = (TextView) findViewById(R.id.tv_camera);
        tv_sensor = (TextView) findViewById(R.id.tv_sensor);

        tv_contacts.setOnClickListener(this);
        tv_sms.setOnClickListener(this);
        tv_phone.setOnClickListener(this);
        tv_location.setOnClickListener(this);
        tv_sdcard.setOnClickListener(this);
        tv_record.setOnClickListener(this);
        tv_calender.setOnClickListener(this);
        tv_camera.setOnClickListener(this);
        tv_sensor.setOnClickListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_miui) {
            //跳转到MIUI的权限适配界面
            Intent intent = new Intent();
            intent.setClass(this, MIUIActivity.class);
            startActivity(intent);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void showToast(String text){
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.tv_contacts:
                //READ_CONTACTS是读取联系人
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限
                    //如果没有权限则申请权限
                    showTipsDialog("读取联系人", Manifest.permission.READ_CONTACTS, 101);
                } else {
                    showToast("已经获得‘读取联系人’权限");
                }
                break;
            case R.id.tv_location:
                //ACCESS_FINE_LOCATION是GPS定位,ACCESS_COARSE_LOCATION是网络定位
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("GPS定位", Manifest.permission.ACCESS_FINE_LOCATION, 102);
                } else {
                    showToast("已经获得‘GPS定位’权限");
                }
                break;
            case R.id.tv_sdcard:
                //READ_EXTERNAL_STORAGE是读取存储卡,
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("读存储卡", Manifest.permission.READ_EXTERNAL_STORAGE, 103);
                } else {
                    showToast("已经获得‘读存储卡’权限");
                }
                break;
            case R.id.tv_sms:
                //READ_SMS是读取短信,SEND_SMS是发送短信
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("读取短信", Manifest.permission.READ_SMS, 104);
                } else {
                    showToast("已经获得‘读取短信’权限");
                }
                break;
            case R.id.tv_phone:
                //CALL_PHONE是拨打电话
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("拨打电话", Manifest.permission.CALL_PHONE, 105);
                } else {
                    showToast("已经获得‘拨打电话’权限");
                }
                break;
            case R.id.tv_record:
                //RECORD_AUDIO是录音
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("录音", Manifest.permission.RECORD_AUDIO, 106);
                } else {
                    showToast("已经获得‘录音’权限");
                }
                break;
            case R.id.tv_camera:
                //CAMERA是调用相机
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("调用相机", Manifest.permission.CAMERA, 107);
                } else {
                    showToast("已经获得‘调用相机’权限");
                }
                break;
            case R.id.tv_calender:
                //WRITE_CALENDAR是写日历
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("写日历", Manifest.permission.WRITE_CALENDAR, 108);
                } else {
                    showToast("已经获得‘写日历’权限");
                }
                break;
            case R.id.tv_sensor:
                //BODY_SENSORS是传感器权限
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.BODY_SENSORS) !=
                        PackageManager.PERMISSION_GRANTED){//拒绝了权限,或者没有获得权限

                    showTipsDialog("传感器", Manifest.permission.BODY_SENSORS, 109);
                } else {
                    showToast("已经获得‘传感器’权限");
                }
                break;
        }
    }

    /**
     * ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_CONTACTS)
     * 如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
     * 如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,此方法将返回 false。
     * 如果设备规范禁止应用具有该权限,此方法也会返回 false。
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 101:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    showToast("已经获得‘读取联系人’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘读取联系人’权限");
                    getAppDetailSettingIntent("读取联系人");
                }
                break;
            case 102:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘GPS定位’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘GPS定位’权限");
                    getAppDetailSettingIntent("GPS定位");
                }
                break;
            case 103:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘读存储卡’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘读存储卡’权限");
                    getAppDetailSettingIntent("读存储卡");
                }
                break;
            case 104:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘读取短信’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘读取短信’权限");
                    getAppDetailSettingIntent("读取短信");
                }
                break;
            case 105:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘拨打电话’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘拨打电话’权限");
                    getAppDetailSettingIntent("拨打电话");
                }
                break;
            case 106:
                //录音默认询问,请求权限会弹窗
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘录音’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘录音’权限");
                    getAppDetailSettingIntent("录音");
                }
                break;
            case 107:
                //相机默认询问,请求权限会弹窗
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘调用相机’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘调用相机’权限");
                    getAppDetailSettingIntent("调用相机");
                }
                break;
            case 108:
                //日历默认询问,请求权限会弹窗
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘写日历’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘写日历’权限");
                    getAppDetailSettingIntent("写日历");
                }
                break;
            case 109:
                //传感器默认允许,不会弹窗
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //获取了权限
                    showToast("已经获得‘传感器’权限???");
                } else {
                    //拒绝了权限
                    showToast("拒绝获得‘传感器’权限");
                    getAppDetailSettingIntent("传感器");
                }
                break;
        }
    }

    /**
     * 显示对话框,提示用户允许权限
     * @param name
     */
    public void showTipsDialog(String name, final String permission, final int code){
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("权限申请提示");
            builder.setMessage("当前应用缺少"+name+"权限。是否立即申请权限?");
            builder.setNegativeButton("取消", null);
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{
                            permission},code);
                }
            });
            builder.create().show();
        } else {
            showToast("我们需要"+name+"权限,给我吧!");
            //拒绝后不再询问选中的话,下面就不会在执行
            //如果选中不再询问,则询问状态会变成拒绝,否则一直是询问状态
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{
                    permission},code);
        }
    }

    /**
     * 跳转到App详情页
     */
    public void getAppDetailSettingIntent(String name) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("权限申请提示");
        builder.setMessage("当前应用缺少"+name+"权限。请到应用信息——>权限管理中手动给予权限。");
        builder.setNegativeButton("取消", null);
        builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent localIntent = new Intent();
                localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                if (Build.VERSION.SDK_INT >= 9) {
                    localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                    localIntent.setData(Uri.fromParts("package", getPackageName(), null));
                } else if (Build.VERSION.SDK_INT <= 8) {
                    localIntent.setAction(Intent.ACTION_VIEW);
                    localIntent.setClassName("com.android.settings","com.android.settings.InstalledAppDetails");
                    localIntent.putExtra("com.android.settings.ApplicationPkgName", getPackageName());
                }
                startActivity(localIntent);
            }
        });
        builder.create().show();
    }

}

基本流程如下:

美高梅娱乐平台登录 2图片传自简书APP

6、第三方库推荐

第三方库推荐,列举的有点多,至于你喜欢哪个,需要自己去发现~
前三个都不错,个人用的第四个!

yanzhenjie/AndPermission: Android permission.
https://github.com/yanzhenjie/AndPermission (严振杰)
hongyangAndroid/MPermissions: a easy API to use runtime permission for Android M
https://github.com/hongyangAndroid/MPermissions (鸿洋)
lovedise/PermissionGen: Android API easy to use permission for Android M
https://github.com/lovedise/PermissionGen
tbruyelle/RxPermissions: Android runtime permissions powered by RxJava 支持RxJava的动态权限
https://github.com/tbruyelle/RxPermissions
forJrking/HeiPermission: Hei 一句代码搞定 Android M 动态权限检测。信不信由你,反正我用了。
https://github.com/forJrking/HeiPermission
rebus007/PermissionUtils: Check marshmallow permission easily
https://github.com/rebus007/PermissionUtils
mylhyl/AndroidAcp: 一句话搞定,简化Android 6.0 系统复杂的权限操作
https://github.com/mylhyl/AndroidAcp
lypeer/FcPermissions: Fuck the permissions in Android M
https://github.com/lypeer/FcPermissions
Airsaid/MPermissionUtils: Android6.0 运行时权限 超轻量级工具类
https://github.com/Airsaid/MPermissionUtils
AndSync/XPermissionUtils: 可能是最精简的Android6.0运行时权限处理方式
https://github.com/AndSync/XPermissionUtils

如有疑问,欢迎指正!

个人简介:
GitHub:https://github.com/sendtion
博客:http://sendtion.cn/
简书:http://www.jianshu.com/users/630d98ed1424

用户启动APP后,第一次需要权限的时候,判断用户当前权限,弹出系统默认的系统Snacbar

 if (Build.VERSION.SDK_INT >= 23) { if (checkPermissionsrp { // 对于高于或等于23的API代码导向装置 // 执行具体逻辑 } else { requestPermissionsrp(); //代码去执行权限申请 } } else { //面向API的23以下设备的代码 // 执行具体逻辑 } }

private boolean checkPermissionsrp() { int result2 = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE); if (result2 == PackageManager.PERMISSION_GRANTED) { return true; } else { return false; } }

private void requestPermissionsrp() { boolean permissionRationale = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE); if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_PHONE_STATE)) { new AlertDialog.Builder .setMessage("跳转到设置页面") .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(Settings.ACTION_SETTINGS); startActivity; // 打开系统设置界面 } }) .setNegativeButton("Cancel", null) .create; } else { ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_PHONE_STATE}, PERMISSION_REQUEST_CODE); } }

intstate = ActivityCompat.checkSelfPermission(activity,requestPermission);

当我们点击了拒绝时,就会打出权限被拒绝,您不能继续执行。所以在这时候,咱们就需要去自己单独自定义一个dialog,去引导用户允许咱们的权限申请。

通过onRequestPermissionsResult判断出来用户选择结果,

美高梅娱乐平台登录 3图片来自简书APP

用户选择始终允许,则直接获取了权限,APP继续后续流程。

当用户跟随我们的引导去授予权限时,然后返回我们的APP时,checkPermissionsrp()方法就会返回true,这时候,我们的代码逻辑就可以正常执行了。

如果用户选择了拒绝,则需要APP自己处理,一般会弹出一个Dialog 提示用户需要该权限,是否去设置里面打开该权限。拒绝也分为两种情况,一种是选择了禁止后不再询问,一种是没有选择。两种的区别在于在标准模式下,用户选择了禁止不再提问后,不会再弹出系统Snacbar,而是直接返回拒绝的结果,如果用户没有选择,则会继续弹出系统Snacbar。

 public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.e("value", "权限允许,您可以继续执行"); } else { Log.e("value", "权限被拒绝,您不能继续执行。"); } break; } }

用户启动权限申请后,会有shouldShowRequestPermissionRationale来判断是否需要APP弹出一个提示框,提示用户来同意申请该动态权限。这个在应用首次申请权限时,如果用户点击拒绝,下次再申请权限,Android允许你提示用户,你为什么需要这个权限,更好引导用户是否授权。

到这里,权限申请就结束了,其他权限申请也类似。

本来是添加一个自定义Dialog来提示用户,后产品认为提示过多,则默认还是直接去申请权限。

快乐生活!快乐工作!快乐编程!

if(ActivityCompat.shouldShowRequestPermissionRationale(activity,requestPermission)) {

//为了优化用户关闭权限后 第一次没有任何提示

if(ConfigUtils.isHtc()) {

openSettingActivity(activity,activity.getString(R.string.permission_setting_head)

+ message +"权限",permissionGrant);

}else{

//TODO 直接进行权限申请 不再先进行自定义提示

ActivityCompat.requestPermissions(activity, newString[]{requestPermission},requestCode);

//                shouldShowRationale(activity, requestCode, requestPermission, permissionGrant);

}

}else{

ActivityCompat.requestPermissions(activity, newString[]{requestPermission},requestCode);

}

本文由美高梅平台下载发布于美高梅平台下载,转载请注明出处:也不能在App内到处申请权限,1 标准模式【美高梅

关键词:

注解处理器,接下我们将学习使用APT

主目录见:Android高级进阶知识我们在开发的时候为了提高效率往往会选择一个基于注解的框架,但是有时使用反射通...

详细>>

任何一个包含n个节点完全二叉树(满足从根节点开

一直以来,我都很少使用也避免使用到树和图,总觉得它们神秘而又复杂,但是树在一些运算和查找中也不可避免的要...

详细>>

实现方法,真正调用的构造

参考:Android中定时器的3种实现方法 在Android开发中,定时器一般有以下3种实现方法: 总结 Handler类的主要作用是发送...

详细>>

Android 架构师之路 目录,GUI 系统来说

在日常开发过程中时常需要用到设计模式,但是设计模式有23种,如何将这些设计模式了然于胸并且能在实际开发过程...

详细>>