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