Android动态权限问题探究(并解决OPPO动态权限)

本文探讨了Android动态权限申请的挑战,特别是在国内ROM环境下。提出了三个方案:敲击鉴权、BaseActivity中做伪欢迎页以及任何地方申请权限。方案详细描述了如何在不同场景下处理权限需求,并特别针对OPPO手机进行了优化。虽然方案在测试中表现良好,但也指出了一些潜在问题,如某些机型可能出现多次权限弹框,建议使用系统级判断作为保底措施。
摘要由CSDN通过智能技术生成

前言

之前调研了动态权限的申请方法,可是国内rom千奇百怪,真正实施起来的时候却不见得那么顺利,以前我们在Application里面承载了太多了业务逻辑,其中包含了需要READ_PHONE_STATE和WRITE_EXTERNAL_STORAGE权限的操作,所以这样的逻辑存在于Application里变得不合理,当然本来存放耗时逻辑在Application的onCreate里面就会影响APP启动速度,权限申请的方法在源码里面,存在于ActivityCompat里面的,所以Activity都没创建的时候是不可能完成权限申请的,所以权限动态申请的难点存在于对以往的逻辑进行搬家方面比较多,本文就传统App如何变成动态申请权限APP做一个探究。

方案

在我们APP里面目前在Activity尚未启动起来就需要权限的有两个地方:

权限 用途
READ_PHONE_STATE 友盟统计里面appsecurity需要deviceId、osName
READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE api请求缓存和插件下载都需要读写权限

目前其实还有地图定位的sdk需要定位权限,但是这个倒是可以往后放一放,但是插件化和统计需要的权限无法后移,必须一上来就有这两个权限,不然接口请求之类的都无法进行。就现在这个情况,有如下三种场景:

场景 周期方法
正常启动 Application onCreate ----> splashActivity —> 首页
尝试中偶尔有手机这样 Application onCreate -----> 其他页面
权限手动回收 无固定页面

总结一下上面的三个情况,其实有一个共同特点,就是启动都经过Activity的生命周期方法。对上述三个场景做公共部分提取:onCreate—>BaseActivity(权限申请和必要初始化)—>相关页面,该方案还需要做到在BaseActivity页面承载一个顶层view,实现和Splash一样的展示效果,对于真正的splash页面我们不做改动,只需要继承BaseActivity页面即可。
image

方案第一步–敲击鉴权

对于正常的rom,直接调用google api来检测是否有权限,但是vivo和oppo就不行,所以对于这两个品牌单独取出来,做敲击鉴权,随代码一份,测试敲击时间根据权限不同在虚拟机上耗时1-20ms不等

package com.ymt360.app.mass.permissionUtil.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.ContactsContract;
import android.support.v4.content.PermissionChecker;
import android.telephony.TelephonyManager;
import android.Manifest;
import android.hardware.Camera;
import java.lang.reflect.Field;

import com.ymt360.app.mass.YMTApp;
import com.ymt360.app.mass.util.OSUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import static android.content.Context.TELEPHONY_SERVICE;

/**
 * 对所有危险权限分组做权限判断
 * 所属权限组	权限名	权限等级	解释
 * 日历	READ_CALENDAR	危险	允许应用程序读取用户的日历数据
 * 日历	WRITE_CALENDAR	危险	允许应用程序写入用户的日历数据
 * 相机	CAMERA	危险	使用摄像头做相关工作
 * 联系人	READ_CONTACTS	危险	读取联系人
 * 联系人	WRITE_CONTACTS	危险	写入联系人
 * 联系人	GET_ACCOUNTS	危险	允许访问帐户服务中的帐户列表
 * 位置	ACCESS_FINE_LOCATION	危险	允许应用访问精确位置
 * 位置	ACCESS_COARSE_LOCATION	危险	允许应用访问大致位置
 * 麦克风	RECORD_AUDIO	危险	麦克风的使用
 * 电话	READ_PHONE_STATE	危险	允许对电话状态进行只读访问,包括设备的电话号码,当前蜂窝网络信息,任何正在进行的呼叫的状态以及设备上注册的任何PhoneAccounts列表
 * 电话	CALL_PHONE	危险	允许应用程序在不通过拨号器用户界面的情况下发起电话呼叫,以便用户确认呼叫
 * 电话	READ_CALL_LOG	危险	允许应用程序读取用户的通话记录
 * 电话	WRITE_CALL_LOG	危险	允许应用程序写入(但不读取)用户的呼叫日志数据
 * 电话	ADD_VOICEMAIL	危险	允许应用程序将语音邮件添加到系统中
 * 电话	USE_SIP	危险	允许应用程序使用SIP服务
 * 电话	PROCESS_OUTGOING_CALLS	危险	允许应用程序查看拨出呼叫期间拨打的号码,并选择将呼叫重定向到其他号码或完全中止呼叫
 * 传感器	BODY_SENSORS	危险	允许应用程序访问来自传感器的数据
 * 短信	SEND_SMS	危险	允许应用程序发送SMS消息
 * 短信	RECEIVE_SMS	危险	允许应用程序接收SMS消息
 * 短信	READ_SMS	危险	允许应用程序读取SMS消息
 * 短信	RECEIVE_WAP_PUSH	危险	允许应用程序接收WAP推送消息
 * 短信	RECEIVE_MMS	危险	允许应用程序监视传入的MMS消息(彩信)
 * 存储	READ_EXTERNAL_STORAGE	危险	允许应用程序从外部存储读取
 * 存储	WRITE_EXTERNAL_STORAGE	危险	允许应用程序写入外部存储
 *
 *
 * 防止权限判断错误,使用尝试性敲击权限检查,对分组的权限做哥敲击就性
 *
 *
 */
public class YMTPermissionCheckUtil {
    /**
     * 权限查询对外公布方法
     * @param permission
     * @return
     */
    public static boolean checkSelfPermission(String permission) {
        // 对于非oppo和vivo手机,做正常的权限申请
        if (permissionIsNormal()){
            return selfPermissionGranted(permission);
        }
        // 对于国内部分机型做非正常权限申请
        switch (permission){
            case Manifest.permission.CAMERA:
                return checkCameraPermissions();

            case Manifest.permission.RECORD_AUDIO:
                return checkAudioPermission();

            case Manifest.permission.BODY_SENSORS:
                return checkSensorsPermission();

            case Manifest.permission.READ_CALENDAR:
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值