1e41f4b71Sopenharmony_ci# Starting a Remote PageAbility (for System Applications Only)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciThe **startAbility()** method in the **featureAbility** class is used to start a remote PageAbility.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciIn addition to '\@ohos.ability.featureAbility', you must import '\@ohos.distributedHardware.deviceManager', which provides account-independent distributed device networking capabilities. Then you can use [getTrustedDeviceListSync](../reference/apis-distributedservice-kit/js-apis-device-manager-sys.md#gettrusteddevicelistsync) of the DeviceManager module to obtain the remote device ID and pass the remote device ID in the **want** parameter for starting the remote PageAbility.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ciThe [getTrustedDeviceListSync](../reference/apis-distributedservice-kit/js-apis-device-manager-sys.md#gettrusteddevicelistsync) method is available only for system applications. Therefore, non-system applications cannot obtain remote device information or start a remote ability.
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci**Table 1** featureAbility APIs
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci| API| Description|
16e41f4b71Sopenharmony_ci| -------- | -------- |
17e41f4b71Sopenharmony_ci| startAbility(parameter: StartAbilityParameter)| Starts an ability.|
18e41f4b71Sopenharmony_ci| startAbilityForResult(parameter: StartAbilityParameter)| Starts an ability and returns the execution result when the ability is terminated.|
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci**Table 2** deviceManager APIs
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci| API| Description|
24e41f4b71Sopenharmony_ci| -------- | -------- |
25e41f4b71Sopenharmony_ci| getTrustedDeviceListSync(): Array<DeviceInfo> | Obtains all trusted devices synchronously.|
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ciIn the cross-device scenario, before starting a remote PageAbility, you must request the data synchronization permission. The related APIs are described in the table below.
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci**Table 3** AtManager APIs
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci| API| Description|
34e41f4b71Sopenharmony_ci| -------- | -------- |
35e41f4b71Sopenharmony_ci| checkAccessToken(tokenID: number, permissionName: string): Promise<GrantStatus> | Verifies whether a permission is granted to an application. This API uses a promise to return the result **GrantStatus**. You are advised to use **checkAccessToken** instead of **verifyAccessToken**, which is deprecated since API version 9.|
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci**Table 4** context APIs
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci| API| Description|
41e41f4b71Sopenharmony_ci| -------- | -------- |
42e41f4b71Sopenharmony_ci| requestPermissionsFromUser(permissions: Array<string>, requestCode: number, resultCallback: AsyncCallback< PermissionRequestResult>): void | Requests permissions from the system. This API uses an asynchronous callback to return the result. For details, see [API Reference](../reference/apis-ability-kit/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7-1).|
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ciThe following sample code shows how to request the data synchronization permission from users:
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci```ts
48e41f4b71Sopenharmony_ciimport abilityAccessCtrl from "@ohos.abilityAccessCtrl";
49e41f4b71Sopenharmony_ciimport featureAbility from '@ohos.ability.featureAbility';
50e41f4b71Sopenharmony_ciimport bundle from '@ohos.bundle.bundleManager';
51e41f4b71Sopenharmony_ciimport hilog from '@ohos.hilog';
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ciconst TAG: string = 'PagePageAbilitySecond'
54e41f4b71Sopenharmony_ciconst domain: number = 0xFF00;
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci@Entry
57e41f4b71Sopenharmony_ci@Component
58e41f4b71Sopenharmony_cistruct PagePageAbilitySecond {
59e41f4b71Sopenharmony_ci  async requestPermission(): Promise<void> {
60e41f4b71Sopenharmony_ci    hilog.info(domain, TAG, 'RequestPermission begin');
61e41f4b71Sopenharmony_ci    let array: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
62e41f4b71Sopenharmony_ci    let bundleFlag = 0;
63e41f4b71Sopenharmony_ci    let tokenID: number | undefined = undefined;
64e41f4b71Sopenharmony_ci    let userID = 100;
65e41f4b71Sopenharmony_ci    let appInfo = await bundle.getApplicationInfo('com.samples.famodelabilitydevelop', bundleFlag, userID);
66e41f4b71Sopenharmony_ci    tokenID = appInfo.accessTokenId;
67e41f4b71Sopenharmony_ci    let atManager = abilityAccessCtrl.createAtManager();
68e41f4b71Sopenharmony_ci    let requestPermissions: Array<string> = [];
69e41f4b71Sopenharmony_ci    for (let i = 0;i < array.length; i++) {
70e41f4b71Sopenharmony_ci      let result = await atManager.verifyAccessToken(tokenID, array[i]);
71e41f4b71Sopenharmony_ci      hilog.info(domain, TAG, 'checkAccessToken result:' + JSON.stringify(result));
72e41f4b71Sopenharmony_ci      if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
73e41f4b71Sopenharmony_ci        requestPermissions.push(array[i]);
74e41f4b71Sopenharmony_ci      }
75e41f4b71Sopenharmony_ci    }
76e41f4b71Sopenharmony_ci    hilog.info(domain, TAG, 'requestPermissions:' + JSON.stringify(requestPermissions));
77e41f4b71Sopenharmony_ci    if (requestPermissions.length == 0) {
78e41f4b71Sopenharmony_ci      return;
79e41f4b71Sopenharmony_ci    }
80e41f4b71Sopenharmony_ci    let context = featureAbility.getContext();
81e41f4b71Sopenharmony_ci    context.requestPermissionsFromUser(requestPermissions, 1, (error, data) => {
82e41f4b71Sopenharmony_ci      hilog.info(domain, TAG, 'error:' + error.message + ',data:' + JSON.stringify(data));
83e41f4b71Sopenharmony_ci      hilog.info(domain, TAG, 'data requestCode:' + data.requestCode);
84e41f4b71Sopenharmony_ci      hilog.info(domain, TAG, 'data permissions:' + data.permissions);
85e41f4b71Sopenharmony_ci      hilog.info(domain, TAG, 'data authResults:' + data.authResults);
86e41f4b71Sopenharmony_ci    });
87e41f4b71Sopenharmony_ci    hilog.info(domain, TAG, 'RequestPermission end');
88e41f4b71Sopenharmony_ci  }
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci  build() {
91e41f4b71Sopenharmony_ci    //...
92e41f4b71Sopenharmony_ci  }
93e41f4b71Sopenharmony_ci}
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci```
96e41f4b71Sopenharmony_ci
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ciAfter obtaining the data synchronization permission, obtain the trusted device list for device selection.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ciThe following sample code shows how to use **getAvailableDeviceListSync()** to obtain the trusted device list.
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci```ts
104e41f4b71Sopenharmony_ciimport deviceManager from '@ohos.distributedDeviceManager';
105e41f4b71Sopenharmony_ciimport promptAction from '@ohos.promptAction';
106e41f4b71Sopenharmony_ciimport hilog from '@ohos.hilog';
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ciconst TAG: string = 'PagePageAbilitySecond'
109e41f4b71Sopenharmony_ciconst domain: number = 0xFF00;
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci@Entry
112e41f4b71Sopenharmony_ci@Component
113e41f4b71Sopenharmony_cistruct PagePageAbilitySecond {
114e41f4b71Sopenharmony_ci  @State deviceID: string = '';
115e41f4b71Sopenharmony_ci  
116e41f4b71Sopenharmony_ci  getRemoteDeviceId(): void {
117e41f4b71Sopenharmony_ci    let dmClass: deviceManager.DeviceManager;
118e41f4b71Sopenharmony_ci    dmClass = deviceManager.createDeviceManager('com.samples.famodelabilitydevelop');
119e41f4b71Sopenharmony_ci    try {
120e41f4b71Sopenharmony_ci      if (typeof dmClass === 'object' && dmClass !== null) {
121e41f4b71Sopenharmony_ci        let list = dmClass.getAvailableDeviceListSync();
122e41f4b71Sopenharmony_ci        if (typeof (list) == undefined || list.length == 0) {
123e41f4b71Sopenharmony_ci          hilog.info(domain, TAG, 'EntryAbility onButtonClick getRemoteDeviceId err: list is null');
124e41f4b71Sopenharmony_ci          return;
125e41f4b71Sopenharmony_ci        }
126e41f4b71Sopenharmony_ci        hilog.info(domain, TAG, `EntryAbility onButtonClick getRemoteDeviceId success[${list.length}]:` + JSON.stringify(list[0]));
127e41f4b71Sopenharmony_ci        if (list[0].networkId != undefined) {
128e41f4b71Sopenharmony_ci          this.deviceID = list[0].networkId;
129e41f4b71Sopenharmony_ci        }
130e41f4b71Sopenharmony_ci        promptAction.showToast({
131e41f4b71Sopenharmony_ci          message: this.deviceID
132e41f4b71Sopenharmony_ci        });
133e41f4b71Sopenharmony_ci      } else {
134e41f4b71Sopenharmony_ci        hilog.info(domain, TAG, 'EntryAbility onButtonClick getRemoteDeviceId err: dmClass is null');
135e41f4b71Sopenharmony_ci      }
136e41f4b71Sopenharmony_ci    } catch (error) {
137e41f4b71Sopenharmony_ci      hilog.info(domain, TAG, `getRemoteDeviceId error, error=${error}, message=${error.message}`);
138e41f4b71Sopenharmony_ci    }
139e41f4b71Sopenharmony_ci  }
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci  build() {
142e41f4b71Sopenharmony_ci    //...
143e41f4b71Sopenharmony_ci  }
144e41f4b71Sopenharmony_ci}
145e41f4b71Sopenharmony_ci```
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci
148e41f4b71Sopenharmony_ciAfter a device is selected, call **startAbility()** to explicitly start the remote PageAbility.
149e41f4b71Sopenharmony_ci
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ciThe following sample code shows how to explicitly start a remote PageAbility through **startAbility()**.
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci```ts
154e41f4b71Sopenharmony_ciimport featureAbility from '@ohos.ability.featureAbility';
155e41f4b71Sopenharmony_ciimport Want from '@ohos.app.ability.Want';
156e41f4b71Sopenharmony_ciimport promptAction from '@ohos.promptAction';
157e41f4b71Sopenharmony_ciimport { BusinessError } from '@ohos.base';
158e41f4b71Sopenharmony_ciimport hilog from '@ohos.hilog';
159e41f4b71Sopenharmony_ci
160e41f4b71Sopenharmony_ciconst TAG: string = 'PagePageAbilitySecond'
161e41f4b71Sopenharmony_ciconst domain: number = 0xFF00;
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ci@Entry
164e41f4b71Sopenharmony_ci@Component
165e41f4b71Sopenharmony_cistruct PagePageAbilitySecond {
166e41f4b71Sopenharmony_ci  @State deviceID: string = '';
167e41f4b71Sopenharmony_ci  
168e41f4b71Sopenharmony_ci  onStartRemoteAbility(): void {
169e41f4b71Sopenharmony_ci    hilog.info(domain, TAG, 'onStartRemoteAbility begin');
170e41f4b71Sopenharmony_ci    let wantValue: Want = {
171e41f4b71Sopenharmony_ci      bundleName: 'ohos.samples.distributedmusicplayer',
172e41f4b71Sopenharmony_ci      abilityName: 'ohos.samples.distributedmusicplayer.MainAbility',
173e41f4b71Sopenharmony_ci      deviceId: this.deviceID, // The method of obtaining this.deviceID is described in the preceding sample code.
174e41f4b71Sopenharmony_ci    };
175e41f4b71Sopenharmony_ci    hilog.info(domain, TAG, 'onStartRemoteAbility want=' + JSON.stringify(wantValue));
176e41f4b71Sopenharmony_ci    featureAbility.startAbility({
177e41f4b71Sopenharmony_ci      want: wantValue
178e41f4b71Sopenharmony_ci    }).then((data) => {
179e41f4b71Sopenharmony_ci      promptAction.showToast({
180e41f4b71Sopenharmony_ci        message: 'start_remote_success_toast'
181e41f4b71Sopenharmony_ci      });
182e41f4b71Sopenharmony_ci      hilog.info(domain, TAG, 'onStartRemoteAbility finished, ' + JSON.stringify(data));
183e41f4b71Sopenharmony_ci    }).catch((error: BusinessError) => {
184e41f4b71Sopenharmony_ci      promptAction.showToast({
185e41f4b71Sopenharmony_ci        message: JSON.stringify(error)
186e41f4b71Sopenharmony_ci      });
187e41f4b71Sopenharmony_ci      hilog.error(domain, TAG, 'onStartRemoteAbility failed: ' + JSON.stringify(error));
188e41f4b71Sopenharmony_ci    });
189e41f4b71Sopenharmony_ci    hilog.info(domain, TAG, 'onStartRemoteAbility end');
190e41f4b71Sopenharmony_ci  }
191e41f4b71Sopenharmony_ci  build() {
192e41f4b71Sopenharmony_ci    //...
193e41f4b71Sopenharmony_ci  }
194e41f4b71Sopenharmony_ci}
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci```
197