Android动态权限

Android的权限声明

当APP需要访问APP沙箱外部数据或资源的区域,则需要声明权限。APP必须在AndroidManiffest文件中,通过<uses-permission>声明所需的权限。例如APP需要网络连接,则在manifest中添加一行

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.xxx">

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

    <application ...>
        ...
    </application>
</manifest>

如果应用在manifest中列出了正常权限,系统会自动授予APP这些权限。

如果应用在manifest中列出了危险权限,则需要用户明确同意授予这些权限。

Android的权限分类

Android权限分成几个保护级别,保护级别会影响是否需要APP运行时申请权限。

目前分为三个保护级别:NormalSigatureDangerous权限。

Normal权限在APP安装时系统自动授予。

Sigature权限也是在APP安装时系统授予。

Dangerous权限则需要在APP运行时,APP提示用户授予权限,即动态申请。

1、Normal权限

Normal权限不会直接给用户隐私权带来风险。如果APP在其manifest中声明Normal权限,则系统会在安装时自动授予APP该权限。系统不会提示用户授予Normal权限,用户也无法撤消这些权限。

从Android 8.1(API 27)开始,以下权限为Normal:

  • 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
  • MANAGE_OWN_CALLS
  • MODIFY_AUDIO_SETTINGS
  • NFC ……

2、Sigature权限

顾名思义,Sigature权限仅限于用该APK(定义了这个权限的APK)相同的私钥签名的应用才可以申请该权限。

从Android 8.1(API 27)开始,以下权限为Signature:

  • BIND_ACCESSIBILITY_SERVICE
  • BIND_AUTOFILL_SERVICE
  • BIND_CARRIER_SERVICES
  • BIND_CHOOSER_TARGET_SERVICE
  • BIND_CONDITION_PROVIDER_SERVICE
  • BIND_DEVICE_ADMIN
  • BIND_DREAM_SERVICE
  • BIND_INCALL_SERVICE
  • BIND_INPUT_METHOD ……

3、Dangerous权限

Dangerous权限分成与设备功能相关的权限组,便于用户在授予权限时做出更有意义和更明智的选择。

权限组 权限
CALENDAR READ_CALENDAR
- WRITE_CALENDAR
CAMERA CAMERA
CONTACTS CONTACTS
- READ_CONTACTS
- WRITE_CONTACTS
- GET_ACCOUNTS
LOCATION ACCESS_FINE_LOCATION
- ACCESS_COARSE_LOCATION
MICROPHONE RECORD_AUDIO
PHONE READ_PHONE_STATE
- READ_PHONE_NUMBERS
- CALL_PHONE
- ANSWER_PHONE_CALLS
- READ_CALL_LOG
- WRITE_CALL_LOG
- ADD_VOICEMAIL
- USE_SIP
- PROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS
- RECEIVE_SMS
- READ_SMS
- RECEIVE_WAP_PUSH
- RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE
- WRITE_EXTERNAL_STORAGE

运行时请求Dangerous权限

  • 如果设备运行的是Android 6.0(API 23)或更高版本,并且APP的targetSdkVersion为23或更高,则在安装时,不会通知用户任何APP权限。APP必须在运行时提示用户授予Dangerous权限。

  • 如果设备运行Android 5.1.1(API 22)或更低版本,或者targetSdkVersion为22或更低,则在安装时,系统会自动要求用户授予所有Dangerous权限。

动态申请权限的关键代码

1、请求需要的权限

例如:检查APP是否具备摄像头权限Manifest.permission.CAMERA为例,并根据需要请求该权限

// 检查权限,没有返回true,需要申请
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.CAMERA)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.CAMERA)) {
            
        // 如果应用之前请求过此权限但用户拒绝了请求,此方法将返回true,这步判断非必须      
        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.CAMERA},
                MY_PERMISSIONS_REQUEST_CAMERA);

        // MY_PERMISSIONS_REQUEST_CAMERA is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

注:当APP调用requestPermissions()时,系统将向用户显示一个标准对话框。APP无法配置或更改此对话框。如果需要为用户提供任何信息或解释,应在调用requestPermissions()之前进行,如解释应用为什么需要权限中所述。

2、处理权限请求响应

当应用请求权限时,系统将向用户显示一个对话框。当用户响应时,系统将调用应用的onRequestPermissionsResult()方法,向其传递用户响应。因此,需要在Activity或者Fragment实现onRequestPermissionsResult方法。

@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_CAMERA: {
            // If request is cancelled, the result arrays are empty.
            // 异常情况,grantResultsw也是空数组
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

其他

为了方便申请动态权限,可以使用一些开源库,比如RxPermissions,将权限申请的代码requestPermissions()和请求结果的代码onRequestPermissionsResult()放在一起管理,避免了代码的分散,同时具备Rx(RxJava)的特性。

使用如下

private void requestPremission() {
    RxPermissions rxPermissions = new RxPermissions(this);
    rxPermissions.request(Manifest.permission.CAMERA)
            .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean granted) throws Exception {
                    if (granted) {
                        Log.d("zzhtest", "permission = " + granted);
                    } else {
                        Log.d("zzhtest", "permission = " + granted);
                    }
                }
            });
}

参考

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

推荐阅读更多精彩内容

  • 1.现状 在Android6.0之前,app申请权限是在安装时候申请,必须接受了对应应用的权限列表才能安装应用,同...
    SuperCrab阅读 617评论 0 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,442评论 25 707
  • 昨天和小姐妹聊天,她声泪俱下地吐槽她家儿子:曾经小天使,现在俨然小魔王,哭闹不讲理的戏码天天上演,撒泼、蛮横、自私...
    康媛阅读 511评论 0 5
  • 你爱过别人吗?你被别人爱过吗?你真的爱过或被爱过吗?影片以松子的死亡开篇,外甥阿笙在办理姑姑的后事中,偶然发现了一...
    予不语阅读 545评论 0 0
  • 长夜漫漫,忽而有感,遂赋诗一首,聊以自娱。 负手窗棂久, 遥想当时旧。 落叶满庭芳, 飘零几时休。 思君千万里, ...
    此刻依然如初见阅读 210评论 2 1