鸿蒙学习实战之路-Share Kit系列(11/17)-目标应用接收分享(分享详情页)

最近好多朋友问我:“西兰花啊,我想在分享详情页里处理分享内容,让用户确认后再处理,但不知道代码怎么写?” 害,这问题可问对人了!

今天这篇,我就手把手带你实现目标应用接收分享(分享详情页),从零到一,全程不超过 10 分钟(不含调试时间)~


分享详情页是啥?

分享详情页是一个独立的页面,用于展示分享内容,让用户确认后再处理。比如:

  • 用户分享一张图片到你的应用,先弹出分享详情页,显示图片
  • 用户确认后,再保存图片到应用

这就像前端的弹窗确认,只不过分享详情页是系统级别的服务,体验更统一。


应用内处理 vs 分享详情页

目标应用接收分享有两种方式:

方式 说明 适用场景
应用内处理 直接在应用内处理分享内容 内容简单,不需要额外操作
分享详情页 弹出一个详情页,用户确认后再处理 内容复杂,需要用户确认

上一篇我们讲了应用内处理,今天我们讲分享详情页。


完整实现步骤

实现目标应用接收分享(分享详情页),就三步:

  1. 配置 module.json5:声明 ShareExtensionAbility
  2. 实现 ShareExtensionAbility:在 onCreate 中解析分享数据
  3. 关闭分享面板:调用 terminateSelfWithResult 返回结果

步骤 1:配置 module.json5

module.json5 中声明 ShareExtensionAbility

{
  "module": {
    "abilities": [
      {
        "name": "ShareExtensionAbility",
        "srcEntry": "./ets/shareextensionability/ShareExtensionAbility.ets",
        "exported": true,
        "skills": [
          {
            "entities": ["entity.system.home"],
            "actions": ["ohos.want.action.sendData"],
            "uris": [
              {
                "scheme": "file",
                "linkFeature": "FileOpen",
                "type": "org.openxmlformats.wordprocessingml.document",
                "maxFileSupported": 1
              }
            ],
            "domainVerify": true
          }
        ]
      }
    ]
  }
}

参数说明

  • name:ShareExtensionAbility 的名称
  • srcEntry:ShareExtensionAbility 的文件路径
  • exported:设置为 true,表示可以被其他应用调用
  • skills:声明支持的 UTD 类型

🥦 西兰花警告
我有个朋友第一次配置 module.json5,忘记设置 exported: true,结果分享详情页一直弹不出来,debug 了两小时才发现是配置问题!血泪教训啊朋友们!


步骤 2:实现 ShareExtensionAbility

ShareExtensionAbilityonCreate 方法中解析 want 参数,获取分享数据。

import { common } from '@kit.AbilityKit';
import { systemShare } from '@kit.ShareKit';

@Entry
@Component
struct ShareExtensionAbility {
  onCreate(want: Want, launchParam: LaunchParam) {
    // 解析want参数,获取分享数据
    let shareData: systemShare.SharedData = new systemShare.SharedData({
      utd: want.parameters['utd'],
      uri: want.parameters['uri'],
      title: want.parameters['title'],
      preview: want.parameters['preview'],
      description: want.parameters['description']
    });
    // 处理分享数据
    this.handleShareData(shareData);
  }

  handleShareData(shareData: systemShare.SharedData) {
    // 处理分享数据
    console.log(`分享数据:${shareData}`);
  }
}

步骤 3:关闭分享面板

调用 ShareExtensionAbility.terminateSelfWithResult 方法,关闭分享面板,并返回分享结果。

handleShareData(shareData: systemShare.SharedData) {
  // 处理分享数据
  console.log(`分享数据:${shareData}`);
  // 关闭分享面板
  this.terminateSelfWithResult({
    resultCode: 0,
    resultMessage: '分享成功'
  });
}

参数说明

  • resultCode:分享结果的代码,0 表示成功,非 0 表示失败
  • resultMessage:分享结果的消息,比如"分享成功"、“分享失败”

完整代码示例

把上面的步骤整合起来,就是一个完整的目标应用接收分享(分享详情页)的实现:

import { common } from '@kit.AbilityKit';
import { systemShare } from '@kit.ShareKit';

@Entry
@Component
struct ShareExtensionAbility {
  // 分享数据
  shareData: systemShare.SharedData | null = null;

  onCreate(want: Want, launchParam: LaunchParam) {
    // 解析want参数,获取分享数据
    this.shareData = new systemShare.SharedData({
      utd: want.parameters['utd'],
      uri: want.parameters['uri'],
      title: want.parameters['title'],
      preview: want.parameters['preview'],
      description: want.parameters['description']
    });
  }

  // 确认分享
  onConfirmShare() {
    if (!this.shareData) {
      console.error('分享数据为空');
      return;
    }

    // 处理分享数据
    this.handleShareData(this.shareData);

    // 关闭分享面板
    this.terminateSelfWithResult({
      resultCode: 0,
      resultMessage: '分享成功'
    });
  }

