目录

All-Scenario Collaboration for Social Communication

Overview

In apps such as office, creation, and social networking, content publishing, browsing, and sharing are the core of user interaction and communication. It allows users to create and share multimedia information, including images, videos, and text, to enhance the connection and interaction between users. As electronic devices such as mobile phones, tablets, and computers become more popular, users have increasing demands for processing images, videos, and text across devices, editing content on different devices, seamlessly switching between devices and quickly and conveniently sharing content. This topic describes how to use the cross-device migration and multi-device collaboration functions to implement quick and seamless switching between different devices, improving the convenience of content publishing, browsing, and sharing.

This topic covers the following contents:

User Experience

[h2]Experience

Feature

Experience Video

Device interconnectivity

Cross-device drag-and-drop

Cross-device clipping

Cross-device app continuation

Inserting images through Tap to Transfer

Sharing pages through Tap to Transfer

Sharing pages through Grab & drop

[h2]Restrictions

Restriction/Scenario

Device Interconnectivity

Cross-Device Drag and Drop

Cross-Device Clipping

Cross-Device App Continuation

Sharing Through Tap to Transfer

Sharing Through Grab & Drop

Devices running HarmonyOS NEXT or later

√

√

√

√

√

√

Log in to the same HUAWEI ID

√

√

√

√

  • Not required for Tap to Transfer between phones.
  • Required for Tap to Transfer between phone and PC.

NA

Wi-Fi and Bluetooth are enabled

√

√

√

√

NA

NA

The device needs to be unlocked and the screen needs to be turned on.

NA

NA

√

NA

√

√

Device type (common devices in the vertical domain: phone, tablet, and PC)

  • Local device: tablet or PC
  • Remote device: phone or tablet with the camera capability

A PC must be connected, or a tablet that supports PC mode must be connected.

Phone, tablet, and PC

Phone, tablet, and PC

  • Local device: phone.
  • Target device: phone, tablet (6.1.0 (23) and later versions), or PC. Only bar-type phones or foldable phones in bar mode can share content with PCs using Tap to Transfer.

Phone, tablet, and PC

Enable the corresponding function in Settings > More connectivity options.

√

Enable keyboard & mouse sharing.

Enable cross-device clipboard.

Enable continuation.

NA

NA

Others

Devices can be invoked based on specific invoking policies. For details, see Constraints > Restrictions on usage > Invoking policy.

The devices must be connected to the same LAN. Resource files preset in the app (that is, resource files that already exist in the HAP before the app is installed) do not support cross-device drag-and-drop.

NA

The app must be installed on both devices.

Huawei Share Kit has been enabled (enabled by default). For details about the constraints on the Tap to Transfer between a phone and a PC, see "Constraints on screen touch interaction" in Constraints.

Grab & Drop should be enabled on the device

Device Interconnectivity

[h2]When to Use

When a user is using a text editing app (such as Notepad, Email, or Notes) on a tablet or PC, if the current device is inconvenient for shooting, the user can use the device interconnectivity feature to directly invoke the camera of the phone or tablet to take photos or videos, or select images or videos from the gallery. Phones and tablets have advantages in shooting flexibility, framing convenience, and camera performance. The selected materials will be quickly transferred to the app on the original device, helping the user efficiently complete the image and text editing task.

To use this feature, the device restrictions and usage restrictions must be met. For details, see Constraints in "Device Interconnectivity Development Guide".

[h2]How to Implement

Scenario Analysis

  1. A user operates in the app on the local device (tablet or PC), selects the remote device's camera, scanning, or gallery feature, and sends a request to the remote device.
  2. The system automatically wakes up the camera, gallery, or scanning feature on the remote device and enters the corresponding screen.
  3. The user uses the remote device to take photos or select photos/videos and confirm them, which are then sent back to the local device and inserted into the app on the local device.

Key Technologies

