【Android】关于 Android 获取图片权限的“二三事”
前言
开发 APP 的过程中有个更改用户头像的功能,当时做完后在真机上自测了几遍都能顺利流畅的更换头像,结果在其它开发同事手机上发现一直提示无权限打开相册,但是我这边的测试机又是好的,确认了代码同步、版本一致后,打了个包让其它同事帮忙测试,发现反映的情况各不同,有的能正常打开相册、甚至相机,但有的如果相册打不开的情况下,相机也是一样的问题:提示无权限,我立马查看对应的手机设置里对应的原生权限是否有开启,再三确认已经开启无误后,我是一点都摸不着头脑,这 Bug 是整哪一出?随即,我开始搜索相关问题的篇幅,不停的翻阅 Andriod 官方文档和相关插件 issues,功夫不负有心人,这虫终于让我给揪出来了。
问题:在不同安卓机型上出现,已知的有小米、oppo、荣耀、华为。
- 开始我一直以为是不同品牌的问题(并不是,因为在后续中发现相同品牌的也会出现这个问题)
描述:更换头像选择图片库或者相机的时候会有权限获取问题,有的失败、有的成功。
相关代码如下:
1 | // 使用的是expo官方的 |
推测:经过多方试验,怀疑跟 android:SdkVersion 有关,但官方 issue 里面也有相同的问题,但是没有好的解决方案。
issue1:https://github.com/expo/expo/issues/11504
issue2:https://github.com/expo/expo/issues/20496
方案
在 Android 官方文档上有说明 Android 6 对比 Android 13+,后者废弃了不少 API,其中就有关于原生权限这一块的,找到了原因就能对此做出对应的解决方案了,因为插件升级版本的话,其它一些依赖也要跟着升级,但是升级的风险就是很多 API 废弃、调用方式、参数等都有可能改变,包括对构建的 SDK 版本也会有更高版本的要求,考虑风险、成本后,还是决定弃用 expo 第三方插件,自己写一个工具函数来根据不同的 Android 版本进行兼容来获取相关的相册权限。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import { PermissionsAndroid, Platform, PermissionStatus } from "react-native";
/**
* 判断安卓是否有权限
* @returns {Promise<{status:PermissionStatus}>}
*/
export const hasAndroidPermission = async () => {
const OsVer = Platform.constants["Release"];
// GET SPECIFIC MEDIA PERMISSION ANDROID 13+
const permission =
parseInt(OsVer, 10) >= 13
? PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
: PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE;
const hasPermission = await PermissionsAndroid.check(permission);
if (hasPermission) return { status: "granted" };
const status = await PermissionsAndroid.request(permission);
return { status };
};感想
在当下,使用 React Native、Flutter、Uniapp 来替代原生 Andoriod、Ios 来开发 App,已经是众多公司的选择了,但是相应的对前端来说也是有许多大大小小的挑战、困难,从样式、业务功能、涉及到原生功能,在市面众多机型上都要能够适配,并且因为技术更迭速度快,导致如果进行大版本升级都要“伤筋动骨”,而且手机应用市场对 SDK 版本的要求也会动态上升调整,这就使开发者不得不去进行升级,只有不停下学习的脚步,才能适应这多变的时代。道阻且长,行则将至。