Intermediate: Integration of Hop Feature in Harmony OS App

  • Migrate a video call from the phone to the smart TV for better experience. When the migration is complete, the video app exits on the phone.
  • Migrate the content being read from the phone to the tablet for better experience. When the migration is complete, the reading app exits on the phone.
  • Use an app on the phone as the game controller, and display the game UI on an app on the smart TV for better experience.
  • Use an app on the tablet to answer questions, and take an online class through an app on the smart TV.
{"filter":{"commonFilter": {"system":{"harmonyVersion":"2.0.0"},"groupType": "1","curComType": 0x00000004, "faFilter":"{\"targetBundleName\":\"com.xxx.yyy\"}"}},"transferScene":1,"isTurnOffRecommend":false,"remoteAuthenticationDescription": "Description in the dialog box for HiVision scanning","remoteAuthenticationPicture":""}
  1. Harmony OS phone.
  2. Java JDK.
  3. DevEco Studio.
  1. Create a New Harmony OS Project.
{
"module": {
"reqPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
}
],
...
}
...
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply plugin: 'com.huawei.ohos.app'
//For instructions on signature configuration, see https://developer.harmonyos.com/en/docs/documentation/doc-guides/ide_debug_device-0000001053822404#EN-US_TOPIC_0000001154985555__section1112183053510
ohos {
compileSdkVersion 5
defaultConfig {
compatibleSdkVersion 4
}
}

buildscript {
repositories {
maven {
url 'https://repo.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
jcenter()
}
dependencies {
classpath 'com.huawei.ohos:hap:2.4.4.2'
classpath 'com.huawei.ohos:decctest:1.2.4.0'
}
}
allprojects {
repositories {
maven {
url 'https://repo.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
jcenter()
}
}
apply plugin: 'com.huawei.ohos.hap'
apply plugin: 'com.huawei.ohos.decctest'
//For instructions on signature configuration, see https://developer.harmonyos.com/en/docs/documentation/doc-guides/ide_debug_device-0000001053822404#EN-US_TOPIC_0000001154985555__section1112183053510
ohos {
compileSdkVersion 5
defaultConfig {
compatibleSdkVersion 4
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}

}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
testImplementation 'junit:junit:4.13'
ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100'
}
decc {
supportType = ['html','xml']
}
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// You can design the GUI
// and set a unified background color for buttons as you like.
// For example, you can use PositionLayout to create a simple page.
PositionLayout layout = new PositionLayout(this);
LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);
layout.setLayoutConfig(config);
ShapeElement buttonBg = new ShapeElement();
buttonBg.setRgbColor(new RgbColor(0, 125, 255));
super.setUIContent(layout);
}
@Override
public void onInactive() {
super.onInactive();
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onBackground() {
super.onBackground();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
public void onStop() {
super.onStop();
}
}
public class MainAbilitySlice extends AbilitySlice implements IAbilityContinuation {
private void showMessage(String msg) {
ToastDialog toastDialog = new ToastDialog(this);
toastDialog.setText(msg);
toastDialog.show();
}
@Override
public boolean onStartContinuation() {
showMessage("ContinueAbility Start");
return true;
}
@Override
public boolean onSaveData(IntentParams saveData) {
String exampleData = String.valueOf(System.currentTimeMillis());
saveData.setParam("continueParam", exampleData);
return true;
}
@Override
public boolean onRestoreData(IntentParams restoreData) {
// Restore the FA state data transferred from the target device as required.
Object data = restoreData.getParam("continueParam");
return true;
}
@Override
public void onCompleteContinuation(int result) {
// Show a message to notify the user that the migration is complete and remind the user of stopping the FA on the source device.
showMessage("ContinueAbility Done");
if (!isReversibly) {
terminateAbility();
}
}
@Override
public void onFailedContinuation(int errorCode) {
// Notify the user of the migration failure if required.
showMessage("ContinueAbility failed");
if (!isReversibly) {
terminateAbility();
}
}
}
// You are advised to design buttons in your own style. The following sample code is for reference only:
private static final int OFFSET_X = 100;
private static final int OFFSET_Y = 100;
private static final int ADD_OFFSET_Y = 150;
private static final int BUTTON_WIDTH = 800;
private static final int BUTTON_HEIGHT = 100;
private static final int TEXT_SIZE = 50;
private int offsetY = 0;
private Button createButton(String text, ShapeElement buttonBg) {
Button button = new Button(this);
button.setContentPosition(OFFSET_X, OFFSET_Y + offsetY);
offsetY += ADD_OFFSET_Y;
button.setWidth(BUTTON_WIDTH);
button.setHeight(BUTTON_HEIGHT);
button.setTextSize(TEXT_SIZE);
button.setTextColor(Color.YELLOW);
button.setText(text);
button.setBackground(buttonBg);
return button;
}
// Example of adding buttons to PositionLayout in sequence:
private void addComponents(PositionLayout linear, ShapeElement buttonBg) {
// Create a button for displaying the registration of an FA with the hop task management service.
Button btnRegister = createButton("register", buttonBg);
btnRegister.setClickedListener(mRegisterListener);
linear.addComponent(btnRegister);
// Create a button for displaying the device list.
Button btnShowDeviceList = createButton("ShowDeviceList", buttonBg);
btnShowDeviceList.setClickedListener(mShowDeviceListListener);
linear.addComponent(btnShowDeviceList);
// Create a button for migrating an FA.
Button btnContinueRemoteFA = createButton("ContinueRemoteFA", buttonBg);
btnContinueRemoteFA.setClickedListener(mContinueAbilityListener);
linear.addComponent(btnContinueRemoteFA);
// Create a button for migrating an FA that is reversible.
Button btnContinueReversibly = createButton("ContinueReversibly", buttonBg);
btnContinueReversibly.setClickedListener(mContinueReversiblyListener);
linear.addComponent(btnContinueReversibly);
// Create a button for reversing an FA.
Button btnReverseContinue = createButton("ReverseContinuation", buttonBg);
btnReverseContinue.setClickedListener(mReverseContinueListener);
linear.addComponent(btnReverseContinue);
}
@Override
public void onStart(Intent intent) {
...
// Add the layout of function buttons.
addComponents(layout, buttonBg);
super.setUIContent(layout);
}
public class MainAbility extends Ability implements IAbilityContinuation {
private static final int DOMAIN_ID = 0xD001100;
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, DOMAIN_ID, "MainAbility");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
// For your convenience, the hop logic is implemented in AbilitySlice rather than Ability.
@Override
public boolean onStartContinuation() {
HiLog.info(LABEL_LOG, "onStartContinuation called");
return true;
}
@Override
public boolean onSaveData(IntentParams saveData) {
HiLog.info(LABEL_LOG, "onSaveData called");
return true;
}
@Override
public boolean onRestoreData(IntentParams restoreData) {
HiLog.info(LABEL_LOG, "onRestoreData called");
return true;
}
@Override
public void onCompleteContinuation(int result) {
HiLog.info(LABEL_LOG, "onCompleteContinuation called");
}
@Override
public void onFailedContinuation(int errorCode) {
HiLog.info(LABEL_LOG, "onFailedContinuation called");
}
}
  1. After an FA is registered with the hop task management service, no devices are recommended. When the showDeviceList() method is called, no devices are returned.
  2. User need to specify the deviceId of the peer device. User can call the getDeviceList method in the ohos.distributedschedule.interwork.DeviceManager class to obtain the list of anonymized devices, and then select a target device from the list.
  3. Call the getDeviceList method to obtain the device list, from which you can select the target device.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store