The core of device interconnectivity is to use the distributed collaboration framework of HarmonyOS.

  1. Device discovery: Use the createCollaborationServiceMenuItems component to obtain the list of devices with the corresponding capabilities on the network.
  2. Remote wakeup: The system automatically wakes up the camera, gallery, or scanning feature on the remote device.
  3. Status backhaul: Use the CollaborationServiceStateDialog component to send back the remote shooting status in real time.
  4. Data receiving: Process the received data in the onState() callback.

In the distributed collaboration framework, an app only needs to call the createCollaborationServiceMenuItems (camera device list component) and CollaborationServiceStateDialog (dialog box component showing remote camera status) components to complete cross-device photo shooting, scanning, and gallery access capabilities for the service scenario of cross-device image/video information interconnection. You do not need to pay attention to details such as data transmission and instruction control in distributed scenarios. For details, see Working Principles.

[h2]How to Implement

Cross-Device Image and Text Dragging

[h2]When to Use

In multi-device scenarios, Keyboard & mouse sharing feature can be enabled to move the keyboard and mouse between different devices. Through cross-device drag and drop, the user can easily drag materials from the local device to the remote device to quickly complete content creation and enjoy efficient cross-device collaboration.

To use this feature, the device restrictions and usage restrictions must be met. For details, see Constraints in "Drag-and-Drop Across Devices".

[h2]How to Implement

Scenario Analysis

  1. A user holds down the mouse to trigger a drag event to drag images or texts from the local editing page to the remote editing page.
  2. During this process, the system automatically processes cross-device data transmission. You do not need to intervene.
  3. When the user releases the mouse, the drag release event is triggered. The remote app processes the received drag data and writes the data to the remote editing page.

Key Technologies

The cross-device drag-and-drop feature allows the system to automatically move the mouse between different devices and transfer data. You can drag components in or out and finish the development of drag event in your app based on service requirements. For details, see Working Principles in "Drag-and-Drop Across Devices".

[h2]How to Implement

Cross-Device Image/Video/Text Clipping and Pasting

[h2]When to Use

In multi-device scenarios, cross-device pasteboard enables the user to copy text, images, or videos in the app of the local device and paste it to the app of the remote device, achieving efficient content sharing.

To use this feature, the device restrictions and usage restrictions must be met. For details, see Constraints in "Cross-Device Pasteboard".

[h2]How to Implement

Scenario Analysis

1. A user copies data at the local device, which is written to the system pasteboard service.

2. The system pasteboard service processes and synchronizes the data. This process is not perceived by developers.

3. The user reads the content from the system pasteboard at the remote device and pastes the data from the local device.

Key Technologies

The cross-device pasteboard feature allows the system to automatically complete data transmission across devices. Apps can access the cross-device pasteboard as required to implement cross-device data sharing. For details, see Working Principles in "Cross-Device Pasteboard".

[h2]How to Implement

Cross-Device App Continuation

[h2]When to Use

When the environment changes during usage and a more appropriate device is detected, the user can migrate an ongoing task to another device without exiting. After the continuation is complete, the app on the previous device can be exited or retained. The started device continues the task.

To use this feature, the device and usage restrictions must be met. For details, see Constraints in "App Continuation Overview".

[h2]How to Implement

Scenario Analysis

  1. A user selects photos/videos and enters the title and text on the local device.
  2. After the user taps the dock icon on the remote device, the local device initiates a continuation and transfers data to the remote device.
  3. The remote device receives and displays the continuation data.

The core of this scenario is how to transfer data during app continuation. You can use distributed data objects to store text information; copy the photos/videos to a distributed file directory and use distributed data assets to save them as root properties of distributed data objects.

Key Technologies

The device that initiates the continuation is called the local device, and the device that receives the data is called the remote device. The underlying continuation process relies on the distributed framework and soft bus. You only need to enable continuation, save data, and restore data. For details, see Working Principles in "App Continuation Overview".

[h2]How to Implement

Inserting Images Through Tap to Transfer

[h2]When to Use

In multi-device collaboration scenarios, users can quickly transfer images from their phones to PCs through Tap to Transfer. For example, a user can browse images in the gallery on their phone and then use Tap to Transfer to insert the images into an app on the PC.

