【EasyPermissions】Simplify Android M System Permissions

Github:https://github.com/googlesamples/easypermissions

AndroidM发布后有一个很重要的更新,就是Android里面权限模式的更新!用户需要手动去获取权限而不是开始安装的时候就获取权限!所以,Android M在面向旧版本的应用的时候,可能会因为权限的问题而导致crash。

在Android M版本发布之前,Android系统中的权限模式一直采取较为简单粗暴的处理方式——即在安装之时由用户作出全部允许或者全不允许的二元选择。这意味着如果用户希望使用某款应用程序,则首先需要接受其中包含的全部权限要求或者干脆放弃安装。这就导致很多开发人员的编程成果在安装之时就被用户所弃用,根本无法真正实现用户与开发者间的信任关系乃至其它隐私保障手段。

AndroidM获取权限流程

尽管针对Android M开发而成的应用程序必须采用新型权限对话框与相关实现方法,但面向早期Android版本构建的应用仍然会在安装时直接向用户显示权限列表并要求一次性接受或拒绝。不过在Android M当中,用户完全可以在作出选择之后随时对相关权限进行调用。

Android M的权限大部分分为三种,Dangerous,Normal,specials,下面是危险权限的权限表!

1.png

由于负责处理权限调用任务的底层结构并不适用于面向早期Android版本的应用程序,所以当相关权限未被接受时,任何要求配合相关权限的功能都会返回null、0或者空值。这有可能导致应用程序出现意料之外的行为,因此建议各位开发人员对自己的原有应用程序进行升级,以确保其尽早支持Android M中的全新权限模式。

如何获取简单获取Android M的权限,Google在Github上面给我们提供了EasyPremissions这个库!EasyPermisssions 是一个可以在Android M和更高版本上进行获取权限操作的第三方库,而且不用开发者来判断当前版本,适配了低版本的sdk!

开始

  1. 重写onRequestPermissionsResult方法
    <pre>public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    }

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

     // Forward results to EasyPermissions
     EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    

    }
    }</pre>

  2. 请求权限
    2.1 使用EasyPermissions.hasPermissions来判断app是否已经获得了该权限。这个方法可以获得多个权限。
    2.2 通过EasyPermissisons.requestPermissions来请求系统权限,用户通过rationale提示文字信息来判断是否给与用户该权限
    2.3 使用AfterPermissionGranted注释,这是可选的,但是提供出来是为了方便。如果所有的请求的权限都被授予了,被注解的方法将会被执行,这样做是为了简化通常的请求权限成功之后再调用方法的流程。同时也可以在 onPermissionsGranted的回调中添加逻辑操作~~~他们的区别在于:一个是所有的权限都允许的时候,一个是通过一项允许就运行,就是这个差别!后面有一些源码的分析。。。

<pre>@AfterPermissionGranted(RC_CAMERA_AND_WIFI)
private void methodRequiresTwoPermission() {
String[] perms = {Manifest.permission.CAMERA, Manifest.permission.CHANGE_WIFI_STATE};
if (EasyPermissions.hasPermissions(this, perms)) {
// Already have permission, do the thing
// ...
} else {
// Do not have permissions, request them now
EasyPermissions.requestPermissions(this, getString(R.string.camera_and_wifi_rationale),
RC_CAMERA_AND_WIFI, perms);
}
}</pre>
2.4 实现PermissionCallbacks接口
<pre> @Override
public void onPermissionsGranted(int requestCode, List<String> list) {
// Some permissions have been granted
// ...
}

@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
    // Some permissions have been denied
    // ...
}</pre>

3.如果被用户选择了不再提示。。。我们需要去设置里面给我们的应用相应的权限
<pre>@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size());
// (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN."
// This will display a dialog directing them to enable the permission in app settings.
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this, getString(R.string.rationale_ask_again))
.setTitle(getString(R.string.title_settings_dialog))
.setPositiveButton(getString(R.string.setting))
.setNegativeButton(getString(R.string.cancel), null /* click listener */)
.setRequestCode(RC_SETTINGS_SCREEN)
.build()
.show();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SETTINGS_SCREEN) {
// Do something after user returned from app settings screen, like showing a Toast.
Toast.makeText(this, R.string.returned_from_app_settings_to_activity, Toast.LENGTH_SHORT)
.show();
}
}</pre>

最后附上EasyPermissions的源码
<pre>
public class EasyPermissions {
/**
* Handle the result of a permission request, should be called from the calling Activity's
* {@link android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult(int, String[], int[])}
* method.
* <p/>
* If any permissions were granted or denied, the Activity will receive the appropriate
* callbacks through {@link PermissionCallbacks} and methods annotated with
* {@link AfterPermissionGranted} will be run if appropriate.
*
* @param requestCode requestCode argument to permission result callback.
* @param permissions permissions argument to permission result callback.
* @param grantResults grantResults argument to permission result callback.
* @param object the calling Activity or Fragment.
* @throws IllegalArgumentException if the calling Activity does not implement
* {@link PermissionCallbacks}.
*/
public static void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults, Object object) {
//判断传入参数是否合适
checkCallingObjectSuitability(object);
//合适的话直接强转,不合适抛异常
PermissionCallbacks callbacks = (PermissionCallbacks) object;

    // Make a collection of granted and denied permissions from the request.
    ArrayList<String> granted = new ArrayList<>();
    ArrayList<String> denied = new ArrayList<>();
  //判断返回的权限数据,如果权限被授予,添加到granted的List中,没有被授予则添加到denied的List中
    for (int i = 0; i < permissions.length; i++) {
        String perm = permissions[i];
        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
            granted.add(perm);
        } else {
            denied.add(perm);
        }
    }

    // Report granted permissions, if any.
  //进行回调
    if (!granted.isEmpty()) {
        // Notify callbacks
        callbacks.onPermissionsGranted(requestCode, granted);
    }

    // Report denied permissions, if any.
  //进行回调
    if (!denied.isEmpty()) {
        callbacks.onPermissionsDenied(requestCode, denied);
    }

    // If 100% successful, call annotated methods
  //如果所有请求的权限都被授予,则调用被注解的方法
    if (!granted.isEmpty() && denied.isEmpty()) {
        runAnnotatedMethods(object, requestCode);
    }
}

}</pre>

个人建议,早用早好!!!填坑之路,还远着呢!

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

推荐阅读更多精彩内容