提交 566be665 编写于 作者: G ge-yafang

update docs

Signed-off-by: Nge-yafang <geyafang@huawei.com>
上级 1d1e95b6
......@@ -34,7 +34,7 @@ Abilities are classified into two types: [Feature Ability (FA)](../../glossary.m
![en-us_image_0000001215206886](figures/en-us_image_0000001215206886.png)
This document provides a Page ability instance with two pages. For more information about ability development, see [Ability Development](../ability/ability-brief.md).
This document provides a Page ability instance with two pages. For more information about ability development, see [Ability Development](../ability/fa-brief.md).
## Tool Preparation
......
# Stage卡片开发指导
## 卡片概述
卡片是一种界面展示形式,可以将应用的重要信息或操作前置到卡片,以达到服务直达,减少体验层级的目的。
卡片常用于嵌入到其他应用(当前只支持系统应用)中作为其界面的一部分显示,并支持拉起页面,发送消息等基础的交互功能。卡片使用方负责显示卡片。
卡片的基本概念:
- 卡片提供方
提供卡片显示内容原子化服务,控制卡片的显示内容、控件布局以及控件点击事件。
- 卡片使用方
显示卡片内容的宿主应用,控制卡片在宿主中展示的位置。
- 卡片管理服务
用于管理系统中所添加卡片的常驻代理服务,包括卡片对象的管理与使用,以及卡片周期性刷新等。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 卡片使用方和提供方不要求常驻运行,在需要添加/删除/请求更新卡片时,卡片管理服务会拉起卡片提供方获取卡片信息。
开发者仅需作为卡片提供方进行卡片内容的开发,卡片使用方和卡片管理服务由系统自动处理。
卡片提供方控制卡片实际显示的内容、控件布局以及点击事件。
## 场景介绍
Stage卡片开发,即基于[Stage模型综述](stage-brief.md)的卡片提供方开发,主要涉及如下功能逻辑:
- 卡片生命周期回调函数FormExtension开发。
- 创建卡片数据FormBindingData对象。
- 通过FormProvider更新卡片。
- 卡片页面开发。
## 接口说明
FormExtension功能如下:FormExtension类,拥有context属性,具体的API详见[接口文档](../reference/apis/js-apis-formextension.md)
**表1** FormExtension API接口功能介绍
| 接口名 | 描述 |
| :----------------------------------------------------------- | :------------------------------------------- |
| onCreate(want: Want): formBindingData.FormBindingData | 卡片提供方接收创建卡片的通知接口。 |
| onCastToNormal(formId: string): void | 卡片提供方接收临时卡片转常态卡片的通知接口。 |
| onUpdate(formId: string): void | 卡片提供方接收更新卡片的通知接口。 |
| onVisibilityChange(newStatus: { [key: string]: number }): void | 卡片提供方接收修改可见性的通知接口。 |
| onEvent(formId: string, message: string): void | 卡片提供方接收处理卡片事件的通知接口。 |
| onDestroy(formId: string): void | 卡片提供方接收销毁卡片的通知接口。 |
| onConfigurationUpdated(config: Configuration): void; | 当系统配置更新时调用。 |
FormExtension类拥有context属性,context属性为FormExtensionContext类,具体的API详见[接口文档](../reference/apis/js-apis-formextensioncontext.md)
**表2** FormExtensionContext API接口功能介绍
| 接口名 | 描述 |
| :----------------------------------------------------------- | :------------------------ |
| updateForm(formId: string, formBindingData: formBindingData.FormBindingData, callback: AsyncCallback\<void>): void | 回调形式主动更新卡片。 |
| updateForm(formId: string, formBindingData: formBindingData.FormBindingData): Promise\<void> | Promise形式主动更新卡片。 |
FormProvider类具体的API详见[接口文档](../reference/apis/js-apis-formprovider.md)
**表3** FormProvider API接口功能介绍
| 接口名 | 描述 |
| :----------------------------------------------------------- | :------------------------------------------------ |
| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback&lt;void&gt;): void; | 设置指定卡片的下一次更新时间。 |
| setFormNextRefreshTime(formId: string, minute: number): Promise&lt;void&gt;; | 设置指定卡片的下一次更新时间,以promise方式返回。 |
| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback&lt;void&gt;): void; | 更新指定的卡片。 |
| updateForm(formId: string, formBindingData: FormBindingData): Promise&lt;void&gt;; | 更新指定的卡片,以promise方式返回。 |
## 开发步骤
### 创建卡片FormExtension
创建Stage模型的卡片,需实现FormExtension生命周期接口。具体示例代码如下:
1. 导入相关模块
```javascript
import FormExtension from '@ohos.application.FormExtension'
import formBindingData from '@ohos.application.formBindingData'
import formInfo from '@ohos.application.formInfo'
import formProvider from '@ohos.application.formProvider'
```
2. 实现FormExtension生命周期接口
```javascript
export default class FormAbility extends FormExtension {
onCreate(want) {
console.log('FormAbility onCreate');
// 由开发人员自行实现,将创建的卡片信息持久化,以便在下次获取/更新该卡片实例时进行使用
let obj = {
"title": "titleOnCreate",
"detail": "detailOnCreate"
};
let formData = formBindingData.createFormBindingData(obj);
return formData;
}
onCastToNormal(formId) {
// 使用方将临时卡片转换为常态卡片触发,提供方需要做相应的处理
console.log('FormAbility onCastToNormal');
}
onUpdate(formId) {
// 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要覆写该方法以支持数据更新
console.log('FormAbility onUpdate');
let obj = {
"title": "titleOnUpdate",
"detail": "detailOnUpdate"
};
let formData = formBindingData.createFormBindingData(obj);
formProvider.updateForm(formId, formData).catch((error) => {
console.log('FormAbility updateForm, error:' + JSON.stringify(error));
});
}
onVisibilityChange(newStatus) {
// 使用方发起可见或者不可见通知触发,提供方需要做相应的处理
console.log('FormAbility onVisibilityChange');
}
onEvent(formId, message) {
// 若卡片支持触发事件,则需要覆写该方法并实现对事件的触发
console.log('FormAbility onEvent');
}
onDestroy(formId) {
// 删除卡片实例数据
console.log('FormAbility onDestroy');
}
onAcquireFormState(want) {
console.log('FormAbility onAcquireFormState');
return formInfo.FormState.READY;
}
}
```
### 配置卡片配置文件
Form需要在应用配置文件module.json中进行配置。
- extensionAbility模块,内部字段结构说明:
| 属性名称 | 含义 | 数据类型 | 是否可缺省 |
| ----------- | ------------------------------------------------------------ | ---------- | -------------------- |
| name | 表示extensionAbility的名字。该标签不可缺省。 | 字符串 | 否 |
| srcEntrance | 表示extensionAbility所对应的JS的代码路径。该标签不可缺省。 | 字符串 | 否 |
| description | 表示extensionAbility的描述。可以是表示描述内容的字符串,也可以是对描述内容的资源索引以支持多语言。 | 字符串 | 可缺省,缺省值为空。 |
| icon | 表示extensionAbility的图标资源文件的索引。 | 字符串 | 可缺省,缺省值为空。 |
| label | 表示extensionAbility的标签信息,即extensionAbility对外显示的文字描述信息。取值可以是描述性内容,也可以是标识label的资源索引。 | 字符串 | 可缺省,缺省值为空。 |
| type | 表示extensionAbility的类型。取值form、service等 | 字符串 | 否 |
| permissions | 表示其他应用的Ability调用此Ability时需要申请的权限。 | 字符串数组 | 可缺省,缺省值为空。 |
| metadata | 表示extensionAbility的元信息。用于描述extensionAbility的配置信息。 | 对象 | 可缺省,缺省值为空 |
对于FormExtensionAbility来说,type需要配置为form,并且需要填写metadata元信息,用于配置卡片的具体信息。
配置示例如下:
```json
"extensionAbilities": [{
"name": "FormAbility",
"srcEntrance": "./ets/FormAbility/FormAbility.ts",
"label": "$string:form_FormAbility_label",
"description": "$string:form_FormAbility_desc",
"type": "form",
"metadata": [{
"name": "ohos.extension.form",
"resource": "$profile:form_config"
}]
}]
```
- 卡片profile模块。在 FormExtensionAbility 的元信息中,需要使用 ohos.extension.form 指定的资源文件的路径,如使用 $profile:form_config 指定开发视图的 resources/base/profile/ 目录下的 form_config.json 作为卡片profile配置文件。
内部字段结构说明:
| 属性名称 | 含义 | 数据类型 | 是否可缺省 |
| ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ |
| name | 表示卡片的类名。字符串最大长度为127字节。 | 字符串 | 否 |
| description | 表示卡片的描述。取值可以是描述性内容,也可以是对描述性内容的资源索引,以支持多语言。字符串最大长度为255字节。 | 字符串 | 可缺省,缺省为空。 |
| src | 表示卡片对应的UI代码的完整路径。 | 字符串 | 否 |
| window | 用于定义与显示窗口相关的配置。 | 对象 | 可缺省 |
| isDefault | 表示该卡片是否为默认卡片,每个Ability有且只有一个默认卡片。<br />true:默认卡片。<br />false:非默认卡片。 | 布尔值 | 否 |
| colorMode | 表示卡片的主题样式,取值范围如下:<br />auto:自适应。<br />dark:深色主题。<br />light:浅色主题。 | 字符串 | 可缺省,缺省值为“auto”。 |
| supportDimensions | 表示卡片支持的外观规格,取值范围:<br />1 * 2:表示1行2列的二宫格。<br />2 * 2:表示2行2列的四宫格。<br />2 * 4:表示2行4列的八宫格。<br />4 * 4:表示4行4列的十六宫格。 | 字符串数组 | 否 |
| defaultDimension | 表示卡片的默认外观规格,取值必须在该卡片supportDimensions配置的列表中。 | 字符串 | 否 |
| updateEnabled | 表示卡片是否支持周期性刷新,取值范围:<br />true:表示支持周期性刷新,可以在定时刷新(updateDuration)和定点刷新(scheduledUpdateTime)两种方式任选其一,优先选择定时刷新。<br />false:表示不支持周期性刷新。 | 布尔类型 | 否 |
| scheduledUpdateTime | 表示卡片的定点刷新的时刻,采用24小时制,精确到分钟。 | 字符串 | 可缺省,缺省值为“0:0”。 |
| updateDuration | 表示卡片定时刷新的更新周期,单位为30分钟,取值为自然数。<br />当取值为0时,表示该参数不生效。<br />当取值为正整数N时,表示刷新周期为30*N分钟。 | 数值 | 可缺省,缺省值为“0”。 |
| formConfigAbility | 表示用于调整卡片的设施或活动的名称。 | 字符串 | 可缺省,缺省值为空。 |
| formVisibleNotify | 标识是否允许卡片使用卡片可见性通知 | 字符串 | 可缺省,缺省值为空。 |
| metaData | 表示卡片的自定义信息,包含customizeData数组标签。 | 对象 | 可缺省,缺省值为空。 |
配置示例如下:
```json
{
"forms": [{
"name": "widget",
"description": "This is a service widget.",
"src": "./js/widget/pages/index/index",
"window": {
"autoDesignWidth": true,
"designWidth": 720
},
"isDefault": true,
"colorMode": "auto",
"supportDimensions": ["2*2"],
"defaultDimension": "2*2",
"updateEnabled": true,
"scheduledUpdateTime": "10:30",
"updateDuration": 1
}]
}
```
### 卡片信息的持久化
因大部分卡片提供方都不是常驻服务,只有在需要使用时才会被拉起获取卡片信息,且卡片管理服务支持对卡片进行多实例管理,卡片ID对应实例ID,因此若卡片提供方支持对卡片数据进行配置,则需要对卡片的业务数据按照卡片ID进行持久化管理,以便在后续获取、更新以及拉起时能获取到正确的卡片业务数据。
```javascript
onCreate(want) {
console.log('FormAbility onCreate');
let formId = want.parameters["ohos.extra.param.key.form_identity"];
let formName = want.parameters["ohos.extra.param.key.form_name"];
let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"];
// 由开发人员自行实现,将创建的卡片信息持久化,以便在下次获取/更新该卡片实例时进行使用
storeFormInfo(formId, formName, tempFlag, want);
let obj = {
"title": "titleOnCreate",
"detail": "detailOnCreate"
};
let formData = formBindingData.createFormBindingData(obj);
return formData;
}
```
且需要适配onDestroy卡片删除通知接口,在其中实现卡片实例数据的删除。
```javascript
onDestroy(formId) {
// 删除卡片实例数据
deleteFormInfo(formId);
console.log('FormAbility onDestroy');
}
```
具体的持久化方法可以参考[轻量级数据存储开发指导](../database/database-storage-guidelines.md)。
需要注意的是,卡片使用方在请求卡片时传递给提供方应用的Want数据中存在临时标记字段,表示此次请求的卡片是否为临时卡片:
常态卡片:卡片使用方会持久化的卡片;
临时卡片:卡片使用方不会持久化的卡片;
由于临时卡片的数据具有非持久化的特殊性,某些场景比如卡片服务框架死亡重启,此时临时卡片数据在卡片管理服务中已经删除,且对应的卡片ID不会通知到提供方,所以卡片提供方需要自己负责清理长时间未删除的临时卡片数据。同时对应的卡片使用方可能会将之前请求的临时卡片转换为常态卡片。如果转换成功,卡片提供方也需要对对应的临时卡片ID进行处理,把卡片提供方记录的临时卡片数据转换为常态卡片数据,防止提供方在清理长时间未删除的临时卡片时,把已经转换为常态卡片的临时卡片信息删除,导致卡片信息丢失。
### 开发卡片页面
开发者可以使用hml+css+json开发JS卡片页面:
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 当前仅支持JS扩展的类Web开发范式来实现卡片的UI页面。
- hml:
```html
<div class="container">
<stack>
<div class="container-img">
<image src="/common/widget.png" class="bg-img"></image>
</div>
<div class="container-inner">
<text class="title">{{title}}</text>
<text class="detail_text" onclick="routerEvent">{{detail}}</text>
</div>
</stack>
</div>
```
- css:
```css
.container {
flex-direction: column;
justify-content: center;
align-items: center;
}
.bg-img {
flex-shrink: 0;
height: 100%;
}
.container-inner {
flex-direction: column;
justify-content: flex-end;
align-items: flex-start;
height: 100%;
width: 100%;
padding: 12px;
}
.title {
font-size: 19px;
font-weight: bold;
color: white;
text-overflow: ellipsis;
max-lines: 1;
}
.detail_text {
font-size: 16px;
color: white;
opacity: 0.66;
text-overflow: ellipsis;
max-lines: 1;
margin-top: 6px;
}
```
- json:
```json
{
"data": {
"title": "TitleDefault",
"detail": "TextDefault"
},
"actions": {
"routerEvent": {
"action": "router",
"abilityName": "com.example.MyApplication.hmservice.FormAbility",
"params": {
"message": "add detail"
}
}
}
}
```
最终可以得到,如下卡片:
![fa-form-example](figures/fa-form-example.png)
\ No newline at end of file
......@@ -8,4 +8,5 @@
- 开发基础知识
- [包结构说明](package-structure.md)
- [资源文件的分类](basic-resource-file-categories.md)
- [SysCap说明](syscap.md)
......@@ -34,7 +34,7 @@ Ability可以分为[FA(Feature Ability)](../../glossary.md#f)和[PA(Partic
![zh-cn_image_0000001215206886](figures/zh-cn_image_0000001215206886.png)
快速入门提供了一个含有两个页面的Page Ability实例。更多Ability的开发内容及指导,请参见[Ability开发](../ability/ability-brief.md)
快速入门提供了一个含有两个页面的Page Ability实例。更多Ability的开发内容及指导,请参见[Ability开发](../ability/fa-brief.md)
## 工具准备
......
# SysCap使用指南
## 概述
### 系统能力与 API
SysCap,全称SystemCapability,即系统能力,指操作系统中每一个相对独立的特性,如蓝牙,WIFI,NFC,摄像头等,都是系统能力之一。每个系统能力对应多个 API,这些 API 绑定在一起,随着目标设备是否支持该系统能力共同存在或消失,也会随着 IDE 一起提供给开发者做联想。
![image-20220326064841782](figures/image-20220326064841782.png)
### 支持能力集,联想能力集与要求能力集
支持能力集,联想能力集与要求能力集都是系统能力的集合。
支持能力集描述的是设备能力,要求能力集描述的是应用能力。若应用A的要求能力集是设备N的支持能力集的子集,则应用A可分发到设备N上安装运行,否则不能分发。
联想能力集是该应用开发时,IDE 可联想的 API 所在的系统能力集合。
![image-20220326064913834](figures/image-20220326064913834.png)
### 设备与支持能力集
每个设备根据其硬件能力,对应不同的支持能力集。
SDK 将设备分为两组,爆款设备和自定义设备,爆款设备的支持能力集由 OpenHarmony 来定义,自定义设备由设备厂商给出。
![image-20220326064955505](figures/image-20220326064955505.png)
### 设备与SDK能力的对应
SDK 提供全量的 API 给 IDE,IDE 通过开发者的项目支持的设备,找到该设备的支持能力集,筛选支持能力集包含的 API 提供给开发者做联想。
![image-20220326065043006](figures/image-20220326065043006.png)
## SysCap开发指导
### PCID导入
DevEco Studio 工程支持 PCID 的导入。导入的 PCID 文件解码后输出的 syscap 会被写入 syscap.json 文件中。
在工程目录右键后选择 Import Product Compatibility ID,即可上传 PCID 文件并导入至 syscap.json 中。
![20220329-103626](figures/20220329-103626.gif)
### 配置联想能力集和要求能力集
IDE 会根据创建的工程所支持的设置自动配置联想能力集和要求能力集,开发者也可以自行修改。
对于联想能力集,开发者通过添加更多的系统能力,在 IDE 中可以使用更多的 API,但要注意这些 API 可能在设备上不支持,使用前需要判断。
对于要求能力集,开发者修改时要十分慎重,修改不当会导致应用无法分发到目标设备上。
```
/* syscap.json */
{
devices: {
general: [ /*每一个爆款设备对应一个syscap支持能力集,可配置多个爆款设备*/
“phone”,
"car,
"pc",
...
],
custom: [ /*厂家自定义设备*/
{
"某自定义设备": [
"SystemCapability.Communication.SoftBus.Core",
...
]
},
...
]
},
development: { /*addedSysCaps内的sycap集合与devices中配置的各设备支持的syscap集合的并集共同构成联想能力集*/
addedSysCaps: [
"SystemCapability.Location.Location.Lite",
...
]
},
production: { /*用于生成rpcid,慎重添加,可能导致应用无法分发到目标设备上*/
addedSysCaps: [], //devices中配置的各设备支持的syscap集合的交集,添加addedSysCaps集合再除去removedSysCaps集合,共同构成要求能力集
removedSysCaps: [] //当该要求能力集为某设备的子集时,应用才可被分发到该设备上
}
}
```
### 单设备应用开发
默认应用的联想能力集、要求系统能力集和设备的支持系统能力集相等,开发者修改要求能力集需要慎重。
![image-20220326065124911](figures/image-20220326065124911.png)
### 跨设备应用开发
默认应用的联想能力集是多个设备支持能力集的并集,要求能力集则是交集。
![image-20220326065201867](figures/image-20220326065201867.png)
### 判断 API 是否可以使用
首先我们定义了 API canIUse 帮助开发者来判断该工程是否支持某个特定的syscap。
```
if (canIUse("SystemCapability.ArkUI.ArkUI.Full")) {
console.log("该应用支持SystemCapability.ArkUI.ArkUI.Full");
} else {
console.log("该应用不支持SystemCapability.ArkUI.ArkUI.Full");
}
```
开发者可通过 import 的方式将模块导入,若当前设备不支持该模块,import 的结果为 undefined,开发者在使用其 API 时,需要判断其是否存在。
```
import geolocation from '@ohos.geolocation';
if (geolocation) {
geolocation.getCurrentLocation((location) => {
console.log(location.latitude, location.longitude);
});
} else {
console.log('该设备不支持位置信息');
}
```
### 不同设备相同能力的差异检查
即使是相同的系统能力,在不同的设备下,也会有能力的差异。比如同是摄像头的能力,手机比手表要强很多。
```
import userAuth from '@ohos.userIAM.userAuth';
const authenticator = userAuth.getAuthenticator();
const result = authenticator.checkAbility('FACE_ONLY', 'S1');
if (result == authenticator.CheckAvailabilityResult.AUTH_NOT_SUPPORT) {
console.log('该设备不支持人脸识别');
}
//强行调用不支持的 API 会返回错误信息,但不会出现语法错误。
authenticator.execute('FACE_ONLY', 'S1', (err, result) => {
if (err) {
console.log(err.message);
return;
}
})
```
### 设备间的SysCap差异如何产生的
设备的SysCap因产品解决方案厂商拼装的部件组合不同而不同,整体流程如下图:
![image-20220326072448840](figures/image-20220326072448840.png)
1、一套 OpenHarmony 源码由可选和必选部件集组成,不同的部件为对外体现的系统能力不同,即部件与 SysCap 之间映射关系。
2、发布归一化的 SDK,API 与 SysCap 之间存在映射关系。
3、产品解决方案厂商按硬件能力和产品诉求,可按需拼装部件。
4、产品配置的部件可以是 OpenHarmony 的部件,也可以是三方开发的私有部件,由于部件与SysCap间存在映射,所有拼装后即可得到该产品的SysCap集合。
5、SysCap集编码生成 PCID (Product Compatibility ID, 产品兼容性标识),应用开发者可将 PCID 导入 IDE解码成SysCap ,开发时对设备的SysCap差异做兼容性处理。
6、部署到设备上的系统参数中包含了 SysCap 集,系统提供了native的接口和应用接口,可供系统内的部件和应用查询某个 SysCap 是否存在。
7、应用开发过程中,应用必要的 SysCap 将被编码成 RPCID(Required Product Compatibility ID),并写入应用安装包中。应用安装时,包管理器将解码 RPCID 得到应用需要的 SysCap,与设备当前具备的 SysCap 比较,若应用要求的 SysCap 都被满足,则安装成功。
8、应用运行时,可通过 canIUse 接口查询设备的 SysCap,保证在不同设备上的兼容性。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册