To use this feature, certain device and usage restrictions must be met. For details, see Constraints in "Overview of Tap to Transfer Between a Phone and a PC/2-in-1 Device".

[h2]How to Implement

Scenario Analysis

  1. A user browses images in the gallery on the phone and selects the image to be inserted.
  2. Based on the gallery-based Tap to Transfer feature, the user taps the top of the phone against the PC screen to open the Tap to Transfer screen and share the image.
  3. After receiving the shared image, the PC inserts it into the app page.

For details, see "PC/2-in-1 device as the data receiver" in Service Process of "Overview of Tap to Transfer Between a Phone and a PC/2-in-1 Device".

Key Technologies

The core of receiving images inserted through Tap to Transfer on a PC is to use the data receiving feature of harmonyShare.

  1. Data receiving listener registration: Call harmonyShare.on('dataReceive') to register a data receiving listener.
  2. Receiving capability setting: Define the supported data types and the maximum number of data items that can be received.
  3. Received data processing: Process the received file data in the onDataReceived callback.
  4. Conversion to PixelMap: Convert the received image data into a PixelMap for display.

[h2]How to Implement

  1. Register an on('dataReceive') listener on the PC to receive data from the phone.
    /**
     * Add dataReceive listening in 2in1 device type.
     */
    public dataReceiveListeningPC(uiContext: UIContext) {
      if (!canIUse('SystemCapability.Collaboration.HarmonyShare')) {
        return;
      }
      window.getLastWindow(this.context).then(((data) => {
        try {
          let mainWindowID: number = data.getWindowProperties().id;
          harmonyShare.on('dataReceive', {
            windowId: mainWindowID, capabilities: [
              {
                'utd': uniformTypeDescriptor.UniformDataType.MEDIA,
                'maxSupportedCount': 5
              },
              {
                'utd': uniformTypeDescriptor.UniformDataType.FILE,
                'maxSupportedCount': 5
              }
            ]
          },
            (receiveTarget: harmonyShare.ReceivableTarget) => {
              if (!this.context) {
                return;
              }
    
              // Process the received file data.
              receiveTarget.receive(fileUri.getUriFromPath(this.context.filesDir), {
                onDataReceived: (shareData: systemShare.SharedData) => {
                  // ...
                },
                onResult(resultCode: harmonyShare.ShareResultCode) {
                  if (resultCode === harmonyShare.ShareResultCode.SHARE_SUCCESS) {
                    hilog.info(DOMAIN, TAG, FORMAT, 'receive file success');
                  } else {
                    hilog.error(DOMAIN, TAG, FORMAT, 'receive failed ' + resultCode);
                  }
                }
              });
            });
        } catch (error) {
          hilog.error(DOMAIN, TAG, FORMAT, `getWindowProperties error ${error.code} ${error.message}`);
        }
      })).catch((error: BusinessError) => {
        hilog.error(DOMAIN, TAG, FORMAT, `failed to obtain the window. cause ${error.code} ${error.message}`);
      });
    }
  2. Customize the implementation of the ReceiveCallback() callback function to process the received data. For example, the received image data is converted into a pixel map for display in the app.
    let shareRecords = shareData.getRecords();
    let mediaUriArray = AppStorage.get('mediaUriArray') as Array<MediaInfo>;
    shareRecords.forEach(async (record: systemShare.SharedRecord) => {
      if (!record.uri) {
        return;
      }
      let fileName = record.uri.split('/').pop()?.split('.')[0];
      if (record.uri.endsWith('png') || record.uri.endsWith('jpg') || record.uri.endsWith('jpeg')) {
        let imageUri = record.uri;
        let file = fileIo.openSync(imageUri, fileIo.OpenMode.READ_ONLY);
        let imageSourceApi: image.ImageSource | undefined = undefined;
        try {
          imageSourceApi = image.createImageSource(file.fd);
        } catch (err) {
          hilog.error(DOMAIN, TAG, FORMAT,
            `CreateImageSource error: ${(err as BusinessError).code} ${(err as BusinessError).message}`);
        } finally {
          fileIo.closeSync(file.fd);
        }
        const imagePackApi = image.createImagePacker();
        let packOpts: image.PackingOption = { format: 'image/png', quality: 100 };
        imagePackApi.packToData(imageSourceApi!, packOpts).then(async readBuffer => {
          let imageSource: image.ImageSource = image.createImageSource(readBuffer as ArrayBuffer);
          let option: image.InitializationOptions = {
            pixelFormat: 3,
            size: {
              width: 100,
              height: 100
            }
          };
          imageSource.createPixelMap(option).then((pixelMap: PixelMap) => {
            if (mediaUriArray.length < CommonConstants.MAX_ADD_MEDIA_NUM) {
              mediaUriArray.push({
                imagePixelMap: pixelMap,
                mediaName: fileName,
                mediaType: MediaType.MEDIA_IMAGE
              });
            } else {
              try {
                uiContext.getPromptAction().showToast({ message: $r('app.string.add_picture_prompt') });
              } catch (err) {
                hilog.error(DOMAIN, TAG, FORMAT,
                  `ShowToast failed. Cause code: ${(err as BusinessError).code}, message: ${(err as BusinessError).message}`);
              }
            }
            imageSource.release();
            imageSource = undefined;
            imageSourceApi?.release();
            imageSourceApi = undefined;
          });
        }).catch((err: BusinessError) => {
          hilog.error(DOMAIN, TAG, FORMAT,
            `PackToData failed. Cause code: ${err.code}, message: ${err.message}`);
        });
      }
    });
  3. When the user leaves the sharing screen (including scenarios where the app is switched to the background), the Grab & drop event listener is unregistered to release resources.
    /**
     *  Remove dataReceive listening.
     */
    public dataReceiveDisableListeningPC() {
      if (!canIUse('SystemCapability.Collaboration.HarmonyShare')) {
        return;
      }
      window.getLastWindow(this.context).then(((data) => {
        try {
          let mainWindowID: number = data.getWindowProperties().id;
          harmonyShare.off('dataReceive', {
            windowId: mainWindowID, capabilities: [
              {
                'utd': uniformTypeDescriptor.UniformDataType.MEDIA,
                'maxSupportedCount': 5
              },
              {
                'utd': uniformTypeDescriptor.UniformDataType.FILE,
                'maxSupportedCount': 5
              }
            ]
          });
        } catch (error) {
          hilog.error(DOMAIN, TAG, FORMAT, `getWindowProperties error ${error.code} ${error.message}`);
        }
      })).catch((error: BusinessError) => {
        hilog.error(DOMAIN, TAG, FORMAT, `failed to obtain the window. cause ${error.code} ${error.message}`);
      });
    }

