鸿蒙判断应用是否支持某能力
背景
在鸿蒙系统跨应用能力调用场景中,需解决以下核心问题:被调用方应用的版本是否满足当前所需功能。例如SDK判断抖音是否支持投稿、授权才真正进行拉起抖音,不然会出现拉起抖音后没有任何反应或者能力缺失。因此目标为实现在SDK侧能判断应用是否支持某能力。
方案对比(太长不看版)
| 方案 | 实现 | 是否可用 | 是否启动对方进程 | 优点 | 缺点 |
|---|---|---|---|---|---|
| metadata 字段读取 | 应用 A 在 module.json5 声明能力及版本号,SDK 侧用 bundleManager 读取 | ❌ | 不会启动 | 读取轻量,性能极高,不依赖进程存活;可以随意自定义字段 | 三方应用只能查自身包信息,SDK 无法读取其他应用信息 |
| DataShareExtensionAbility | 应用 A 侧声明并注册扩展能力,SDK 侧创建 DataShareHelper 查询 | ❌ | 会启动对方的 DataShareExtensionAbility 进程(但不拉 UI) | 跨应用通用,数据可动态更新。如果能力有问题在App侧可以通过settings修改值来避免拉起却不可用的情况。 | 第一次调用耗时(冷启动几十~几百 ms);IPC 大数据效率低;目前仅对系统应用开放,暂不提供相关内容与指导 |
| 使用 canOpenLink 判断应用是否可访问 | 调用方在 module.json5 配置 querySchemes 声明 URL scheme,调用 canOpenLink 接口;目标方配置 uris 属性 | ✅ | 不会启动 | 读取轻量,性能极高,不依赖进程存活 | 1. 调用方的 querySchemes 最多配置 50 个 URL scheme 2. 每次新增版本号需要在被调用侧新增 schema 的 host。 |
方案调研
metadata字段读取
实现
在应用A侧的module.json5 里声明能力及版本号:
1 | { |
在SDK侧使用bundleManager 读取字段
1 | import bundleManager from '@ohos.bundle.bundleManager'; |
问题
三方应用目前只能查询到自身应用包的信息,由于安全隐私,暂时不支持查询其他应用。因此在SDK侧无法通过bundleManager读取其他应用的信息。
https://developer.huawei.com/consumer/cn/doc/architecture-guides/insurance-v1_2-ts_34-0000002312854248
DataShareExtensionAbility
实现
在应用A侧声明 DataShareExtensionAbility在 ets/CustomDataShare.ets 里:
1 | import dataShare from '@ohos.data.dataShare'; |
在 module.json5 注册扩展能力
1
2
3
4
5
6
7
8
9
10{
"extensionAbilities": [
{
"name": "CustomDataShare",
"srcEntry": "./ets/CustomDataShare.ets",
"type": "dataShare",
"uri": "datashareproxy://com.example.provider"
}
]
}
SDK侧
1 | async queryCustomField() { |
问题
使用DataShareExtensionAbility实现数据共享:目前仅对系统应用开放,暂不具体展开提供相关内容和指导。
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/data-share-overview
canOpenLink 判断应用是否可访问
实现
参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/canopenlink
调用方(SDK):
- 在 entry 模块的 module.json5 文件中配置 querySchemes 属性,声明想要查询的 URL scheme。
1 | { |
- 调用 canOpenLink 接口:
1
2
3
4
5
6
7
8
9
10
11import { bundleManager } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
try {
let link = 'app1Scheme://test.example.com/home';
let canOpen = bundleManager.canOpenLink(link);
hilog.info(0x0000, 'testTag', 'canOpenLink successfully: %{public}s', JSON.stringify(canOpen));
} catch (err) {
let message = (err as BusinessError).message;
hilog.error(0x0000, 'testTag', 'canOpenLink failed: %{public}s', message);
}
目标方:
在 module.json5 文件中配置 uris 属性。
1 | { |
问题
querySchemes 中最多允许配置 50 个 URL scheme。因此限制不能无限使用新的 schema 头,但整体方案是可行的。