提交 f80e7983 编写于 作者: zyjhandsome's avatar zyjhandsome

1、向用户申请授权接口从UIAbilityContext迁移到安全模块,配套修改

2、申请授权统一术语
Signed-off-by: zyjhandsome's avatarzyjhandsome <zyjhandsome@126.com>
上级 fa67d0fb
......@@ -27,8 +27,7 @@
"host": "www.test.com",
"port": "8080",
// prefix matching
"pathStartWith": "query",
"type": "text/*"
"pathStartWith": "query"
},
{
"scheme": "http",
......@@ -57,8 +56,7 @@ function implicitStartAbility() {
"action": "ohos.want.action.viewData",
// entities can be omitted.
"entities": ["entity.system.browsable"],
"uri": "https://www.test.com:8080/query/student",
"type": "text/plain"
"uri": "https://www.test.com:8080/query/student"
}
context.startAbility(wantInfo).then(() => {
// ...
......
......@@ -19,10 +19,10 @@
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let uiAbilityContext = this.context;
// ...
}
onCreate(want, launchParam) {
let uiAbilityContext = this.context;
// ...
}
}
```
......@@ -34,10 +34,10 @@
```ts
import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
export default class MyService extends ServiceExtensionAbility {
onCreate(want) {
let serviceExtensionContext = this.context;
// ...
}
onCreate(want) {
let serviceExtensionContext = this.context;
// ...
}
}
```
- 获取[AbilityStageContext](../reference/apis/js-apis-inner-application-abilityStageContext.md)。Module级别的Context,和基类Context相比,额外提供HapModuleInfo、Configuration等信息。
......@@ -45,10 +45,10 @@
```ts
import AbilityStage from "@ohos.app.ability.AbilityStage";
export default class MyAbilityStage extends AbilityStage {
onCreate() {
let abilityStageContext = this.context;
// ...
}
onCreate() {
let abilityStageContext = this.context;
// ...
}
}
```
- 获取[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md)。应用级别的Context。ApplicationContext在基类Context的基础上提供了订阅应用内应用组件的生命周期的变化、订阅系统内存变化和订阅应用内系统环境的变化的能力,在UIAbility、ExtensionAbility、AbilityStage中均可以获取。
......@@ -56,10 +56,10 @@
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext();
// ...
}
onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext();
// ...
}
}
```
......@@ -127,16 +127,16 @@
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let cacheDir = this.context.cacheDir;
let tempDir = this.context.tempDir;
let filesDir = this.context.filesDir;
let databaseDir = this.context.databaseDir;
let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir;
// ...
}
onCreate(want, launchParam) {
let cacheDir = this.context.cacheDir;
let tempDir = this.context.tempDir;
let filesDir = this.context.filesDir;
let databaseDir = this.context.databaseDir;
let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir;
// ...
}
}
```
......@@ -146,36 +146,42 @@ export default class EntryAbility extends UIAbility {
### 获取和修改加密分区
上一个场景中,引入了加密等级的概念,通过对[Context的area属性](../reference/apis/js-apis-inner-application-context.md)的读写来实现获取和设置当前加密分区,支持如下两种加密等级:
应用文件加密是一种保护数据安全的方法,可以使得文件在未经授权访问的情况下得到保护。在不同的场景下,应用需要不同程度的文件保护。对于私有文件,如闹铃、壁纸等,应用需要将这些文件放到设备级加密分区(EL1)中,以保证在用户输入密码前就可以被访问;对于更敏感的文件,如个人隐私信息等,应用需要将这些文件放到更高级别的加密分区(EL2)中,以保证更高的安全性。
在实际应用中,开发者需要根据不同场景的需求选择合适的加密分区,从而保护应用数据的安全。通过合理使用EL1和EL2加密分区,可以有效提高应用数据的安全性。
- AreaMode.EL1:设备级加密区,设备开机后可访问的数据区。
> **说明:**
>
> - AreaMode.EL1:设备级加密区,设备开机后可访问的数据区。
>
> - AreaMode.EL2:用户级加密区,设备开机,首次输入密码后才能够访问的数据区。
- AreaMode.EL2:用户级加密区,设备开机,首次输入密码后才能够访问的数据区
要实现获取和设置当前加密分区,可以通过读写[Context的area属性](../reference/apis/js-apis-inner-application-context.md)来实现
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 存储普通信息前,切换到EL1设备机加密
if (this.context.area === 1) { // 获取area
this.context.area = 0; // 修改area
}
// 存储普通信息
// 存储敏感信息前,切换到EL2用户级加密
if (this.context.area === 0) { // 获取area
this.context.area = 1; // 修改area
}
// 存储敏感信息
onCreate(want, launchParam) {
// 存储普通信息前,切换到EL1设备机加密
if (this.context.area === 1) { // 获取area
this.context.area = 0; // 修改area
}
// 存储普通信息
// 存储敏感信息前,切换到EL2用户级加密
if (this.context.area === 0) { // 获取area
this.context.area = 1; // 修改area
}
// 存储敏感信息
}
}
```
### 创建其他应用或其他Module的Context
基类Context提供创建其他应用或其他Module的Context的方法有[createBundleContext(bundleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatebundlecontext)[createModuleContext(moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext)[createModuleContext(bundleName:string, moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext-1)接口,创建其他应用或者其他Module的Context,从而通过该Context获取相应的资源信息(例如获取其他Module的[获取应用开发路径](#获取应用开发路径)信息)。
基类Context提供创建其他应用或其他Module的Context的方法有[createBundleContext(bundleName: string)](../reference/apis/js-apis-inner-application-context.md#contextcreatebundlecontext)[createModuleContext(moduleName: string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext)[createModuleContext(bundleName: string, moduleName: string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext-1)接口,创建其他应用或者其他Module的Context,从而通过该Context获取相应的资源信息(例如获取其他Module的[获取应用开发路径](#获取应用开发路径)信息)。
- 调用createBundleContext(bundleName:string)方法,创建其他应用的Context信息。
> **说明:**
......@@ -191,12 +197,12 @@ export default class EntryAbility extends UIAbility {
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let bundleName2 = "com.example.application";
let context2 = this.context.createBundleContext(bundleName2);
let label2 = context2.applicationInfo.label;
// ...
}
onCreate(want, launchParam) {
let bundleName2 = "com.example.application";
let context2 = this.context.createBundleContext(bundleName2);
let label2 = context2.applicationInfo.label;
// ...
}
}
```
......@@ -212,12 +218,12 @@ export default class EntryAbility extends UIAbility {
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let bundleName2 = "com.example.application";
let moduleName2 = "module1";
let context2 = this.context.createModuleContext(bundleName2, moduleName2);
// ...
}
onCreate(want, launchParam) {
let bundleName2 = "com.example.application";
let moduleName2 = "module1";
let context2 = this.context.createModuleContext(bundleName2, moduleName2);
// ...
}
}
```
......@@ -227,77 +233,90 @@ export default class EntryAbility extends UIAbility {
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let moduleName2 = "module1";
let context2 = this.context.createModuleContext(moduleName2);
// ...
}
onCreate(want, launchParam) {
let moduleName2 = "module1";
let context2 = this.context.createModuleContext(moduleName2);
// ...
}
}
```
### 订阅进程内UIAbility生命周期变化
在应用内的DFX统计场景,如需要统计对应页面停留时间和访问频率等信息,可以使用订阅进程内UIAbility生命周期变化功能。
在应用内的DFX统计场景,如需要统计对应页面停留时间和访问频率等信息,可以使用订阅进程内UIAbility生命周期变化功能。
[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext)提供了订阅进程内UIAbility生命周期变化的能力。在进程内UIAbility生命周期变化时,如创建、可见/不可见、获焦/失焦、销毁等,会触发进入相应的回调,其中返回的此次注册监听生命周期的ID(每次注册该ID会自增+1,当超过监听上限数量2^63-1时,返回-1),以在[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)使用为例进行说明。
通过[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext)提供的能力,可以订阅进程内UIAbility生命周期变化。当进程内的UIAbility生命周期变化时,如创建、可见/不可见、获焦/失焦、销毁等,会触发相应的回调函数。每次注册回调函数时,都会返回一个监听生命周期的ID,此ID会自增+1。当超过监听上限数量2^63-1时,会返回-1。以[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)中的使用为例进行说明。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
const TAG: string = "[Example].[Entry].[EntryAbility]";
const TAG: string = '[Example].[Entry].[EntryAbility]';
export default class EntryAbility extends UIAbility {
lifecycleId: number;
onCreate(want, launchParam) {
let abilityLifecycleCallback = {
onAbilityCreate(uiability) {
console.info(TAG, "onAbilityCreate uiability:" + JSON.stringify(uiability));
},
onWindowStageCreate(uiability, windowStage) {
console.info(TAG, "onWindowStageCreate uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageCreate windowStage:" + JSON.stringify(windowStage));
},
onWindowStageActive(uiability, windowStage) {
console.info(TAG, "onWindowStageActive uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageActive windowStage:" + JSON.stringify(windowStage));
},
onWindowStageInactive(uiability, windowStage) {
console.info(TAG, "onWindowStageInactive uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageInactive windowStage:" + JSON.stringify(windowStage));
},
onWindowStageDestroy(uiability, windowStage) {
console.info(TAG, "onWindowStageDestroy uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageDestroy windowStage:" + JSON.stringify(windowStage));
},
onAbilityDestroy(uiability) {
console.info(TAG, "onAbilityDestroy uiability:" + JSON.stringify(uiability));
},
onAbilityForeground(uiability) {
console.info(TAG, "onAbilityForeground uiability:" + JSON.stringify(uiability));
},
onAbilityBackground(uiability) {
console.info(TAG, "onAbilityBackground uiability:" + JSON.stringify(uiability));
},
onAbilityContinue(uiability) {
console.info(TAG, "onAbilityContinue uiability:" + JSON.stringify(uiability));
}
}
// 1. 通过context属性获取applicationContext
let applicationContext = this.context.getApplicationContext();
// 2. 通过applicationContext注册监听应用内生命周期
this.lifecycleId = applicationContext.on("abilityLifecycle", abilityLifecycleCallback);
console.info(TAG, "register callback number: " + JSON.stringify(this.lifecycleId));
// 定义生命周期ID
lifecycleId: number;
onCreate(want, launchParam) {
// 定义生命周期回调对象
let abilityLifecycleCallback = {
// 当UIAbility创建时被调用
onAbilityCreate(uiAbility) {
console.log(TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当窗口创建时被调用
onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
},
// 当窗口处于活动状态时被调用
onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
},
// 当窗口处于非活动状态时被调用
onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
},
// 当窗口被销毁时被调用
onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
},
// 当UIAbility被销毁时被调用
onAbilityDestroy(uiAbility) {
console.log(TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当UIAbility从后台转到前台时触发回调
onAbilityForeground(uiAbility) {
console.log(TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当UIAbility从前台转到后台时触发回调
onAbilityBackground(uiAbility) {
console.log(TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当UIAbility迁移时被调用
onAbilityContinue(uiAbility) {
console.log(TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}
}
// 获取应用上下文
let applicationContext = this.context.getApplicationContext();
// 注册应用内生命周期回调
this.lifecycleId = applicationContext.on("abilityLifecycle", abilityLifecycleCallback);
console.log(TAG, `register callback number: ${this.lifecycleId}`);
}
onDestroy() {
let applicationContext = this.context.getApplicationContext();
applicationContext.off("abilityLifecycle", this.lifecycleId, (error, data) => {
console.info(TAG, "unregister callback success, err: " + JSON.stringify(error));
});
}
// ...
onDestroy() {
// 获取应用上下文
let applicationContext = this.context.getApplicationContext();
// 取消应用内生命周期回调
applicationContext.off("abilityLifecycle", this.lifecycleId);
}
}
```
......@@ -19,11 +19,10 @@ OpenHarmony通过CES(Common Event Service,公共事件服务)为应用程
- 有序公共事件:CES转发公共事件时,根据订阅者设置的优先级等级,在接收到优先级较高的一个订阅者回复后,再向下一个优先级较低的订阅者转发公共事件。具有相同优先级的订阅者将按随机顺序收到公共事件。
- 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅,同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请`ohos.permission.COMMONEVENT_STICKY`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
- 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅,同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请`ohos.permission.COMMONEVENT_STICKY`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
每个应用都可以按需订阅公共事件,订阅成功,当公共事件发布时,系统会将其发送给对应的应用。这些公共事件可能来自系统、其他应用和应用自身。
**图1** 公共事件示意图
**图1** 公共事件示意图
![common-event](figures/common-event.png)
......@@ -47,60 +47,38 @@
## 开发步骤
1. 在module.json5配置数据同步权限,示例代码如下。
1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)
3. 在配置文件中配置跨端迁移相关标签字段。
配置应用支持迁移
在module.json5中配置continuable标签:true表示支持迁移,false表示不支持,默认为false。配置为false的UIAbility将被系统识别为无法迁移。
```json
{
"module": {
"requestPermissions":[
{
"name" : "ohos.permission.DISTRIBUTED_DATASYNC",
// ...
"abilities": [
{
// ...
"continuable": true,
}
]
}
}
```
2. 在配置文件中配置跨端迁移相关标签字段。
- 配置应用支持迁移
在module.json5中配置continuable标签:true表示支持迁移,false表示不支持,默认为false。配置为false的UIAbility将被系统识别为无法迁移。
```json
{
"module": {
// ...
"abilities": [
{
// ...
"continuable": true,
}
]
}
}
```
- 根据需要配置应用启动模式类型,配置详情请参照[UIAbility组件启动模式](uiability-launch-type.md)
3. 申请数据同步权限,弹框示例代码。
```ts
requestPermission() {
let context = this.context
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC']
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error))
})
}
```
根据需要配置应用启动模式类型,配置详情请参照[UIAbility组件启动模式](uiability-launch-type.md)
4. 在发起端UIAbility中实现[onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)接口。
当应用触发迁移时,[onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)接口在发起端被调用,开发者可以在该接口中保存迁移数据,实现应用兼容性检测,决定是否支持此次迁移。
当应用触发迁移时,[onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)接口在发起端被调用,开发者可以在该接口中保存迁移数据,实现应用兼容性检测,决定是否支持此次迁移。
- 保存迁移数据:开发者可以将要迁移的数据通过键值对的方式保存在wantParam中。
- 应用兼容性检测:开发者可以通过从wantParam中获取目标应用的版本号与本应用版本号做兼容性校验。
- 迁移决策:开发者可以通过onContinue接口的返回值决定是否支持此次迁移,返回值信息见[接口说明](#接口说明)
示例如下:
......
......@@ -47,24 +47,12 @@
### 开发步骤
1. 申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 申请数据同步权限,弹框示例代码。
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)
3. 获取目标设备的设备ID。
```ts
import deviceManager from '@ohos.distributedHardware.deviceManager';
......@@ -94,7 +82,7 @@
```
4. 设置目标组件参数,调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)接口,启动UIAbility或ServiceExtensionAbility。
```ts
let want = {
deviceId: getRemoteDeviceId(),
......@@ -129,24 +117,12 @@
### 开发步骤
1. 申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 申请数据同步权限,弹框示例代码。
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)
3. 在发起端设置目标组件参数,调用startAbilityForResult()接口启动目标端UIAbility,异步回调中的data用于接收目标端UIAbility停止自身后返回给调用方UIAbility的信息。getRemoteDeviceId方法参照[通过跨设备启动uiability和serviceextensionability组件实现多端协同无返回数据](#通过跨设备启动uiability和serviceextensionability组件实现多端协同无返回数据)
```ts
let want = {
deviceId: getRemoteDeviceId(),
......@@ -163,7 +139,7 @@
```
4. 在目标端UIAbility任务完成后,调用terminateSelfWithResult()方法,将数据返回给发起端的UIAbility。
```ts
const RESULT_CODE: number = 1001;
let abilityResult = {
......@@ -181,7 +157,7 @@
```
5. 发起端UIAbility接收到目标端UIAbility返回的信息,对其进行处理。
```ts
const RESULT_CODE: number = 1001;
......@@ -218,21 +194,9 @@
### 开发步骤
1. 申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 申请数据同步权限,弹框示例代码。
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)
3. 如果已有后台服务,请直接进入下一步;如果没有,则[实现一个后台服务](serviceextensionability.md#实现一个后台服务仅对系统应用开放)
......@@ -292,7 +256,7 @@
getRemoteDeviceId方法参照[通过跨设备启动uiability和serviceextensionability组件实现多端协同无返回数据](#通过跨设备启动uiability和serviceextensionability组件实现多端协同无返回数据)。
5. 断开连接。调用disconnectServiceExtensionAbility()断开与后台服务的连接。
```ts
let connectionId = 1 // 在通过connectServiceExtensionAbility绑定服务时返回的Id
this.context.disconnectServiceExtensionAbility(connectionId).then((data) => {
......@@ -327,116 +291,104 @@
### 开发步骤
1. 申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 申请数据同步权限,弹框示例代码。
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)
3. 创建被调用端UIAbility。
被调用端UIAbility需要实现指定方法的数据接收回调函数、数据的序列化及反序列化方法。在需要接收数据期间,通过on接口注册监听,无需接收数据时通过off接口解除监听。
被调用端UIAbility需要实现指定方法的数据接收回调函数、数据的序列化及反序列化方法。在需要接收数据期间,通过on接口注册监听,无需接收数据时通过off接口解除监听。
1. 配置UIAbility的启动模式。
配置module.json5,将CalleeAbility配置为单实例"singleton"。
1. 配置UIAbility的启动模式。
配置module.json5,将CalleeAbility配置为单实例"singleton"。
| Json字段 | 字段说明 |
| -------- | -------- |
| “launchType” | Ability的启动模式,设置为"singleton"类型。 |
| Json字段 | 字段说明 |
| -------- | -------- |
| “launchType” | Ability的启动模式,设置为"singleton"类型。 |
UIAbility配置标签示例如下:
UIAbility配置标签示例如下:
```json
"abilities":[{
"name": ".CalleeAbility",
"srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
"launchType": "singleton",
"description": "$string:CalleeAbility_desc",
"icon": "$media:icon",
"label": "$string:CalleeAbility_label",
"visible": true
}]
```
2. 导入UIAbility模块。
```ts
import Ability from '@ohos.app.ability.UIAbility';
```
3. 定义约定的序列化数据。
调用端及被调用端发送接收的数据格式需协商一致,如下示例约定数据由number和string组成。
```json
"abilities":[{
"name": ".CalleeAbility",
"srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
"launchType": "singleton",
"description": "$string:CalleeAbility_desc",
"icon": "$media:icon",
"label": "$string:CalleeAbility_label",
"visible": true
}]
```
2. 导入UIAbility模块。
```ts
import Ability from '@ohos.app.ability.UIAbility';
```
3. 定义约定的序列化数据。
调用端及被调用端发送接收的数据格式需协商一致,如下示例约定数据由number和string组成。
```ts
export default class MyParcelable {
num: number = 0;
str: string = "";
constructor(num, string) {
this.num = num;
this.str = string;
}
marshalling(messageSequence) {
messageSequence.writeInt(this.num);
messageSequence.writeString(this.str);
return true;
}
unmarshalling(messageSequence) {
this.num = messageSequence.readInt();
this.str = messageSequence.readString();
return true;
}
}
```
4. 实现Callee.on监听及Callee.off解除监听。
如下示例在Ability的onCreate注册MSG_SEND_METHOD监听,在onDestroy取消监听,收到序列化数据后作相应处理并返回。应用开发者根据实际业务需要做相应处理。
```ts
const TAG: string = '[CalleeAbility]';
const MSG_SEND_METHOD: string = 'CallSendMsg';
function sendMsgCallback(data) {
console.info('CalleeSortFunc called');
// 获取Caller发送的序列化数据
let receivedData = new MyParcelable(0, '');
data.readParcelable(receivedData);
console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`);
// 作相应处理
// 返回序列化数据result给Caller
return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`);
}
export default class CalleeAbility extends Ability {
onCreate(want, launchParam) {
try {
this.callee.on(MSG_SEND_METHOD, sendMsgCallback);
} catch (error) {
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`);
}
}
onDestroy() {
try {
this.callee.off(MSG_SEND_METHOD);
} catch (error) {
console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`);
}
}
}
```
```ts
export default class MyParcelable {
num: number = 0;
str: string = "";
constructor(num, string) {
this.num = num;
this.str = string;
}
marshalling(messageSequence) {
messageSequence.writeInt(this.num);
messageSequence.writeString(this.str);
return true;
}
unmarshalling(messageSequence) {
this.num = messageSequence.readInt();
this.str = messageSequence.readString();
return true;
}
}
```
4. 实现Callee.on监听及Callee.off解除监听。
如下示例在Ability的onCreate注册MSG_SEND_METHOD监听,在onDestroy取消监听,收到序列化数据后作相应处理并返回。应用开发者根据实际业务需要做相应处理。
```ts
const TAG: string = '[CalleeAbility]';
const MSG_SEND_METHOD: string = 'CallSendMsg';
function sendMsgCallback(data) {
console.info('CalleeSortFunc called');
// 获取Caller发送的序列化数据
let receivedData = new MyParcelable(0, '');
data.readParcelable(receivedData);
console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`);
// 作相应处理
// 返回序列化数据result给Caller
return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`);
}
export default class CalleeAbility extends Ability {
onCreate(want, launchParam) {
try {
this.callee.on(MSG_SEND_METHOD, sendMsgCallback);
} catch (error) {
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`);
}
}
onDestroy() {
try {
this.callee.off(MSG_SEND_METHOD);
} catch (error) {
console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`);
}
}
}
```
4. 获取Caller接口,访问被调用端UIAbility。
1. 导入UIAbility模块。
......@@ -512,8 +464,8 @@
```
6. 释放Caller通信接口。
Caller不再使用后,应用开发者可以通过release接口释放Caller。
Caller不再使用后,应用开发者可以通过release接口释放Caller。
```ts
releaseCall() {
try {
......
......@@ -30,102 +30,100 @@
一个UIAbility实例对应一个单独的任务,因此应用调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动一个UIAbility时,就是创建了一个任务。
桌面应用调用[missionManager](../reference/apis/js-apis-application-missionManager.md)的接口管理任务,需要申请`ohos.permission.MANAGE_MISSIONS`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
利用missionManager进行任务管理(监听任务变化、获取任务信息、获取任务快照、清理任务、任务加锁/解锁等),示例代码如下:
```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
// 任务创建
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// 任务销毁
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// 任务快照变化
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// 任务被移动到前台
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// 任务图标变化
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// 任务名称变化
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// 任务实例被关闭
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
};
// 1.注册任务变化通知
let listenerId = missionManager.on('mission', listener);
// 2.获取系统最近20个任务
missionManager.getMissionInfos("", 20, (error, missions) => {
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions));
});
// 3.获取单个任务的详细信息()
let missionId = 11; // 11只是示例,实际是从系统中获取的任务id,下面类似
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
});
// 4.获取任务快照
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 5.获取低分辨任务快照
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 6.加锁/解锁任务
missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called ");
});
missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called ");
});
// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called ");
});
// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called ");
});
// 9.删除全部任务
missionManager.clearAllMissions().catch(function (err) {
console.info(err);
});
// 10.解注册任务变化通知
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
})
```
1. 桌面应用调用[missionManager](../reference/apis/js-apis-application-missionManager.md)的接口管理任务,需要申请`ohos.permission.MANAGE_MISSIONS`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 利用missionManager进行任务管理(监听任务变化、获取任务信息、获取任务快照、清理任务、任务加锁/解锁等)。
```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
// 任务创建
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// 任务销毁
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// 任务快照变化
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// 任务被移动到前台
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// 任务图标变化
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// 任务名称变化
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// 任务实例被关闭
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
};
// 1.注册任务变化通知
let listenerId = missionManager.on('mission', listener);
// 2.获取系统最近20个任务
missionManager.getMissionInfos("", 20, (error, missions) => {
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions));
});
// 3.获取单个任务的详细信息()
let missionId = 11; // 11只是示例,实际是从系统中获取的任务id,下面类似
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
});
// 4.获取任务快照
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 5.获取低分辨任务快照
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 6.加锁/解锁任务
missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called ");
});
missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called ");
});
// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called ");
});
// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called ");
});
// 9.删除全部任务
missionManager.clearAllMissions().catch(function (err) {
console.info(err);
});
// 10.解注册任务变化通知
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
})
```
......@@ -9,37 +9,7 @@
在config.json声明需要的权限,在module下添加"reqPermissions",并写入对应权限。
例如申请访问日历权限:
如申请访问日历权限,需要申请`ohos.permission.READ_CALENDAR`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
对应config.json文件的示例代码如下所示:
```json
{
"module": {
// ...
"reqPermissions": [
{
"name": "ohos.permission.READ_CALENDAR"
// ...
}
]
}
}
```
通过动态弹窗向用户申请授权:
```ts
import featureAbility from '@ohos.ability.featureAbility';
let context = featureAbility.getContext();
let permissions: Array<string> = ['ohos.permission.READ_CALENDAR']
context.requestPermissionsFromUser(permissions, 1).then((data) => {
console.info("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)
......@@ -240,10 +240,6 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
struct Index {
onPageShow() {
let ctx = globalThis.context; // 页面中从globalThis中取出context并使用
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
// ...
});
}
// 页面展示
build() {
......@@ -251,7 +247,7 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
}
}
```
3. 在UIAbilityB文件中使用globalThis中存放了[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md),并且命名为相同的名称。
```ts
......@@ -274,10 +270,6 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
struct Index {
onPageShow() {
let ctx = globalThis.context; // Page中从globalThis中取出context并使用
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
}
// 页面展示
build() {
......@@ -285,7 +277,7 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
}
}
```
5. 在UIAbilityB实例切换至后台,将UIAbilityA实例从后台切换回到前台。此时UIAbilityA的onCreate生命周期不会再次进入。
```ts
......@@ -307,10 +299,6 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
struct Index {
onPageShow() {
let ctx = globalThis.context; // 这时候globalThis中的context是UIAbilityB的context
let permissions=['com.example.permission'];
ctx.requestPermissionsFromUser(permissions,(result) => { // 使用这个对象就会导致进程崩溃
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
}
// 页面展示
build() {
......
......@@ -12,9 +12,8 @@
具体接口描述,详见[WantAgent接口文档](../reference/apis/js-apis-app-ability-wantAgent.md)
| | |
| -------- | -------- |
| **接口名** | **描述** |
| -------- | -------- |
| getWantAgent(info:&nbsp;WantAgentInfo,&nbsp;callback:&nbsp;AsyncCallback&lt;WantAgent&gt;):&nbsp;void | 创建WantAgent。 |
| trigger(agent:&nbsp;WantAgent,&nbsp;triggerInfo:&nbsp;TriggerInfo,&nbsp;callback?:&nbsp;Callback&lt;CompleteData&gt;):&nbsp;void | 触发WantAgent意图。 |
| cancel(agent:&nbsp;WantAgent,&nbsp;callback:&nbsp;AsyncCallback&lt;void&gt;):&nbsp;void | 取消WantAgent。 |
......
......@@ -110,7 +110,7 @@
"acls":{
"allowed-acls":[
"ohos.permission.WRITE_AUDIO",
"ohos.permission.CAPTURE_SCREEN"
"ohos.permission.CAPTURE_SCREEN"
]
}
}
......@@ -131,7 +131,7 @@
以允许应用读取日历信息为例进行说明。
1. 申请`ohos.permission.READ_CALENDAR`权限,配置方式请参见[访问控制授权申请](#配置文件权限声明)
1. 申请`ohos.permission.READ_CALENDAR`权限,配置方式请参见[配置文件权限声明](#配置文件权限声明)
2. 校验当前是否已经授权。
......@@ -335,4 +335,4 @@ reqPermissions() {
针对访问控制,有以下相关实例可供参考:
- [AbilityAccessCtrl:访问权限控制(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Security/AbilityAccessCtrl)
- [为应用添加运行时权限(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Ability/AccessPermission)
\ No newline at end of file
- [为应用添加运行时权限(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Ability/AccessPermission)
......@@ -19,7 +19,7 @@
## 开发步骤
1. 申请`ohos.permission.PUBLISH_AGENT_REMINDER`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
1. 需要申请`ohos.permission.PUBLISH_AGENT_REMINDER`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. [使能通知开关](../notification/notification-enable.md),获得用户授权后,才能使用代理提醒功能。
......@@ -180,4 +180,4 @@
基于后台代理提醒的开发,有以下相关实例可供参考:
- [闹钟(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/CommonEventAndNotification/AlarmClock)
\ No newline at end of file
- [闹钟(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/CommonEventAndNotification/AlarmClock)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册