Sharing Pages Through Tap to Transfer

[h2]When to Use

In multi-device collaboration scenarios, users can share the current page to another device through Tap to Transfer. For example, a user can browse a content page on their phone and then use Tap to Transfer to share the page to a nearby device.

To use this feature, the device and usage restrictions must be met. For details, see:

  • Tap to Transfer Between Phones: Constraints
  • Tap to Transfer Between a Phone and a PC/2-in-1 Device: Constraints

[h2]How to Implement

Scenario Analysis

1. A user opens the app on the local device and taps the details page of the content to be shared.

2. The user performs the Tap to Transfer operation between the local device and the remote device. The local device triggers the Tap to Transfer sharing panel, and the user swipes up to share the content.

3. The remote device displays the receiving panel. The user can tap the receiving button to directly access the app sharing page. If the user taps the reject button, a dialog box is displayed on the local device, indicating that the sharing is rejected.

Key Technologies

The core of the Tap to Transfer sharing page is to support cross-device link sharing through Tap to Transfer. For details, see Tap to Transfer for Links.

[h2]How to Implement

1. Configure App Linking. To implement the feature of directly accessing an app through Tap to Transfer, your app needs to integrate App Linking to ensure the integrity of end-to-end experience. For details about the configuration method, see Configuring App Linking.

