安卓6.0+ 动态权限申请总结


网上关于安卓动态权限申请的文章很多,但是毕竟眼花缭乱,所以下面我将根据自己的理解和在网上获取到的信息对动态权限申请进行小小的总结,以便以后再次接触安卓的时候能够拿出来看!

  • 下面有几组需要动态申请的权限,据说在每一组中,只需要成功申请一组即可。申请需要在AndroidManifest.xml中添加对应的代码:
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
  • 需要注意,无论是动态权限申请还是其他权限的申请,都需要在AndroidManifest.xml文件中进行申请。对于动态权限还需要在对应的java文件中用代码进行动态权限的申请。接下来的内容主要是在.java文件中进行动态权限申请的代码的介绍。

--今天没有进行研究,我想得过几天再进行研究,然后再进行总结,今天带外甥仔忘记了^ _ ^ 早点休息吧(2018/1/17 23:55)


好了,现在继续我们的总结,首先,先给一个链接,这个是google官方的关于运行时动态申请权限的代码,在github上,喜欢的话可以fork到你的github账户中,点这里进行查看。
在下面我的介绍中,我也是基于官方文档的,因为规则是人家定的,你必须遵循人家的标准。总的来说,在java代码中动态申请权限分为三个大的步骤,步骤一是检查是否已经获得了权限,步骤二则在步骤一没有获取到权限的时候进行动态权限的申请,步骤三则在回调函数中实现相应的操作。
下面我将以申请手机拍照的权限作为例子来总结分析:
在官方文档的注释当中,有几句话是很重要的,我摘抄在下面:

* This Activity requests permissions to access the camera ({@link android.Manifest.permission#CAMERA})
 * when the 'Show Camera' button is clicked to display the camera preview.

 * First, permissions are checked if they have already been granted through {@link
 * ActivityCompat#checkSelfPermission(Context, String)}.
 * If permissions have not been granted, they are requested through
 * {@link ActivityCompat#requestPermissions(Activity, String[], int)} and the return value checked
 * in
 * a callback to the {@link android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback}
 * interface.

这里表达的意思和我前面总结的三个步骤其实是一样的。
接下来,我们来看具体的代码,首先是一个showCamera()函数:

public void showCamera(View view) {
        Log.i(TAG, "Show camera button pressed. Checking permission.");
        // BEGIN_INCLUDE(camera_permission)
        // Check if the Camera permission is already available.
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            // Camera permission has not been granted.

            requestCameraPermission();

        } else {

            // Camera permissions is already available, show the camera preview.
            Log.i(TAG,
                    "CAMERA permission has already been granted. Displaying camera preview.");
            showCameraPreview();
        }
        // END_INCLUDE(camera_permission)

    }

在这部分代码里面其实包含了我总结的两个步骤,即步骤一检查是否已经申请到了权限步骤二如果没有则进行权限的动态申请。检查是否已经获得了权限的代码是if语句里面的判断条件所示的代码,在这里拿出来展示,以便看得更加清晰:

ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED

其实原理很简单,就是使用ActivityCompat.checkSelfPermission(Context, String)来判断是否已经获得了权限,如果其返回值等于PackageManager.PERMISSION_GRANTED则已经获得,否则没有获得权限。函数中的第一个参数是Context参数,即上下文,这个一般是this(fragment中则一般是getActivity()),第二个参数是String类型的参数,表示的是申请的动态权限的类型,比如这里需要申请Camera的权限,则是Manifest.permission.CAMERA,如果是其他,则填上相应的即可,关于这个我会在文章后面进行一个总结。
判断完之后,如果已经获得了权限,则我们可以用我们定义的方法打开相机,完成相应的操作;否则,我们要动态申请权限,即进行步骤二,我们用了另外一个函数来写申请相机权限的过程,代码如下:

private void requestCameraPermission() {
        Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission.");

        // BEGIN_INCLUDE(camera_permission_request)
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.CAMERA)) {
            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // For example if the user has previously denied the permission.
            Log.i(TAG,
                    "Displaying camera permission rationale to provide additional context.");
            Snackbar.make(mLayout, R.string.permission_camera_rationale,
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(R.string.ok, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.CAMERA},
                                    REQUEST_CAMERA);
                        }
                    })
                    .show();
        } else {

            // Camera permission has not been granted yet. Request it directly.
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
                    REQUEST_CAMERA);
        }
        // END_INCLUDE(camera_permission_request)
    }

上面的这个函数看似很复杂,其实思路很清晰的,下面我就来分析分析:首先用ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)这个函数来检测用户是否设定了申请权限时弹出一些东西来提示是否允许使用相应的权限,如果是,那么就定制相应的提示,比如这里就使用了一个Snackbar来提醒用户进行权限的申请;如果用户没有设定,那么直接进行权限的申请,而不告知用户。申请权限的函数是:

ActivityCompat.requestPermissions(Activity, String[], int)

第一个参数是Context,第二个参数是申请的权限的字符串数组,因为有时需要申请的权限不止一个,第三个参数则是请求码,这里已经定义了它的值:REQUEST_CAMERA = 0,关于不同的权限的请求码将会在文章的后面进行总结。
最后,我们进行最后一个步骤,即实现回调函数,只需要重写onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)这个函数即可,函数里面需要实现的内容我也展示出来,注意这里是以申请相机权限为例的:

if (requestCode == REQUEST_CAMERA) {
            // BEGIN_INCLUDE(permission_result)
            // Received permission result for camera permission.
            Log.i(TAG, "Received response for Camera permission request.");

            // Check if the only required permission has been granted
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Camera permission has been granted, preview can be displayed
                Log.i(TAG, "CAMERA permission has now been granted. Showing preview.");
                Snackbar.make(mLayout, R.string.permision_available_camera,
                        Snackbar.LENGTH_SHORT).show();
            } else {
                Log.i(TAG, "CAMERA permission was NOT granted.");
                Snackbar.make(mLayout, R.string.permissions_not_granted,
                        Snackbar.LENGTH_SHORT).show();

            }
            // END_INCLUDE(permission_result)

        }

在这个回调函数中,根据申请权限时返回的信息来判断权限是否申请成功,从而用Snackbar来给用户相应的提示,告诉用户权限申请成功与否。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,028评论 25 707
  • 几乎每个人都知道都知道,Google为了提高Android系统的安全在6.0系统加上了动态申请权限。权限不在是像6...
    邢二创阅读 10,089评论 1 17
  • 文/聆听流年 你是爱穿旗袍的女子 馨嬅落落的气质 岁月 被束起在长发里 你是爱穿旗袍的女子 萼萼婷婷着老街的斑驳...
    聆听流年_b2a4阅读 277评论 0 3
  • 终于知道 走比跑累 老师比学生精明 现实比梦境更能让人清醒 偌大的操场 稀稀疏疏几盏残灯 满天的星光 正好给几对小...
    墨兰molan阅读 125评论 0 3
  • 小灶群今天的话题是:你有没有什么小心愿一直没实现呢? 我想了想,写道:我想变大咖,纵横多个领域! 啊!先别管这个愿...
    捡到蜜罐的熊阅读 73评论 2 3