`

android6.0新特性之权限管理

阅读更多

现状:

1、当代码编译版本都是 5.0及其以下(API23以下),在Manifest注册了权限。

    运行在6.0以下手机没有问题,用户只能在安装的时候选择同意权限,不能修改(不考虑第三方安全软件设置的因素)
    运行在6.0及其以上,对于敏感权限用户可以在设置中修改(不需要第三方软件),修改时系统会提示用户“可能会导致无法正常运行”,但还可以修改成功。一旦修改了在API23以下是没有办法在程序内部通过API的方法打开权限。对于非敏感权限安装后无法修改。
 

2、当代码编译版本都是 6.0及其以上(API23及其以上),在Manifest注册了权限。

    运行在6.0以下手机没有问题,用户只能在安装的时候选择同意权限,不能修改(不考虑第三方安全软件设置的因素)运行在6.0及其以上对于敏感权限安装后即可获取该权限,也无法修改。对于敏感权限安装后默认是没有权限的。程序内部可以判断、提示用户赋予这些权限。
 
Android6.0与权限相关的API
//检查是否已赋予某个权限,返回PackageManager.PERMISSION_GRANTED或PERMISSION_DENIED
ContextCompat.checkSelfPermission()
//向用户请求赋予某个(某些)权限
ActivityCompat.requestPermissions()
//向用户请求赋予权限的结果
OnRequestPermissionsResultCallback()
//Google提供的一个人性化的方法,表示是否向用户解释一下权限
ActivityCompat.shouldShowRequestPermissionRationale()
 
Fragment类似

FragmentCompat.requestPermissions()
OnRequestPermissionsResultCallback()
FragmentCompat.shouldShowRequestPermissionRationale()
 
示例:
public class MainActivity extends AppCompatActivity {

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

        readExtStorageDir();
    }

    /**
     * 读取外部SD卡目录
     */
    private void readExtStorageDir() {
        int permissionResult = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
        if (PackageManager.PERMISSION_GRANTED == permissionResult) {//已有权限
            doReadExtStorageDir();
        } else {//没有权限向用户索取权限
            final String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};
            ActivityCompat.requestPermissions(MainActivity.this, permissions, 100);
        }
    }

    /**
     * 索取权限的结果
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (100 == requestCode) {
            if (null != permissions) {
//是读取外部SD卡的权限&已赋予权限
                if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permissions[0]) && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
                    doReadExtStorageDir();
                }
            }
        }
    }

    private void doReadExtStorageDir() {
        File storageDir = Environment.getExternalStorageDirectory();
        File[] files = storageDir.listFiles();
        if (null != files && files.length > 0) {
            for (File f : files) {
                Log.e("P", "==>" + f.getName());
            }
        }
    }

}
 
个性化提示:
   当用户拒绝后,但又没有点不再提示,那么这个时候是否给用户一个对权限要求的说明呢?这个时候就用到shouldShowRequestPermissionRationale方法
shouldShowRequestPermissionRationale()的理解:
如果之前请求过并被用户拒绝,那么它会返回 true,如果之前用户已经勾选了不再提示的选项,它会返回 false,同样当设备策略禁止应用拥有这条权限时也会返回 false。第一次请求这个权限也返回false。那么我们需要做的,就是在用户确切需要拒绝这个权限请求前向他解释我们为什么需要,否则当彻底拒绝后(用户在拒绝的时候勾选了不再提示也返回false,但执行requestPermissions()方法不会显示请求权限框),除非用户手动去设置中开启,我们都无法再得到权限了。
/**
 * 读取外部SD卡目录
*/
private void readExtStorageDir() {
    int permissionResult = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
    if (PackageManager.PERMISSION_GRANTED == permissionResult) {
        doReadExtStorageDir();
    } else {
        final String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};

        boolean shouldShowRequestPermission = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE);
        Log.e("P", "shouldShowRequestPermission==" + shouldShowRequestPermission);
        if (shouldShowRequestPermission) {
            showMessageOKCancel("向用户解释权限,请用户点击允许!", new DialogInterface.OnClickListener() {

                @Override
public void onClick(DialogInterface dialogInterface, int i) {
                    ActivityCompat.requestPermissions(MainActivity.this, permissions, 100);
                }
            });
            return;
        }
        ActivityCompat.requestPermissions(MainActivity.this, permissions, 100);

    }
}
一次请求多个权限:
//定义请求多个权限的名称    
String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
//向用户请求赋予权限
ActivityCompat.requestPermissions(MainActivity.this,permissions,100);

//回调结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Log.e("P", requestCode + " " + permissions[0] + " " + grantResults[0]);
    if (100 == requestCode) {
        if (null != permissions) {
            for (int i = 0; i < permissions.length; i++) {
                Log.e("P", permissions[i] + " ===> " + grantResults[i]);
                if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permissions[i])) {
                    if (PackageManager.PERMISSION_GRANTED == grantResults[i]) {
                        doReadExtStorageDir();
                    }
                }
            }
        }
    }
}
  
 
权限组 
 ActivityCompat.requestPermissions()不能传权限组名称,只能传权限名称,同一组的任何一个权限被授权了,其他权限也自动被授权。
敏感权限列表
权限组 权限
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
 
  • 大小: 47.2 KB
  • 大小: 53.2 KB
  • 大小: 44.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics