Android动态权限管理

Android6.0以后,应用权限分为静态权限和动态权限,下表是需要动态申请的权限。

描述

权限代码

调用相机权限

CAMERA

日历权限

READ_CALENDAR

WRITE_CALENDAR

通讯录权限

READ_CONTACTS

WRITE_CONTACTS

GET_ACCOUNTS

定位权限

ACCESS_FINE_LOCATION

ACCESS_COARSE_LOCATION

录音权限

RECORD_AUDIO

手机状态相关

READ_PHONE_STATE

CALL_PHONE

READ_CALL_LOG

WRITE_CALL_LOG

ADD_VOICEMAIL

传感器权限

BODY_SENSORS

SMS消息权限

SEND_SMS

RECEIVE_SMS

READ_SMS

RECEIVE_WAP_PUSH

RECEIVE_MMS

外部存储权限

READ_EXTERNAL_STORAGE

WRITE_EXTERNAL_STORAGE

权限注册

要使用相关权限,首先必须在AndroidManifest.xml中注册响应权限,才能在代码中动态申请。
示例:

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

权限申请

多数应用在安装后启动的第一时间向用户申请权限,为了方便用户操作,可以在启动页完成权限申请代码。以获取位置信息为例:

if (ContextCompat.checkSelfPermission(MainActivity.this,
        Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED){
     if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
    Manifest.permission.ACCESS_FINE_LOCATION)) {
            //这里可以写个对话框之类的项向用户解释为什么要申请权限,并在对话框的确认键后续再次申请权限
        } else {
            //申请权限,字符串数组内是一个或多个要申请的权限,1是申请权限结果的返回参数,在onRequestPermissionsResult可以得知申请结果
            ActivityCompat.requestPermissions(MainActivity.this,
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
        }
    }else {
        // TODO
    }

权限管理有三种状态
- 允许
- 禁止
- 询问

应用安装时,默认为询问状态,应用可发起申请,用户许可后,状态为允许,用户不许可,则状态更改为禁止。

每次进行相应操作时,都需要判断是否授予了对应的权限,若不作判断,权限状态不为允许时,应用会崩溃。

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

返回true即已获取到权限

状态修改

当权限状态处于询问或者禁止时,且部分手机无法收到申请弹窗(生无可恋魅族脸.jpg),这时,需要引导用户跳转到设置界面,手动开启权限。

Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
startActivity(intent);

权限开启了,但功能未开启,同样需要引导用户开启功能,以获取位置信息为例。

检测功能是否开启:

locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)

返回值为Boolean类型,true表示已开启。若返回值为flash,则引导用户跳转到设置页面,开启功能。

// 转到手机设置界面,用户设置GPS
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);

// 设置完成后返回到原来的界面
startActivityForResult(intent, 0);