{
  "module": {
    // ...
    "abilities": [
      {
        "name": "EntryAbility",
        // ...
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home",
              // entities must contain "entity.system.browsable"
              "entity.system.browsable"
            ],
            "actions": [
              "action.system.home",
              // Actions must contain "ohos.want.action.viewData"
              "ohos.want.action.viewData"
            ],
            "uris": [
              {
                // The scheme must be configured as https
                "scheme": "https",
                // The host must be configured as the associated domain name
                "host": "www.example.com",
                "path": ""
              }
            ],
            // domainVerify must be set to true
            "domainVerify": true
          }
        ],
        // ...
      }
    ],
    // ...
  }
}

2. Register the on('knockShare') event to listen for the Tap to Transfer event and cancel the listening through off('knockShare').

/**
 *  Add knock listening.
 */
public immersiveListening() {
  if (canIUse('SystemCapability.Collaboration.HarmonyShare')) {
    harmonyShare.on('knockShare', (target: harmonyShare.SharableTarget) => {
      this.immersiveCallback(target);
    });
  }
}

/**
 *  Add knock listening in 2in1 device type.
 */
public immersiveListeningPC() {
  if (canIUse('SystemCapability.Collaboration.HarmonyShare')) {
    window.getLastWindow(this.context).then((data) => {
      try {
        let mainWindowID: number = data.getWindowProperties().id;
        harmonyShare.on('knockShare', { windowId: mainWindowID }, (target: harmonyShare.SharableTarget) => {
          this.immersiveCallback(target);
        });
      } catch (err) {
        hilog.error(DOMAIN, TAG, FORMAT,
          `GetWindowProperties error: ${(err as BusinessError).code} ${(err as BusinessError).message}`);
      }
    }).catch((error: BusinessError) => {
      hilog.error(DOMAIN, TAG, FORMAT, `GetLastWindow failed. Error: ${error.code} ${error.message}`);
    });
  }
}

/**
 *  remove knock listening.
 */
public immersiveDisableListening() {
  if (canIUse('SystemCapability.Collaboration.HarmonyShare')) {
    harmonyShare.off('knockShare');
  }
}

/**
 *  remove knock listening.
 */
public immersiveDisableListeningPC() {
  if (canIUse('SystemCapability.Collaboration.HarmonyShare')) {
    window.getLastWindow(this.context).then((data) => {
      try {
        let mainWindowID: number = data.getWindowProperties().id;
        harmonyShare.off('knockShare', { windowId: mainWindowID });
      } catch (err) {
        hilog.error(DOMAIN, TAG, FORMAT,
          `GetWindowProperties error ${(err as BusinessError).code} ${(err as BusinessError).message}`);
      }
    }).catch((error: BusinessError) => {
      hilog.error(DOMAIN, TAG, FORMAT, `GetLastWindow failed. Error: ${error.code} ${error.message}`);
    });
  }
}

3. Construct the data to be shared and initiate the sharing on the local device. Construct the ShareRecord object, set the utd attribute to uniformTypeDescriptor.UniformDataType.HYPERLINK (for details about the attribute, see UniformDataType), and set the content attribute to the corresponding page link. After the construction is complete, call the share() method of sharableTarget to initiate the sharing.

/**
 * Knock listening callback.
 *
 * @param target After the Huawei Share event is triggered,
 * you can call back the parameters and share them across devices.
 */
public immersiveCallback(target: harmonyShare.SharableTarget) {
  let shareData: systemShare.SharedData = this.getLinkShareData();
  target.share(shareData);
}

/**
 * Get link share data.
 * @returns systemShare.SharedData.
 */
