HarmonyOS 鸿蒙Next 如何解决Flutter使用permission_handler插件无法获取写入权限的问题

发布于 1周前 作者 h691938207 最后一次编辑是 5天前 来自 鸿蒙OS

【问题现象】

在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);
  });
}

效果如下所示:

点击放大

【总结】

  • 应用在申请权限时,需要在项目的配置文件中,逐个声明需要的权限,否则应用将无法获取授权,具体可参考授权方式
  • Flutter可以申请的权限是ohos可以申请的权限的子集,ohos可以申请的权限清单
  • flutter_permission_handler插件已经提供的供申请的权限清单
1 回复

针对HarmonyOS 鸿蒙Next上Flutter使用permission_handler插件无法获取写入权限的问题,可以尝试以下解决方案:

  1. 检查权限声明

    • 确保在鸿蒙特有的权限声明文件中已正确声明写入权限。
  2. 插件版本兼容性

    • 检查flutter_permission_handler插件的版本是否与鸿蒙OS版本兼容。
    • 尝试更新插件到最新版本,或查看插件的官方文档了解支持的鸿蒙版本。
  3. 系统API调用

    • 鸿蒙系统可能修改了某些API的实现方式,导致原有方法无法正确请求权限。
    • 查看鸿蒙系统的官方文档,了解如何正确调用相关API以请求写入权限。
  4. 代码实现

    • 检查调用权限请求的代码逻辑,确保在请求权限前已正确初始化插件。
    • 确保正确处理回调结果,并根据结果进行相应的处理。

如果以上方法均无法解决问题,可能是由于系统级的bug或特定环境下的兼容性问题。此时,可以尝试在鸿蒙系统的开发者社区中搜索类似问题或提交新的issue。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部