多端协同流程
多端协同流程如下图所示。
图1 多端协同流程图
约束限制
-
由于“多端协同任务管理”能力尚未具备,开发者当前只能通过开发系统应用获取设备列表,不支持三方应用接入。
-
多端协同需遵循 分布式跨设备组件启动规则。
-
为了获得最佳体验,使用want传输的数据建议在100KB以下。
通过跨设备启动UIAbility和ServiceExtensionAbility组件实现多端协同(无返回数据)
在设备A上通过发起端应用提供的启动按钮,启动设备B上指定的UIAbility与ServiceExtensionAbility。
接口说明
表1 跨设备启动API接口功能介绍
接口名 | 描述 |
---|---|
startAbility(want: Want, callback: AsyncCallback): void; | 启动UIAbility和ServiceExtensionAbility(callback形式)。 |
stopServiceExtensionAbility(want: Want, callback: AsyncCallback): void; | 退出启动的ServiceExtensionAbility(callback形式)。 |
stopServiceExtensionAbility(want: Want): Promise; | 退出启动的ServiceExtensionAbility(Promise形式)。 |
开发步骤
-
需要申请
ohos.permission.DISTRIBUTED_DATASYNC
权限,配置方式请参见 声明权限 。 -
同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见 向用户申请授权 。
-
获取目标设备的设备ID。
import deviceManager from '@ohos.distributedDeviceManager';
import hilog from '@ohos.hilog';
const TAG: string = '[Page_CollaborateAbility]';
const DOMAIN_NUMBER: number = 0xFF00;
let dmClass: deviceManager.DeviceManager;
function initDmClass(): void {
// 其中createDeviceManager接口为系统API
try {
dmClass = deviceManager.createDeviceManager('com.samples.stagemodelabilitydevelop');
hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(dmClass) ?? '');
} catch (err) {
hilog.error(DOMAIN_NUMBER, TAG, 'createDeviceManager err: ' + JSON.stringify(err));
};
}
function getRemoteDeviceId(): string | undefined {
if (typeof dmClass === 'object' && dmClass !== null) {
let list = dmClass.getAvailableDeviceListSync();
hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(dmClass), JSON.stringify(list));
if (typeof (list) === 'undefined' || typeof (list.length) === 'undefined') {
hilog.info(DOMAIN_NUMBER, TAG, 'getRemoteDeviceId err: list is null');
return;
}
if (list.length === 0) {
hilog.info(DOMAIN_NUMBER, TAG, `getRemoteDeviceId err: list is empty`);
return;
}
return list[0].networkId;
} else {
hilog.info(DOMAIN_NUMBER, TAG, 'getRemoteDeviceId err: dmClass is null');
return;
}
}
- 设置目标组件参数,调用
startAbility()
接口,启动UIAbility或ServiceExtensionAbility。
import { BusinessError } from '@ohos.base';
import hilog from '@ohos.hilog';
import Want from '@ohos.app.ability.Want';
import deviceManager from '@ohos.distributedDeviceManager';
import common from '@ohos.app.ability.common';
const TAG: string = '[Page_CollaborateAbility]';
const DOMAIN_NUMBER: number = 0xFF00;
let dmClass: deviceManager.DeviceManager;
function getRemoteDeviceId(): string | undefined {
if (typeof dmClass === 'object' && dmClass !== null) {
let list = dmClass.getAvailableDeviceListSync();
hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(dmClass), JSON.stringify(list));
if (typeof (list) === 'undefined' || typeof (list.length) === 'undefined') {
hilog.info(DOMAIN_NUMBER, TAG, 'getRemoteDeviceId err: list is null');
return;
}
if (list.length === 0) {
hilog.info(DOMAIN_NUMBER, TAG, `getRemoteDeviceId err: list is empty`);
return;
}
return list[0].networkId;
} else {
hilog.info(DOMAIN_NUMBER, TAG, 'getRemoteDeviceId err: dmClass is null');
return;
}
};
@Entry
@Component
struct Page_CollaborateAbility {
private context = getContext(this) as common.UIAbilityContext;
build() {
// ...
Button('startAbility')
.onClick(() => {
let want: Want = {
deviceId: getRemoteDeviceId(),
bundleName: 'com.samples.stagemodelabilityinteraction',
abilityName: 'CollaborateAbility',
moduleName: 'entry' // moduleName非必选
}
// context为发起端UIAbility的AbilityContext
this.context.startAbility(want).then(() => {
// ...
}).catch((err: BusinessError) => {
// ...
hilog.error(DOMAIN_NUMBER, TAG, `startAbility err: ` + JSON.stringify(err));
});
}
)
}
}
- 当设备A发起端应用不需要设备B上的ServiceExtensionAbility时,可调用 stopServiceExtensionAbility 接口退出。(该接口不支持UIAbility的退出,UIAbility由用户手动通过任务管理退出)
import Want from '@ohos.app.ability.Want';
import hilog from '@ohos.hilog';
import { BusinessError } from '@ohos.base';
import deviceManager from '@ohos.distributedDeviceManager';
import common from '@ohos.app.ability.common';
const TAG: string = '[Page_CollaborateAbility]';
const DOMAIN_NUMBER: number = 0xFF00;
let dmClass: deviceManager.DeviceManager;
function getRemoteDeviceId(): string | undefined {
if (typeof dmClass === 'object' && dmClass !== null) {
let list = dmClass.getAvailableDeviceListSync();
hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(dmClass), JSON.stringify(list));
if (typeof (list) === 'undefined' || typeof (list.length) === 'undefined') {
hilog.info(DOMAIN_NUMBER, TAG, 'getRemoteDeviceId err: list is null');
return;
}
if (list.length === 0) {
hilog.info(DOMAIN_NUMBER, TAG, `getRemoteDeviceId err: list is empty`);
return;
}
return list[0].networkId;
} else {
hilog.info(DOMAIN_NUMBER, TAG, 'getRemoteDeviceId err: dmClass is null');
return;
}
};
@Entry
@Component
struct Page_CollaborateAbility {
private context = getContext(this) as common.UIAbilityContext;
build() {
// ...
Button('stopServiceExtensionAbility')
.onClick(() => {
let want: Want = {
deviceId: getRemoteDeviceId(),
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName非必选
}
// 退出由startAbility接口启动的ServiceExtensionAbility
this.context.stopServiceExtensionAbility(want).then(() => {
console.info("stop service extension ability success")
}).catch((err: BusinessError) => {
console.info("stop service extension ability err is " + JSON.stringify(err))
})
})
}
}