getLinkShareData(): systemShare.SharedData {
  let encodedParams = encodeURIComponent(JSON.stringify(this.pageParamsData));
  let title: string = CommonConstants.STRING_DEFAULT_VALUE;
  try {
    title = this.context!.resourceManager.getStringSync(this.pageParamsData?.userName.id);
  } catch (err) {
    hilog.error(DOMAIN, TAG, FORMAT,
      `resourceManager getStringSync error: ${(err as BusinessError).code} ${(err as BusinessError).message}`);
  }
  // share app linking.
  let shareData: systemShare.SharedData = new systemShare.SharedData({
    // Set the shared data type to Link.
    utd: uniformTypeDescriptor.UniformDataType.HYPERLINK,
    // title
    title: title,
    // description
    description: this.pageParamsData?.title,
    // The shared App Linking link is replaced with the real address here.
    content: `${CommonConstants.SHARE_URL_SCHEME}://www.example.com?pageUrl=${this.pageUrl}&pageParams=${encodedParams}&sharingMechanism=knockShare`,
  });
  return shareData;
}

4. (The app has been installed on the remote device.) The remote device obtains information such as the target page and input parameters in the link in the onCreate() and onNewWant() lifecycle methods for subsequent redirection.

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  // ...

  let pageUrl = getValueFromWant(want, 'pageUrl');
  let pageParams = getValueFromWant(want, 'pageParams');
  let shareMechanism = getValueFromWant(want, 'sharingMechanism');
  if (pageUrl !== '') {
    if (shareMechanism === 'gesturesShare') {
      // ...
    } else if (shareMechanism === 'knockShare') {
      AppStorage.setOrCreate(CommonConstants.KNOCK_SHARE_SHARE_PAGE_URL, pageUrl);
      AppStorage.setOrCreate(CommonConstants.KNOCK_SHARE_SHARE_PAGE_PARAMS, pageParams);
      AppStorage.setOrCreate(CommonConstants.KNOCK_SHARE_IS_SHARE_LINK, true);
    }
  }
  hilog.info(DOMAIN, TAG, FORMAT, `onCreate() pageUrl: ${pageUrl} pageParams:${pageParams}`);
}

onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  // ...
  let pageUrl = getValueFromWant(want, 'pageUrl');
  let pageParams = getValueFromWant(want, 'pageParams');
  let shareMechanism = getValueFromWant(want, 'sharingMechanism');
  if (pageUrl !== '') {
    if (shareMechanism === 'gesturesShare') {
      // ...
    } else if (shareMechanism === 'knockShare') {
      AppStorage.setOrCreate(CommonConstants.KNOCK_SHARE_SHARE_PAGE_URL, pageUrl);
      AppStorage.setOrCreate(CommonConstants.KNOCK_SHARE_SHARE_PAGE_PARAMS, pageParams);
      AppStorage.setOrCreate(CommonConstants.KNOCK_SHARE_IS_SHARE_LINK, true);
    }
  }
  hilog.info(DOMAIN, TAG, FORMAT, `onNewWant() pageUrl: ${pageUrl} pageParams:${pageParams}`);
}

The parsing logic can be encapsulated into a tool method for subsequent invoking.

export function getValueFromWant(want: Want, key: string): string {
  let value: string = '';
  try {
    let uri = want?.uri;
    if (!uri) {
      hilog.error(DOMAIN, TAG, FORMAT, `Failed to getValueFromWant, uri is undefined.`);
      return value;
    }
    // Parse the parameters to obtain the app linking
    let urlObject = url.URL.parseURL(want?.uri);
    if (key !== 'pageParams') {
      value = urlObject.params.get(key) as string;
      return value;
    }
    let encodedData = urlObject.params.get(key);
    if (encodedData) {
      value = decodeURIComponent(encodedData);
    }
    return value;
  } catch (err) {
    let error = err as BusinessError;
    hilog.error(DOMAIN, TAG, FORMAT, `Failed to getValueFromWant, error: ${error.code} ${error.message}`);
  }
  return value;
}

Sharing Pages Through Grab & Drop

[h2]When to Use

