从零开始搭建一个主流项目框架(七)—— 权限申请(Android 6.0)

个人博客:haichenyi.com。感谢关注

  总所周知,Android 6.0以上的版本,google对权限做了更严格的限制,不能app自动给权限,必须要让用户选择是否给权限。如果,用户不给权限,辣么,用这个功能的时候,app会造成崩溃,所以,最简单的办法就是,用户不给权限,不让用户用这个功能,也就是页面不做跳转。

  当时,刚出来这个权限问题的时候,本人用原生的写,写了封装,搞了好长时间,总感觉各种不爽,各种不舒服,后来好了,大牛封装了一个开源框架——RxPermission,一行代码解决动态申请权限问题。

依赖

implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'

工具类

package com.haichenyi.myproject.utils

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.support.v7.app.AlertDialog
import com.haichenyi.myproject.R
import com.tbruyelle.rxpermissions2.RxPermissions
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.util.*

/**
 * Author: 海晨忆
 * Date: 2018/2/28
 * Desc:
 */
object RxPerUtils {

    /**
     * 请求权限的获取方法
     * activity:Activity对象
     * permissions:需要获取的权限,可以传多个
     * aloe: (b: Boolean):一个参数的回调方法,b为true,表示用户给了权限,false,表示没有给权限
     */
    fun requestPermission(activity: Activity, vararg permissions: String, aloe: (b: Boolean) -> Unit) {
        RxPermissions(activity).request(*permissions)
                .subscribe { aBoolean -> aloe(aBoolean) }
    }
    
    /**
     * 当用户拒绝给权限的时候调用,跳转权限设置页面,让用户手动给权限
     * activity:Activity对象
     * permissionName:权限名称
     * msg:提示信息
     */
    fun setupPermission(activity: Activity, permissionName: String, msg: String,
                        aloe: () -> Unit) {
        AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog).setTitle("权限申请")
                .setMessage(String.format(Locale.getDefault(),
                        "请在“权限”中开启“%1s权限”,以正常使用%2s", permissionName, msg))
                .setCancelable(false)
                .setNegativeButton(android.R.string.cancel) { dialog, which -> aloe }.setPositiveButton("去设置") { dialog, which ->
            if (isMiUi()) {
                setMiUiPermissions(activity)
            } else {
                activity.startActivityForResult(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        .setData(Uri.fromParts("package", activity.packageName, null)), 1000)
            }
        }.create().show()
    }

    private fun setMiUiPermissions(activity: Activity) {
        if (isMiUi()) {
            try {
                // MIUI 8
                activity.startActivityForResult(Intent("miui.intent.action.APP_PERM_EDITOR")
                        .setClassName("com.miui.securitycenter",
                                "com.miui.permcenter.permissions.PermissionsEditorActivity")
                        .putExtra("extra_pkgname", activity.packageName), 1000)
            } catch (e: Exception) {
                try {
                    // MIUI 5/6/7
                    activity.startActivityForResult(Intent("miui.intent.action.APP_PERM_EDITOR")
                            .setClassName("com.miui.securitycenter",
                                    "com.miui.permcenter.permissions.AppPermissionsEditorActivity")
                            .putExtra("extra_pkgname", activity.packageName), 1000)
                } catch (e1: Exception) {
                    // 否则跳转到应用详情
                    activity.startActivityForResult(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                            .setData(Uri.fromParts("package", activity.packageName,
                                    null)), 1000)
                }
            }
        }
    }

    private fun isMiUi(): Boolean {
        val device = Build.MANUFACTURER
        if (device == "Xiaomi") {
            try {
                val prop = Properties()
                prop.load(FileInputStream(File(Environment.getRootDirectory(), "build.prop")))
                return (prop.getProperty("ro.miui.ui.version.code", null) != null
                        || prop.getProperty("ro.miui.ui.version.name", null) != null
                        || prop.getProperty("ro.miui.internal.storage", null) != null)
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return false
    }
}

调用

RxPerUtils.requestPermission(this, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE) {
                if (it) {
                    //这里写你自己的逻辑,已经获得权限,做你自己的业务逻辑操作
                    ToastUtils.showTipMsg("已经获得权限")
                } else {
                    RxPerUtils.setupPermission(this, "相机和存储",
                            "相机功能") {
                    }
                }
            }

  请求权限的整个过程就是:

  1. 用RxPermission去请求权限,需要传activity对象,然后就是你需要获取的权限(可以传多个),再就是回调方法
  2. 在回调方法里面做判断,用户是否给了权限,如果给了,就走你正常的逻辑。如果没有给,就弹对话框提示用户,去设置页面给权限。

  就这么简单,方法都封装好了,如果,你嫌弃系统自带的对话框样式不好看,你也可以自己写一个样式。项目就不传了,如果你有之前的代码,就直接把我这几个方法拷贝过去用就可以了,没有之前的代码,就去瞅瞅之前的博客吧。

    原文作者:海晨忆
    原文地址: https://www.jianshu.com/p/a15bf21be38a
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