1# Cross-Device Migration (for System Applications Only) 2 3 4## When to Use 5 6The main task of cross-device migration is to migrate the current task (including the page control status) of an application to the target device so that the task can continue on it. Cross-device migration supports the following functionalities: 7 8- Storage and restoration of custom data 9 10- Storage and restoration of page routing information and page control status data 11 12- Application compatibility detection 13 14 15## Cross-Device Migration Process 16 17The following figure shows the cross-device migration process. 18 19**Figure 1** Cross-device migration process 20![hop-cross-device-migration](figures/hop-cross-device-migration.png) 21 22 23## Constraints 24 25- Since cross-device migration task management is not available, you can only develop applications that support cross-device migration. Your application cannot initiate migration. 26 27- Cross-device migration can be performed between the same UIAbility component. In other words, the components must have the same **bundleName**, **abilityName**, and **signature**. 28 29 30## Best Practices 31 32For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB. 33 34 35## Available APIs 36 37The table below describes the main APIs used for cross-device migration. For details, see [API Reference](../reference/apis/js-apis-app-ability-uiAbility.md). 38 39**Table 1** Cross-device migration APIs 40 41| **API**| Description| 42| -------- | -------- | 43| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for migration and indicate whether the migration is accepted.<br>- **AGREE**: The migration is accepted.<br>- **REJECT**: The migration is rejected.<br>- **MISMATCH**: The version does not match.| 44| onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the multi-instance migration scenario.| 45| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the singleton migration scenario.| 46 47 48## How to Develop 49 501. Configure the data synchronization permission in the **module.json5** file. The sample code is as follows: 51 52 ```json 53 { 54 "module": { 55 "requestPermissions":[ 56 { 57 "name" : "ohos.permission.DISTRIBUTED_DATASYNC", 58 } 59 ] 60 } 61 } 62 ``` 63 642. Configure the fields related to cross-device migration in the configuration file. 65 - Configure the application to support migration. 66 67 68 Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device. 69 ```json 70 { 71 "module": { 72 // ... 73 "abilities": [ 74 { 75 // ... 76 "continuable": true, 77 } 78 ] 79 } 80 } 81 ``` 82 83 - Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md). 84 853. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: 86 87 ```ts 88 requestPermission() { 89 let context = this.context 90 let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'] 91 context.requestPermissionsFromUser(permissions).then((data) => { 92 console.info("Succeed to request permission from user with data: "+ JSON.stringify(data)) 93 }).catch((error) => { 94 console.info("Failed to request permission from user with error: "+ JSON.stringify(error)) 95 }) 96 } 97 ``` 98 994. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator. 100 101 [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision. 102 103 - Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**. 104 105 - Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application. 106 107 - Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis). 108 109 The sample code is as follows: 110 111 ```ts 112 import UIAbility from '@ohos.app.ability.UIAbility'; 113 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 114 115 onContinue(wantParam : {[key: string]: any}) { 116 console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) 117 let workInput = AppStorage.Get<string>('ContinueWork'); 118 // Set the user input data into wantParam. 119 wantParam["work"] = workInput // set user input data into want params 120 console.info(`onContinue input = ${wantParam["input"]}`); 121 return AbilityConstant.OnContinueResult.AGREE 122 } 123 ``` 124 1255. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration. 126 - Implementation example of **onCreate** in the multi-instance scenario 127 - The target device determines whether the startup is **LaunchReason.CONTINUATION** based on **launchReason** in **onCreate()**. 128 - You can obtain the saved migration data from the **want** parameter. 129 - After data restoration is complete, call **restoreWindowStage()** to trigger page restoration. 130 131 ```ts 132 import UIAbility from '@ohos.app.ability.UIAbility'; 133 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 134 import distributedObject from '@ohos.data.distributedDataObject'; 135 136 export default class EntryAbility extends UIAbility { 137 storage : LocalStorage; 138 onCreate(want, launchParam) { 139 console.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) 140 if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { 141 // Obtain the user data from the want parameter. 142 let workInput = want.parameters.work 143 console.info(`work input ${workInput}`) 144 AppStorage.SetOrCreate<string>('ContinueWork', workInput) 145 this.storage = new LocalStorage(); 146 this.context.restoreWindowStage(this.storage); 147 } 148 } 149 } 150 ``` 151 - For a singleton ability, use **onNewWant()** to achieve the same implementation. 152