开天辟地 HarmonyOS(鸿蒙) - 跨进程通信: 系统分享

源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd

开天辟地 HarmonyOS(鸿蒙) - 跨进程通信: 系统分享

示例如下:

pages\ipc\ShareDemo.ets

/*
 * 系统分享
 *
 * 注:本例演示的是分享源,关于分享目标请参见 /harmonydemo2 项目的相关说明
 *
 * 在系统分享的目标应用的 module.json5 中做类似如下的配置
 * {
 *   "module": {
 *     "abilities": [
 *       {
 *         "skills": [
 *           // 作为系统分享的目标应用,需要做类似如下的配置
 *           {
 *             "actions": [
 *               "ohos.want.action.sendData"
 *             ],
 *             "uris": [
 *               {
 *                 // 系统分享的目标应用的协议名,必须配置为 file
 *                 "scheme": "file",
 *                 // 可接收数据的标准化数据类型
 *                 // 分享源分享此 utd 的数据时,当前应用会显示在分享面板中
 *                 "utd": "general.text",
 *                 // 可接收的分享数据的最大数量
 *                 "maxFileSupported": 1
 *               },
 *               {
 *                 "scheme": "file",
 *                 "utd": "general.jpeg",
 *                 "maxFileSupported": 1
 *               }
 *             ]
 *           }
 *         ]
 *       }
 *     ]
 *   }
 * }
 */

import { RadioBar, TitleBar } from '../TitleBar';
import { systemShare } from '@kit.ShareKit';
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileUri, fileIo as fs } from '@kit.CoreFileKit';

@Entry
@Component
struct ShareDemo {

  build() {
    Column({space:10}) {
      TitleBar()
      Tabs() {
        TabContent() { MySample1() }.tabBar('分享文本').align(Alignment.Top)
        TabContent() { MySample2() }.tabBar('分享图片').align(Alignment.Top)
      }
      .scrollable(true)
      .barMode(BarMode.Scrollable)
      .layoutWeight(1)
    }
  }
}

@Component
struct MySample1 {

  @State message: string = ""

  context = getContext(this) as common.UIAbilityContext

  build() {
    Column({space:10}) {

      Text(this.message)

      /*
       * systemShare.SharedData - 分享数据
       *   utd - 标准化数据类型(utd 的全称是 uniform type descriptor)
       *     只有支持此 utd 的分享目标才会显示在分享面板中
       *     可以使用 UniformDataType.TEXT, UniformDataType.IMAGE, UniformDataType.VIDEO 等
       *     可以通过 getUniformDataTypeByFilenameExtension() 获取标准化数据类型
       *   title - 标题
       *   description - 描述
       *   content - 内容
       *   extraData - 扩展数据
       *   uri - 分享的文件的地址
       *     通过 fileUri.getUriFromPath() 获取文件的分享地址
       *   thumbnail - 分享数据左侧显示的图标(一个 Uint8Array 数据)
       *   thumbnailUri - 分享数据左侧显示的图标(一个 string 数据)
       *   addRecord() - 添加一条分享数据记录(用于一次分享多条数据记录)
       *
       * systemShare.ShareController() - 分享面板
       *   data - 指定分享数据
       *   show() - 拉起分享面板
       *     selectionMode - 选择的模式(SelectionMode 枚举)
       *       SINGLE - 单选
       *       BATCH - 多选
       *     previewMode - 预览的模式(SharePreviewMode 枚举)
       *       DEFAULT - 图文模式
       *       DETAIL - 大图模式
       */
      Button("分享文本").onClick(() => {
        let shareData: systemShare.SharedData = new systemShare.SharedData({
          utd: utd.UniformDataType.TEXT,
          title: 'title',
          description: 'description',
          content: 'content',
        })

        let controller: systemShare.ShareController = new systemShare.ShareController(shareData)
        controller.show(this.context, {
          selectionMode: systemShare.SelectionMode.SINGLE,
          previewMode: systemShare.SharePreviewMode.DEFAULT
        }).then(() => {
          this.message = "打开系统分享面板成功"
        }).catch((error: BusinessError) => {
          this.message = `打开系统分享面板失败 errCode:${error.code}, errMessage:${error.message}`
        });
      })
    }
  }
}