In multi-device collaboration scenarios, users can share the current page to another device through air gestures. For example, a user can browse content on their phone and use the grab-and-drop gesture to share the page to a nearby device.

To use this feature, the device and usage restrictions must be met. For details, see Restrictions.

[h2]How to Implement

Scenario Analysis

1. A user opens the app on the local device and taps the details page of the content to be shared.

2. The user perform the grab gesture on the local device and then the drop gesture on the remote device.

3. After the remote device successfully identifies the gesture, the user can directly access the app sharing page.

Key Technologies

Grab & drop is based on the Share Kit. An app can listen for the harmonyShare.on('gesturesShare') event, so that users can share content across devices by performing the simple grab-and-drop gesture. For details, see Key Technologies.

[h2]How to Implement

1. Configure the App Linking service. To implement the feature of directly accessing an app through Grab & drop, your app needs to integrate App Linking to ensure the integrity of end-to-end experience. For details about the configuration method, see Configuring App Linking.

{
  "module": {
    // ...
    "abilities": [
      {
        "name": "EntryAbility",
        // ...
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home",
              // entities must contain "entity.system.browsable"
              "entity.system.browsable"
            ],
            "actions": [
              "action.system.home",
              // Actions must contain "ohos.want.action.viewData"
              "ohos.want.action.viewData"
            ],
            "uris": [
              {
                // The scheme must be configured as https
                "scheme": "https",
                // The host must be configured as the associated domain name
                "host": "www.example.com",
                "path": ""
              }
            ],
            // domainVerify must be set to true
            "domainVerify": true
          }
        ],
        // ...
      }
    ],
    // ...
  }
}

2. Register the on('gesturesShare') event to listen for the Grab & drop event and cancel the listening through off('gesturesShare').

/**
 *  Add gesturesShare listening.
 */
public immersiveListening(shareType: ShareType) {
  if (canIUse('SystemCapability.Collaboration.HarmonyShare')) {
    window.getLastWindow(this.context).then((data) => {
      try {
        let mainWindowID: number = data.getWindowProperties().id;
        harmonyShare.on('gesturesShare', { windowId: mainWindowID }, (target: harmonyShare.SharableTarget) => {
          this.immersiveCallback(target, shareType);
        });
      } catch (err) {
        let error = err as BusinessError;
        hilog.error(DOMAIN, TAG, FORMAT, `getWindowProperties error ${error.code} ${error.message}`);
      }
    }).catch((error: BusinessError) => {
      hilog.error(DOMAIN, TAG, FORMAT, `immersiveListening error ${error.code} ${error.message}`);
    })
  }
}

/**
 *  Remove gesturesShare listening.
 */
public immersiveDisableListening() {
  if (canIUse('SystemCapability.Collaboration.HarmonyShare')) {
    window.getLastWindow(this.context).then((data) => {
      try {
        let mainWindowID: number = data.getWindowProperties().id;
        harmonyShare.off('gesturesShare', { windowId: mainWindowID });
      } catch (error) {
        let err = error as BusinessError;
        hilog.error(DOMAIN, TAG, FORMAT, `getWindowProperties error ${err.code} ${err.message}`);
      }
    }).catch((error: BusinessError) => {
      hilog.error(DOMAIN, TAG, FORMAT, `immersiveDisableListening error ${error.code} ${error.message}`);
    })
  }
}

3. Construct the data to be shared and initiate the sharing on the local device. Construct the ShareRecord object, set the utd attribute to uniformTypeDescriptor.UniformDataType.HYPERLINK, and set the content attribute to the corresponding page link. After the construction is complete, call the share() method of sharableTarget to initiate the sharing.

public immersiveCallback(target: harmonyShare.SharableTarget, shareType: ShareType) {
  if (shareType === ShareType.LINK_SHARE) {
    let shareData: systemShare.SharedData = this.getLinkShareData();
    target.share(shareData);
  }
}


/**
 * Get link share data.
 * @returns systemShare.SharedData.
 */