  // 取消分享
  onCancelShare() {
    // 关闭分享面板
    this.terminateSelfWithResult({
      resultCode: 1,
      resultMessage: '用户取消分享'
    });
  }

  handleShareData(shareData: systemShare.SharedData) {
    // 处理分享数据
    console.log(`分享数据:${shareData}`);
  }

  build() {
    Column() {
      Text('分享详情页')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin(20)
        .fontColor(Color.Black);

      if (this.shareData) {
        Text(`标题:${this.shareData.title}`)
          .fontSize(16)
          .margin(20)
          .fontColor(Color.Black);

        Text(`描述:${this.shareData.description}`)
          .fontSize(16)
          .margin({ left: 20, right: 20, bottom: 20 })
          .fontColor(Color.Gray);

        Row() {
          Button('确认')
            .onClick(() => {
              this.onConfirmShare();
            })
            .margin(10);

          Button('取消')
            .onClick(() => {
              this.onCancelShare();
            })
            .margin(10);
        }
        .margin(20);
      }
    }
    .width('100%')
    .height('100%');
  }
}

在实际项目中怎么用?

上面的代码是基础实现,但在实际项目中,你可能会这样用:

示例:显示图片预览并确认

import { common } from '@kit.AbilityKit';
import { systemShare } from '@kit.ShareKit';

@Entry
@Component
struct ShareExtensionAbility {
  // 分享数据
  shareData: systemShare.SharedData | null = null;

  onCreate(want: Want, launchParam: LaunchParam) {
    // 解析want参数,获取分享数据
    this.shareData = new systemShare.SharedData({
      utd: want.parameters['utd'],
      uri: want.parameters['uri'],
      title: want.parameters['title'],
      preview: want.parameters['preview'],
      description: want.parameters['description']
    });
  }

  // 确认分享
  onConfirmShare() {
    if (!this.shareData) {
      console.error('分享数据为空');
      return;
    }

    // 处理分享数据
    this.handleShareData(this.shareData);

    // 关闭分享面板
    this.terminateSelfWithResult({
      resultCode: 0,
      resultMessage: '分享成功'
    });
  }

  // 取消分享
  onCancelShare() {
    // 关闭分享面板
    this.terminateSelfWithResult({
      resultCode: 1,
      resultMessage: '用户取消分享'
    });
  }

  handleShareData(shareData: systemShare.SharedData) {
    // 处理分享数据
    console.log(`分享数据:${shareData}`);
  }

  build() {
    Column() {
      Text('分享详情页')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin(20)
        .fontColor(Color.Black);

      if (this.shareData && this.shareData.preview) {
        Image(this.shareData.preview)
          .width(200)
          .height(200)
          .margin(20);
      }

      if (this.shareData) {
        Text(`标题:${this.shareData.title}`)
          .fontSize(16)
          .margin(20)
          .fontColor(Color.Black);

        Text(`描述:${this.shareData.description}`)
          .fontSize(16)
          .margin({ left: 20, right: 20, bottom: 20 })
          .fontColor(Color.Gray);

        Row() {
          Button('确认')
            .onClick(() => {
              this.onConfirmShare();
            })
            .margin(10);

          Button('取消')
            .onClick(() => {
              this.onCancelShare();
            })
            .margin(10);
        }
        .margin(20);
      }
    }
    .width('100%')
    .height('100%');
  }
}

常见问题

Q1:分享详情页弹不出来怎么办?

检查以下几点:

  1. module.json5 配置是否正确

    • 确认 exported 是否设置为 true
    • 确认 skills 中的 actions 是否设置为 ohos.want.action.sendData
    • 确认 uris 中的 type 是否和分享数据的 utd 类型匹配
  2. ShareExtensionAbility 文件路径是否正确

    • 确认 srcEntry 指向的文件是否存在
    • 确认文件路径是否正确

Q2:如何关闭分享面板?

调用 terminateSelfWithResult 方法,传入分享结果:

this.terminateSelfWithResult({
  resultCode: 0,
  resultMessage: "分享成功",
});

Q3:terminateSelfWithResult 的参数是什么?

参数 类型 说明
resultCode number 分享结果的代码,0 表示成功,非 0 表示失败
resultMessage string 分享结果的消息,比如"分享成功"、“分享失败”

下一步学什么?

看完这篇,你应该已经能实现目标应用接收分享(分享详情页)了。接下来可以深入学习:

  1. 判断应用是否被系统分享拉起:LaunchParam 的使用
  2. 配置目标应用名单:企业应用专属功能
  3. 高级功能:碰一碰分享、隔空传送
  4. 常见问题:分享失败、数据类型不支持等问题的解决方案

推荐资料

📚 官方文档


我是盐焗西兰花,
不教理论,只给你能跑的代码和避坑指南。
下期见!🥦

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