@Component
struct MySample2 {

  @State message: string = ""

  context = getContext(this) as common.UIAbilityContext

  @State previewMode: systemShare.SharePreviewMode = systemShare.SharePreviewMode.DEFAULT
  valueList =  ["DEFAULT", "DETAIL"]

  build() {
    Column({space:10}) {

      RadioBar({valueList: this.valueList, onChange: (selectedIndex: number) => {
        this.previewMode = systemShare.SharePreviewMode[this.valueList[selectedIndex]]
      }})

      Text(this.message)

      Button("分享图片").onClick(() => {

        // 需要分享的图片的沙箱地址
        let filePath = `${getContext(this).filesDir + "/share.jpg"}`

        // 从 rawfile 中复制文件到指定的沙箱地址
        let context = getContext(this) as common.UIAbilityContext;
        context.resourceManager.getRawFileContent('son.jpg', (err, value) => {
          let myBuffer: ArrayBufferLike = value.buffer
          let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
          fs.writeSync(file.fd, myBuffer)
          fs.closeSync(file)
        })

        /*
         * systemShare.SharedData - 分享数据
         *   utd - 标准化数据类型(utd 的全称是 uniform type descriptor)
         *     只有支持此 utd 的分享目标才会显示在分享面板中
         *     可以使用 UniformDataType.TEXT, UniformDataType.IMAGE, UniformDataType.VIDEO 等
         *     可以通过 getUniformDataTypeByFilenameExtension() 获取标准化数据类型
         *   title - 标题
         *   description - 描述
         *   content - 内容
         *   uri - 分享的文件的地址
         *     通过 fileUri.getUriFromPath() 获取文件的分享地址
         *   extraData - 扩展数据
         *   thumbnail - 分享数据左侧显示的图标(一个 Uint8Array 数据)
         *   thumbnailUri - 分享数据左侧显示的图标(一个 string 数据)
         *   addRecord() - 添加一条分享数据记录(用于一次分享多条数据记录)
         *
         * systemShare.ShareController() - 分享面板
         *   data - 指定分享数据
         *   show() - 拉起分享面板
         *     selectionMode - 选择的模式(SelectionMode 枚举)
         *       SINGLE - 单选
         *       BATCH - 多选
         *     previewMode - 预览的模式(SharePreviewMode 枚举)
         *       DEFAULT - 图文模式
         *       DETAIL - 大图模式
         */
        let shareData: systemShare.SharedData = new systemShare.SharedData({
          utd: utd.getUniformDataTypeByFilenameExtension('.jpg', utd.UniformDataType.IMAGE),
          uri: fileUri.getUriFromPath(filePath),
          title: 'title',
          description: 'description',
        })

        let controller: systemShare.ShareController = new systemShare.ShareController(shareData)
        controller.show(this.context, {
          selectionMode: systemShare.SelectionMode.SINGLE,
          previewMode: this.previewMode
        }).then(() => {
          this.message = "打开系统分享面板成功"
        }).catch((error: BusinessError) => {
          this.message = `打开系统分享面板失败 errCode:${error.code}, errMessage:${error.message}`
        });
      })
    }
  }
}

