• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

Android6.0run时权限请求计划

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0919/649.html

 
本日常州微信公众平台在测试APP的时候发现片面手机APP定位权限应用不了。看了一下机型都是Android6.0以上版本的Android手机。
以前就传闻Android6.0以上版本权限经管更严格了,没想到本日踩坑了。
 
6.0版本以前的权限经管都是少许手机体系本人写的权限经管,好比说小米手机体系,魅族...这些都本人带有本人权限经管。
如许子轻易出现的题目是:
1.要是某个权限被禁用了。运用开发中底子没提供方式来校验该权限是否被禁用。我们就需求本人的方式去校验。
好比说灌音权限被禁用了,是从灌音功效动手做校验。而不是从权限列表获取权限状况。这是真的坑。
2.我们晓得权限被禁用了,还需求校验一下是哪一个体系好提醒用户根据操纵去开启这个权限。
也即是说开发过程当中需求把合流的机型测试一遍。而后要是有权限经管的话把权限流程过一遍。加个鉴别体系的方式,而后在把流程做成一个一个加上去。的确可骇。
 
Google非常终办理计划,给体系弄一个权限经管。
太棒了,权限经管由Android体系本身来做才是对开发者非常友爱的办理计划。
1
2
3
4
5
6
7
8
9
10
11
12
空话未几说,接下来就讲讲6.0版本权限题目的终极办理计划吧。
 
Android在 6.0以上版本需求进行动静的权限配置。
 
一、SDK新增方式
1.在ActivityCompat增加的方式
ActivityCompat.requestPermissions(context, needPermissions, REQUEST_CODE_REQUEST_PERMISSION);
1
这个方式用来动静配置权限。要是没有所需的权限。将会弹窗提醒用户配置权限。 
三个参数分别为:目前高低文,需求要求的权限列表列表,要求码。要求码用于背面回调回笼要求后果用。
 
ActivityCompat.checkSelfPermission(context, needPermission);
1
2
这个方式用来监测某个权限是否被常州微信小程序开发配置。 
两个参数分别为:目前高低文,需求监测的权限信息。 
这个方式的回笼值有两个0或-1 分别是已授权,和未授权
 
在PackManager这个类中有与之相般配的常量
 
 /**
     * Permission check result: this is returned by {@link #checkPermission}
     * if the permission has been granted to the given package.
     */
    public static final int PERMISSION_GRANTED = 0;    /**
     * Permission check result: this is returned by {@link #checkPermission}
     * if the permission has not been granted to the given package.
     */
    public static final int PERMISSION_DENIED = -1;
1
2
3
4
5
6
7
8
9
10
11
2.Activity中增加回调方式
 
  @Override
   public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
1
2
3
4
5
6
这个方式会在用户配置完权限后回调 
三个回调参数分别是:要求码,要求的权限,权限目前状况
 
二、写个demo实验一下
package cn.xiaolongonly.myapplication;import android.Manifest;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v7.app.AppCompatActivity;import android.util.Log;public class MainActivity extends AppCompatActivity {
    private String[] requestPermissions = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION};    @Override
    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);        int write = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);        int read = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);        int coarse = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);        int fine = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
        Log.d("permissionState:", "write:"+write + "_" + "read:"+read + "_" + "coarse:"+coarse + "_" + "fine:"+fine);
        ActivityCompat.requestPermissions(this, requestPermissions, 10086);
    }    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.d("RequestCode", requestCode + "");        for (int i = 0; i < permissions.length; i++) {
            Log.d("permissionInfo", "permissionName:" + permissions[i] + "permission State:" + grantResults[i]);
        }        int write = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);        int read = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);        int coarse = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);        int fine = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
        Log.d("permissionState:", "write:"+write + "_" + "read:"+read + "_" + "coarse:"+coarse + "_" + "fine:"+fine);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
打印出常州网站开发建设的Log如下
容许的环境
 
