解决android 动态权限,android 6.0 动态权限管理的解决方案

Android 6.0版本(Api 23)推出了不少新的特性, 大幅提高了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制本身的隐私, 一方面须要从新适配应用权限. 时代老是不断发展, 程序老是以人为本, 让咱们为应用添加动态权限管理吧! 这里提供了一个很是不错的解决方案, 提供源码, 项目能够直接使用.java

08a170788ff04ba28743e664.html

Permissionsandroid

Android系统包含默认的受权提示框, 可是咱们仍须要设置本身的页面. 缘由是系统提供的受权框, 会有再也不提示的选项. 若是用户选择, 则没法触发受权提示. 使用自定义的提示页面, 能够给予用户手动修改受权的指导.git

本文示例的GitHub下载地址程序员

在Api 23中, 权限须要动态获取, 核心权限必须知足. 标准流程:github

08a170788ff04ba28743e664.html

流程图ide

若是用户点击, 再也不提示, 则系统受权弹窗将不会弹出. 流程变为:工具

08a170788ff04ba28743e664.html

流程图ui

流程就这些, 让咱们看看代码吧.this

1. 权限

在AndroidManifest中, 添加两个权限, 录音和修改音量.code

危险权限必需要受权, 通常权限不须要.

检测权限类

/**

* 检查权限的工具类

* Created by wangchenlong on 16/1/26.

*/public class PermissionsChecker {    private final Context mContext;    public PermissionsChecker(Context context) {

mContext = context.getApplicationContext();

}    // 判断权限集合

public boolean lacksPermissions(String... permissions) {        for (String permission : permissions) {            if (lacksPermission(permission)) {                return true;

}

}        return false;

}    // 判断是否缺乏权限

private boolean lacksPermission(String permission) {        return ContextCompat.checkSelfPermission(mContext, permission) ==

PackageManager.PERMISSION_DENIED;

}

}

2. 首页

假设首页须要使用权限, 在页面显示前, 即onResume时, 检测权限,

若是缺乏, 则进入权限获取页面; 接收返回值, 拒绝权限时, 直接关闭.

public class MainActivity extends AppCompatActivity {    private static final int REQUEST_CODE = 0; // 请求码

// 所需的所有权限

static final String[] PERMISSIONS = new String[]{

Manifest.permission.RECORD_AUDIO,

Manifest.permission.MODIFY_AUDIO_SETTINGS

};    @Bind(R.id.main_t_toolbar) Toolbar mTToolbar;    private PermissionsChecker mPermissionsChecker; // 权限检测器

@Override

protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ButterKnife.bind(this);

setSupportActionBar(mTToolbar);

mPermissionsChecker = new PermissionsChecker(this);

}    @Override protected void onResume() {        super.onResume();        // 缺乏权限时, 进入权限配置页面

if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) {

startPermissionsActivity();

}

}    private void startPermissionsActivity() {

PermissionsActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);

}    @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        // 拒绝时, 关闭页面, 缺乏主要权限, 没法运行

if (requestCode == REQUEST_CODE && resultCode == PermissionsActivity.PERMISSIONS_DENIED) {

finish();

}

}

}

核心权限必须知足, 如摄像应用, 摄像头权限就是必须的, 若是用户不予受权, 则直接关闭.

3. 受权页

受权页, 首先使用系统默认的受权页, 当用户拒绝时, 指导用户手动设置, 当用户再次操做失败后, 返回继续提示. 用户手动退出受权页时, 给使用页发送受权失败的通知.

/**

* 权限获取页面

* Created by wangchenlong on 16/1/26.

*/public class PermissionsActivity extends AppCompatActivity {    public static final int PERMISSIONS_GRANTED = 0; // 权限受权

public static final int PERMISSIONS_DENIED = 1; // 权限拒绝

private static final int PERMISSION_REQUEST_CODE = 0; // 系统权限管理页面的参数

private static final String EXTRA_PERMISSIONS =            "me.chunyu.clwang.permission.extra_permission"; // 权限参数

private static final String PACKAGE_URL_SCHEME = "package:"; // 方案

private PermissionsChecker mChecker; // 权限检测器

private boolean isRequireCheck; // 是否须要系统权限检测

// 启动当前权限页面的公开接口

public static void startActivityForResult(Activity activity, int requestCode, String... permissions) {

Intent intent = new Intent(activity, PermissionsActivity.class);

intent.putExtra(EXTRA_PERMISSIONS, permissions);

ActivityCompat.startActivityForResult(activity, intent, requestCode, null);

}    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getIntent() == null || !getIntent().hasExtra(EXTRA_PERMISSIONS)) {            throw new RuntimeException("PermissionsActivity须要使用静态startActivityForResult方法启动!");

}

setContentView(R.layout.activity_permissions);

mChecker = new PermissionsChecker(this);

isRequireCheck = true;

}    @Override protected void onResume() {        super.onResume();        if (isRequireCheck) {

String[] permissions = getPermissions();            if (mChecker.lacksPermissions(permissions)) {

requestPermissions(permissions); // 请求权限

} else {

allPermissionsGranted(); // 所有权限都已获取

}

} else {

isRequireCheck = true;

}

}    // 返回传递的权限参数

private String[] getPermissions() {        return getIntent().getStringArrayExtra(EXTRA_PERMISSIONS);

}    // 请求权限兼容低版本

private void requestPermissions(String... permissions) {

ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);

}    // 所有权限均已获取

private void allPermissionsGranted() {

setResult(PERMISSIONS_GRANTED);

finish();

}    /**

* 用户权限处理,

* 若是所有获取, 则直接过.

* 若是权限缺失, 则提示Dialog.

*

* @param requestCode  请求码

* @param permissions  权限

* @param grantResults 结果

*/

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {

isRequireCheck = true;

allPermissionsGranted();

} else {

isRequireCheck = false;

showMissingPermissionDialog();

}

}    // 含有所有的权限

private boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {        for (int grantResult : grantResults) {            if (grantResult == PackageManager.PERMISSION_DENIED) {                return false;

}

}        return true;

}    // 显示缺失权限提示

private void showMissingPermissionDialog() {

AlertDialog.Builder builder = new AlertDialog.Builder(PermissionsActivity.this);

builder.setTitle(R.string.help);

builder.setMessage(R.string.string_help_text);        // 拒绝, 退出应用

builder.setNegativeButton(R.string.quit, new DialogInterface.OnClickListener() {            @Override public void onClick(DialogInterface dialog, int which) {

setResult(PERMISSIONS_DENIED);

finish();

}

});

builder.setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() {            @Override public void onClick(DialogInterface dialog, int which) {

startAppSettings();

}

});

builder.show();

}    // 启动应用的设置

private void startAppSettings() {

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));

startActivity(intent);

}

}

注意isRequireCheck参数的使用, 防止和系统提示框重叠.

系统受权提示: ActivityCompat.requestPermissions, ActivityCompat兼容低版本.

效果

08a170788ff04ba28743e664.html

自定义受权

关键部分就这些了, 动态权限受权虽然给程序员带来了一些麻烦, 可是对用户仍是颇有必要的, 咱们也应该欢迎, 毕竟每一个程序员都是半个产品经理.

危险权限列表

08a170788ff04ba28743e664.html

危险权限列表

文/SpikeKing(简书做者)

原文连接:http://www.jianshu.com/p/dbe4d37731e6

著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值