\harmonydemo2\entry\src\main\module.json5

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "com.webabcd.harmonydemo2.EntryAbility",
    "deviceTypes": [
      "phone",
      "tablet",
      "2in1"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "com.webabcd.harmonydemo2.EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:layered_image",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          },

          // 作为 deep linking 的目标应用,需要做类似如下的配置
          {
            // actions 不能为空,随便配置一个值就好
            "actions": [
              "action.app.scheme.webabcd"
            ],
            // 配置 deep linking 的地址,本例为 webabcd://a.b.c
            "uris": [
              {
                // deep linking 的协议名
                "scheme": "webabcd",
                // deep linking 的域名
                "host": "a.b.c",
              }
            ]
          },

          // 作为 app linking 的目标应用,需要做类似如下的配置
          {
            // entities 必须配置为 entity.system.browsable
            "entities": [
              "entity.system.browsable"
            ],
            // actions 必须配置为 ohos.want.action.viewData
            "actions": [
              "ohos.want.action.viewData"
            ],
            // 配置 app linking 的地址,本例为 https://x.y.z
            "uris": [
              {
                // app linking 的协议名,必须配置为 https
                "scheme": "https",
                // app linking 的域名
                "host": "x.y.z",
                // app linking 的 path,这是可选的,当需要一套域名匹配不同的应用时,则可以通过 path 区分
                "path": ""
              }
            ],
            // domainVerify 必须配置为 true
            "domainVerify": true
          },

          // 作为系统分享的目标应用,需要做类似如下的配置
          {
            "actions": [
              "ohos.want.action.sendData"
            ],
            "uris": [
              {
                // 系统分享的目标应用的协议名,必须配置为 file
                "scheme": "file",
                // 可接收数据的标准化数据类型
                // 分享源分享此 utd 的数据时,当前应用会显示在分享面板中
                "utd": "general.text",
                // 可接收的分享数据的最大数量
                "maxFileSupported": 1
              },
              {
                "scheme": "file",
                "utd": "general.jpeg",
                "maxFileSupported": 1
              }
            ]
          }
        ]
      }
    ]
  }
}

\harmonydemo2\entry\src\main\ets\entryability\EntryAbility.ets

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { systemShare } from '@kit.ShareKit';
import { BusinessError } from '@kit.BasicServicesKit';

export default class Feature1Ability extends UIAbility {

  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.parseWantParameter(want)
    this.parseWantShare(want)
  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.parseWantParameter(want)
    this.parseWantShare(want)
  }

  // 解析 Want 中的参数,并保存在 AppStorage 中
  parseWantParameter(want: Want) {
    let k1 = ""
    let k2 = ""
    if (want.parameters?.k1) {
      k1 = want.parameters.k1.toString()
    }
    if (want.parameters?.k2) {
      k2 = want.parameters.k2.toString()
    }
    AppStorage.setOrCreate("k1", k1)
    AppStorage.setOrCreate("k2", k2)
    AppStorage.setOrCreate("uri", want.uri ?? "")
  }

  // 解析 Want 中的分享数据,并保存在 AppStorage 中
  parseWantShare(want: Want) {
    /*
     * systemShare.getSharedData() - 获取分享过来的数据(需要在 module.json5 做相关的配置)
     * SharedData - 分享数据(请参见 /HarmonyDemo/entry/src/main/ets/pages/ipc/ShareDemo 中的相关说明)
     *   getRecords() - 获取分享数据中的所有记录
     * SharedRecord - 分享数据中的某条记录
     */
    systemShare.getSharedData(want).then((data: systemShare.SharedData) => {
      data.getRecords().forEach((record: systemShare.SharedRecord) => {
        let title = record.title
        let description = record.description
        let content = record.content
        let uri = record.uri
        AppStorage.setOrCreate("share_data", `title:${title}, description:${description}, content:${content}, uri:${uri}`)
        AppStorage.setOrCreate("share_uri", `${uri}`)
      });
    }).catch((error: BusinessError) => {

    });
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err) => {

    });
  }
}

\harmonydemo2\entry\src\main\ets\pages\Index.ets

/*
 * 本例用于演示 Want 的目标应用
 * 本例用于演示系统分享的目标应用
 */

@Entry
@Component
struct Index {

  @State message: string = '';

  // 分享过来的数据
  @StorageProp('share_data') share_data: string = ''
  // 分享过来的图片地址
  @StorageProp('share_uri') share_uri: string = ''

  onPageShow(): void {
    // 获取 AppStorage 中的数据(本例会在 UIAbility 中解析 Want 中的参数,并保存在 AppStorage 中)
    this.message = `k1: ${AppStorage.get("k1")}\n`
    this.message += `k2: ${AppStorage.get("k2")}\n`
    this.message += `uri: ${AppStorage.get("uri")}\n`
  }

  build() {
    Column({space:10}) {
      Text(this.message)

      Text(`share_data: ${this.share_data}`)

      Image(`${this.share_uri}`).width(50).height(50)
    }
    .justifyContent(FlexAlign.Start)
    .alignItems(HorizontalAlign.Start)
  }
}

源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd

posted @ 2025-04-15 09:49  webabcd  阅读(92)  评论(0)    收藏  举报