HarmonyOS 鸿蒙Next 如何解决Flutter使用permission_handler插件无法获取写入权限的问题
【问题现象】
在Flutter的HarmonyOS工程中集成permission_handler,执行代码时发现获取写入权限失败,无响应。
问题代码如下:
if (!(await Permission.storage.status.isGranted)) {
if (!(await Permission.storage.request().isGranted)) {
showFlutterToast(S.of(context).qx_nopermission);
dismissLoading();
return;
}
}
【背景知识】
对于权限申请,Flutter提供了三方库,该库简化了Flutter申请权限的流程。
【定位思路】
1. 从权限分析
上述问题中Permission.storage是Android中申请外部文件存储权限,实际上HarmonyOS中已无此对应权限。
2. 从插件源码分析
2.1 Dart侧
(1)插件Dart侧通过MethodChannel调用ohos适配侧方法,进行权限查询:
@override
Futurepermissionstatus checkPermissionStatus(Permission permission) async {
final status = await _methodChannel.invokeMethod(
'checkPermissionStatus', permission.value);return decodePermissionStatus(status);
}
(2)再查看permissions.dart类,storage权限对应的数值为15:
static PERMISSION_GROUP_STORAGE: number = 15;
2.2 Native****侧
(1)Native侧也是通过数值与Dart侧权限进行对应,参看类PermissionConstants.ets中值为15的权限也是Storage:
static PERMISSIONGROUPSTORAGE: number = 15;
(2)再看Native侧实现权限查询的方法,在类PermissionManager.ets中:
public checkPermissionStatus(permission: number, context: common.Context,
successCallback: CheckPermissionSuccessCallback): void {
this.determinePermissionStatus(permission, successCallback);
}
(3)进入determinePermissionStatus方法,截取核心部分:
PermissionUtils.getManifestNames(permission, (names: ArrayList<string>) => {
if (names == null || names == undefined) {
Log.d(PermissionConstants.LOG_TAG, "No android specific permissions needed for: " + permission);
successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
return;
}
if (names.length == 0) {
Log.d(PermissionConstants.LOG_TAG, "No permissions found in manifest for: " + names + permission);
if (permission == PermissionConstants.PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS) {
successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_DENIED);
return;
}
}
(4)通过PermissionUtils.getManifestNames进行权限名称转换,其核心代码:
let permissionNames: ArrayList<string>=newArrayList();
switch (permission) {
case PermissionConstants.PERMISSION_GROUP_STORAGE:
callback(permissionNames);
break;
(5)此时permissionNames为空,再参考上一段代码,当names.length == 0时会直接返回PERMISSION_STATUS_DENIED,所以问题中代码会永远返回false。
【解决方案】
问题中的代码会永远返回false,也无需申请此权限,下面以定位权限为例进行说明如何使用permission_handler插件申请对应权限。
1. 集成permission_handler****插件
需要在pubspec.yaml中加入依赖配置:
permission_handler:
git:
url: https://gitee.com/openharmony-sig/flutter_permission_handler.git
path: permission_handler
文件路径如图:
2. 在ohos中声明需要申请的权限
在ohos/entry/src/main/module.json5中声明需要申请的权限:
"requestPermissions": [
{"name": "ohos.permission.INTERNET"},
{
"name":"ohos.permission.LOCATION",
"reason":"$string:reason",
"usedScene": {
"abilities": [
"FormAbility"
],
"when":"inuse"
}
}
]
文件路径如图:
3. 在Dart中申请权限
编写Dart代码,申请定位权限用户授权:
Future<void> _requestPermissionsFromUser() async {
final status =
await _permissionHandler.requestPermissions([Permission.location]);
setState(() {
print(status);
_permissionStatus =
status[Permission.location] ?? PermissionStatus.denied;
print(_permissionStatus);
});
}
效果如下所示:
【总结】
针对HarmonyOS 鸿蒙Next上Flutter使用permission_handler插件无法获取写入权限的问题,可以尝试以下解决方案:
-
检查权限声明:
- 确保在鸿蒙特有的权限声明文件中已正确声明写入权限。
-
插件版本兼容性:
- 检查flutter_permission_handler插件的版本是否与鸿蒙OS版本兼容。
- 尝试更新插件到最新版本,或查看插件的官方文档了解支持的鸿蒙版本。
-
系统API调用:
- 鸿蒙系统可能修改了某些API的实现方式,导致原有方法无法正确请求权限。
- 查看鸿蒙系统的官方文档,了解如何正确调用相关API以请求写入权限。
-
代码实现:
- 检查调用权限请求的代码逻辑,确保在请求权限前已正确初始化插件。
- 确保正确处理回调结果,并根据结果进行相应的处理。
如果以上方法均无法解决问题,可能是由于系统级的bug或特定环境下的兼容性问题。此时,可以尝试在鸿蒙系统的开发者社区中搜索类似问题或提交新的issue。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。