getLinkShareData(): systemShare.SharedData {
  let encodedParams = encodeURIComponent(JSON.stringify(this.pageParamsData));
  let title: string = CommonConstants.STRING_DEFAULT_VALUE;
  try {
    title = this.context!.resourceManager.getStringSync(this.pageParamsData?.userName.id);
  } catch (err) {
    hilog.error(DOMAIN, TAG, FORMAT,
      `resourceManager getStringSync error: ${(err as BusinessError).code} ${(err as BusinessError).message}`);
  }
  // share app linking.
  let shareData: systemShare.SharedData = new systemShare.SharedData({
    // Set the shared data type to Link.
    utd: uniformTypeDescriptor.UniformDataType.HYPERLINK,
    // title
    title: title,
    // description
    description: this.pageParamsData?.title,
    // The shared App Linking link is replaced with the real address here.
    content: `${CommonConstants.SHARE_URL_SCHEME}://www.example.com?pageUrl=${this.pageUrl}&pageParams=${encodedParams}&sharingMechanism=gesturesShare`,
  });
  return shareData;
}

4. (The app has been installed on the remote device.) The remote device obtains information such as the target page and input parameters in the link in the onCreate() and onNewWant() lifecycle methods for subsequent redirection.

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  // ...

  let pageUrl = getValueFromWant(want, 'pageUrl');
  let pageParams = getValueFromWant(want, 'pageParams');
  let shareMechanism = getValueFromWant(want, 'sharingMechanism');
  if (pageUrl !== '') {
    if (shareMechanism === 'gesturesShare') {
      AppStorage.setOrCreate(CommonConstants.GESTURES_SHARE_SHARE_PAGE_URL, pageUrl);
      AppStorage.setOrCreate(CommonConstants.GESTURES_SHARE_SHARE_PAGE_PARAMS, pageParams);
      AppStorage.setOrCreate(CommonConstants.GESTURES_SHARE_IS_SHARE_LINK, true);
    } else if (shareMechanism === 'knockShare') {
      // ...
    }
  }
  hilog.info(DOMAIN, TAG, FORMAT, `onCreate() pageUrl: ${pageUrl} pageParams:${pageParams}`);
}

onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  // ...
  let pageUrl = getValueFromWant(want, 'pageUrl');
  let pageParams = getValueFromWant(want, 'pageParams');
  let shareMechanism = getValueFromWant(want, 'sharingMechanism');
  if (pageUrl !== '') {
    if (shareMechanism === 'gesturesShare') {
      AppStorage.setOrCreate(CommonConstants.GESTURES_SHARE_SHARE_PAGE_URL, pageUrl);
      AppStorage.setOrCreate(CommonConstants.GESTURES_SHARE_SHARE_PAGE_PARAMS, pageParams);
      AppStorage.setOrCreate(CommonConstants.GESTURES_SHARE_IS_SHARE_LINK, true);
    } else if (shareMechanism === 'knockShare') {
      // ...
    }
  }
  hilog.info(DOMAIN, TAG, FORMAT, `onNewWant() pageUrl: ${pageUrl} pageParams:${pageParams}`);
}

The parsing logic can be encapsulated into a tool method for subsequent invoking.

export function getValueFromWant(want: Want, key: string): string {
  let value: string = '';
  try {
    let uri = want?.uri;
    if (!uri) {
      hilog.error(DOMAIN, TAG, FORMAT, `Failed to getValueFromWant, uri is undefined.`);
      return value;
    }
    // Parse the parameters to obtain the app linking
    let urlObject = url.URL.parseURL(want?.uri);
    if (key !== 'pageParams') {
      value = urlObject.params.get(key) as string;
      return value;
    }
    let encodedData = urlObject.params.get(key);
    if (encodedData) {
      value = decodeURIComponent(encodedData);
    }
    return value;
  } catch (err) {
    let error = err as BusinessError;
    hilog.error(DOMAIN, TAG, FORMAT, `Failed to getValueFromWant, error: ${error.code} ${error.message}`);
  }
  return value;
}

Sample Code