6.0Android手机移动程序开发

Android6.0权限处理不再复杂

2017-04-13  本文已影响791人  街头客

前言

谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6.0出来,使得用户权限授权变得合理。

Android 6.0版本之前

在此版本之前,只要在清单文件(AndroidManifest)中申请需要用到的权限,安装之后,所申请的权限将会被允许。

Android 6.0版本之后

从Android6.0开始,APP可以直接安装,但所需的权限则需要动态申请。App在运行时询问用户授予权限,弹出Dialog窗口进行询问是否允许,【拒绝】之后,也可以引导用户前往设置界面。

权限分类

Google将权限分为两类:
一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等,所以开发者直接在清单文件中申请即可;

另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等;

但在Dangerous Permission中,其实还有比较特殊的两个权限存在,分别是SYSTEM_ALERT_WINDOW(允许一个程序打开窗口,显示在其他所有程序的顶层)WRITE_SETTINGS(允许应用程序更改主屏幕中的设置和快捷方式)

这两个权限也属于Dangerous Permission,但是在申请上却有点特殊。这两个权限是不能自动授权,也不能运行时请求授权,只能引导用户去应用的设置页手动开启

PS:Dangerous Permission的权限9大类别

Dangerous Permission的权限9大类别

只要授权某一个类别中的其中某一个权限,则该类别的权限默认全部授权,不需要针对该类别再次询问用户是否允许。

常用的权限申请

从Android6.0后,我们常用的权限申请,例如相机权限的申请,代码如下:

// 相机权限 2017/3/8 11:45
public static final int REQUEST_CAMERA = 4;
private static String[] PERMISSIONS_CAMERA = {
        Manifest.permission.CAMERA};

/**
 * 申请相机权限 2017/3/8 11:48
 * @param activity
 */
public static void cameraPermissions(Activity activity) {
    logger.debug("Camera permissions.");
    int permission = ActivityCompat.checkSelfPermission(activity,
            Manifest.permission.CAMERA);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        logger.debug("Not have camera permissions.");
        ActivityCompat.requestPermissions(activity, PERMISSIONS_CAMERA,
                REQUEST_CAMERA);
    }
}

上面是申请相机权限的代码,那么在调用的Activity类中,重写如下方法:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == RequestPermissions.REQUEST_CAMERA) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

        } else {
            Toast.makeText(this, "请授予相机权限", Toast.LENGTH_SHORT).show();
            finish();
        }

        return;
    }

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

以上就是我们常用的权限申请。

PermissionsDispatcher

权限调度者

使用

在module.build.gradle中配置,如下:

compile 'com.github.hotchemi:permissionsdispatcher:2.3.2'
annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.2'

PS

旧版需要在top.build.gradle中配置如下信息:

buildscript {
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

在module.build.gradle中配置,如下:

apply plugin: 'android-apt'

我在最新的版本2.3.2已经不需要以上的配置了,不然会生成失败。等会在下面会讲。

Activity中的使用

package com.example.chenchubin.mypermission;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;

import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.OnNeverAskAgain;
import permissions.dispatcher.OnPermissionDenied;
import permissions.dispatcher.OnShowRationale;
import permissions.dispatcher.PermissionRequest;
import permissions.dispatcher.RuntimePermissions;

@RuntimePermissions
public class ScanQRActivity extends Activity {

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

        // 检查权限 2017/4/13 17:22
        ScanQRActivityPermissionsDispatcher.getCameraWithCheck(this);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
            grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // 回调代理进行处理 2017/4/13 17:22
        ScanQRActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }

    /**
     * 已授权时,进入Activity会调用该方法 2017/4/13 17:22
     */
    @NeedsPermission(Manifest.permission.CAMERA)
    public void getCamera() {

    }

    /**
     * 授权申请提示,回调 2017/4/13 17:22
     * @param request
     */
    @OnShowRationale(Manifest.permission.CAMERA)
    public void showRationaleForCamera(final PermissionRequest request) {
        new AlertDialog.Builder(this)
                .setCancelable(false)
                .setTitle("权限申请")
                .setMessage("应用需要使用相机权限,您是否确定要使用")
                .setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.cancel();
                    }
                })
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.proceed();
                    }
                })
                .setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {

                    }
                })
                .show();
    }

    /**
     * 拒绝时,回调 2017/4/13 17:22
     */
    @OnPermissionDenied(Manifest.permission.CAMERA)
    public void showDeniedForCamera() {
        new AlertDialog.Builder(this)
                .setCancelable(false)
                .setTitle("权限申请")
                .setMessage("在设置-应用-当前应用权限中开启相机权限,以正常使用拍照")
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                    }
                })
                .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //开启设置页
                        startActivity(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
                        dialog.dismiss();
                    }
                })
                .show();
    }

    /**
     * 不再询问时,回调 2017/4/13 17:23
     */
    @OnNeverAskAgain(Manifest.permission.CAMERA)
    public void showNeverAskForCamera() {
        new AlertDialog.Builder(this)
                .setCancelable(false)
                .setTitle("权限申请")
                .setMessage("您已禁止不再询问,请前往设置-应用-当前应用权限中开启相机权限,以正常使用拍照")
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                    }
                })
                .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //开启设置页
                        startActivity(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
                        dialog.dismiss();
                    }
                })
                .show();
    }
}

注解的意思

@RuntimePermissions
(必选)运行时,需要检查权限的类。

@NeedsPermission
(必选)当进入Activity类时,如果已授权,会直接调用该注解的方法。

@OnShowRationale
(可选)授权申请时,调用。

@OnPermissionDenied
(可选)授权申请被拒绝时,调用。

@OnNeverAskAgain
(可选)授权申请被勾选不再提示时,调用。

PS:

1,执行request.proceed()调用系统申请权限的弹窗;
如果在系统申请弹窗中勾选了不在提示并且拒绝,会调用@OnNeverAskAgain的方法;

2,执行request.cancel()会调用@OnPermissionDenied的方法。

Make Project

Make Project后,编译器会在app\build\intermediates\classes\debug目录下与被注解的Activity同一个包下生成一个辅助类,名称为被注解的Activity名称+PermissionsDispatcher.class,如图所示:

ScanQRActivityPermissionsDispatcher

PS:

这里需要注意,因为我在这里遇到了一个大坑

就是上面提到的,新版中已不需要在top.build.gradle中配置android-apt插件,要不上面的ScanQRActivityPermissionsDispatcher一直没有生成出来,找了我半个小时。。。

生成代理类后,检查调用,代码如下:

// 检查权限 2017/4/13 17:22
ScanQRActivityPermissionsDispatcher.getCameraWithCheck(this);

运行效果

进入检查提示 确定时,提示 拒绝时,提示

这样使用后,Android权限请求这一块的逻辑就变得比较友好。

以上的所有内容就是今天要讲的关于Android6.0权限处理的内容。

我自己在写这文章时,也有所收获,同时希望能对大家有所帮助。

谢谢支持~~~

上一篇下一篇

猜你喜欢

热点阅读