D/CreatePermissionState:: write:-1_read:-1_coarse:-1_fine:-1 
D/RequestCode: 10086 
D/permissionInfo: permissionName:android.permission.WRITE_EXTERNAL_STORAGEpermission State:0 
D/permissionInfo: permissionName:android.permission.READ_EXTERNAL_STORAGEpermission State:0 
D/permissionInfo: permissionName:android.permission.ACCESS_COARSE_LOCATIONpermission State:-1 
D/permissionInfo: permissionName:android.permission.ACCESS_FINE_LOCATIONpermission State:-1 
D/FinishPermissionState:: write:0_read:0_coarse:-1_fine:-1
 
回绝后
 
D/CreatePermissionState:: write:-1_read:-1_coarse:-1_fine:-1 
D/RequestCode: 10086 
D/permissionInfo: permissionName:android.permission.WRITE_EXTERNAL_STORAGEpermission State:-1 
D/permissionInfo: permissionName:android.permission.READ_EXTERNAL_STORAGEpermission State:-1 
D/permissionInfo: permissionName:android.permission.ACCESS_COARSE_LOCATIONpermission State:-1 
D/permissionInfo: permissionName:android.permission.ACCESS_FINE_LOCATIONpermission State:-1 
D/FinishPermissionState:: write:-1_read:-1_coarse:-1_fine:-1
 
界面:
 
授权提醒
 
出现的题目
发现只出现一个授权文件读写的提醒框。 
非常后发现我在清单文件Manifest中只注册了读写权限。没有注册网页定位和精准定位权限。加上这两个。 
此次启动的时候就出现了两个提醒框了。(授权文件读写和定位) 
可以看出,文件读写是归一个权限掌握来经管的,两个定位权限也是归于一个权限掌握来经管的。 
清单权限注册
 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
1
2
3
4
留意事变:
需求动静配置的权限必然要在清单文件中做注册,不然默认都是不做配置的。以前踩过的一个坑是只注册了COARSE_LOCATION没有注册FINE_LOCATION,发现FINE_LOCATION一直是未授权,不过COARSE_LOCATION授权胜利了。
 
当用户回绝权限授权以后,在次权限要求的时候是会出现不在扣问的提醒框的。勾选以后只能选定回绝权限。回绝以后以后就不会再做提醒了, 
权限会自动被回绝,requestPermissions方式是有走的,体系自动回绝了这个权限。所以在onRequestPermissionResult()中同样能看到不提醒但requestPermissions做了要求的权限。
 
三、非常后再对代码进行简单的封装
package cn.xiaolongonly.myapplication;import android.Manifest;import android.app.Activity;import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.provider.Settings;import android.support.v4.app.ActivityCompat;import android.util.Log;import android.widget.Toast;public class PermissionUtil {
    public static final int REQUEST_CODE_REQUEST_PERMISSION = 1027;    private static final String PACKAGE_URL_SCHEME = "package:";    private static final int REQUEST_CODE_REQUEST_SETTING = 1028;    public interface PermissionListener {
        void allGranted();                                          //要求的权限已一切被容许;
    }    public static class PermissionTool {
 
        public String[] lackPermission;        /**
         * 需求进行检验的权限数组
         */
        public String[] mainNeedPermissions = {       //SD卡权限,定位权限
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
        };        /**
         * 需求进行检验的权限数组
         */
        public String[] qrCodeNeedPermissions = {       //获取相机权限
                Manifest.permission.CAMERA
        };        /**
         * 需求进行检验的权限数组
         */
        public String[] requestNeedPermissions = {       //获取游戏开发运营手机建筑号用
                Manifest.permission.READ_PHONE_STATE
        };        private PermissionListener mListener;        public PermissionTool(PermissionListener listener) {
            mListener = listener;
        }        public void checkAndRequestPermission(Activity activity, String... needPermissions) {            boolean isAllGranted = true;            for (String needPermission : needPermissions) {                if (ActivityCompat.checkSelfPermission(activity, needPermission)
                        != PackageManager.PERMISSION_GRANTED) {
                    isAllGranted = false;
                }
                Log.d("state", ActivityCompat.checkSelfPermission(activity, needPermission) + "");
            }            if (isAllGranted) {
                mListener.allGranted();
            } else {
                ActivityCompat.requestPermissions(activity, needPermissions, REQUEST_CODE_REQUEST_PERMISSION);
            }
 
        }        public void onRequestPermissionResult(final Activity activity,                                              int requestCode, String[] permissions, int[] grantResults) {            if (requestCode == REQUEST_CODE_REQUEST_PERMISSION) {                boolean allGrant = true;                for (int i = 0; i < grantResults.length; i++) {                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        allGrant = false;
                    }
                    Log.d("PermissionTool", "onRequestPermissionResult(): " + grantResults[i] + "permission" + permissions[i]);
                }                if (allGrant) {
                    mListener.allGranted();
                } else {
                    Toast.makeText(activity, "片面所需权限未开启,将影响功效平常应用,请开启权限!", Toast.LENGTH_LONG).show();
                    startAppSettings(activity);
                }
            }
        }        public void startAppSettings(Activity activity) {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse(PACKAGE_URL_SCHEME + activity.getPackageName()));
            activity.startActivityForResult(intent, REQUEST_CODE_REQUEST_SETTING);
        }
 
    }
 
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
这里将权限经管的方式和回调都抽取到一个类中了。干脆挪用方式和回调便了。
 
值得留意的是:在本人写的APP有少许页面没有这些授权是无法应用的。不过用户又不准了权限。而用户可能不晓得要去何处开启这个权限,便通过翻开目前运用的配置页面来指导用户开启。startAppSettings(Activity activity)
 
应用:
package cn.xiaolongonly.myapplication;import android.Manifest;import android.os.Build;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.v7.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {
    private String[] requestPermissions = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION};    private PermissionUtil.PermissionTool permissionTool;    @Override
    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);        if (Build.VERSION.SDK_INT >= 23) { //针对6.0以后的版本加权限校验
            permissionTool = new PermissionUtil.PermissionTool(new PermissionUtil.PermissionListener() {                @Override
                public void allGranted() {
                    initView();
                }
            });
            permissionTool.checkAndRequestPermission(MainActivity.this, requestPermissions);
        } else {
            initView();
        }
    }    private void initView() {        //在这里做界面初始化
    }    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        permissionTool.onRequestPermissionResult(this, requestCode, permissions, grantResults);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
总结对于Android6.0运转时权限暂时就晓得怎么配置了,要是有不及的地方欢迎指出。 
demo下载
 
新功效
这边趁便讲一下在manifest清单文件中多了
 
 <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
1
如许的权限配置,这个跟运用动静授权没有甚么关系。 
在谷歌官方文档 
是这么注释的
 
指明运用需求特定权限,但仅当运用在 API 级别 23 或更高版本的建筑上运转时才需求。要是建筑运转的是 API 级别 22 或更低版本,则运用没有指定的权限。
当您更新运用以包含需求其余权限的新功效时,此元素很有效。要是用户在运转 API 级别 22 或更低版本的建筑更新运用,体系在安置时会提醒用户付与在该更新中申明的所有新权限。要是某个新功效可有可无,您可能想同时在这些建筑上停用该功效,以便用户不需求付与分外权限即可更新运用。要是应用 <uses-permission-sdk-23> 元素而不应用 <uses-permission>,则仅当运用在支持运转时权限模式(用户在运用运转时向其付与权限)的平台上运转时才可要求权限。
如需打听相关权限的详细信息,请参阅简介的权限片面和独自的体系权限 API 指南。在 android.Manifest.permission 上可以找到常州手游开发底子平台定义的权限列表。
1
2
3
也即是说要是应用的是来注册的话这个权限就只能运转时动静付与。 而版本低于SDK23的Android建筑不支持动静配置权限。所以低于SDK23的运用是不行有这个权限的。
 

上篇:上一篇:Android中微信抢红包助手的实现(代码整顿)
下篇:下一篇:android获取建筑唯一标识完善计划