鸿蒙学习实战之路-Share Kit系列(4/17)-分享图片内容实战

最近好多朋友问我:“西兰花啊,我想让用户分享图片,比如商品图片、截图之类的,但不知道代码怎么写?” 害,这问题可问对人了!

今天这篇,我就手把手带你实现分享图片功能,从零到一,全程不超过 5 分钟(不含调试时间)~


分享图片是啥?

分享图片就是把图片文件分享到其他应用或设备。比如:

  • 分享商品图片到微信
  • 分享截图到微博
  • 分享照片到华为图库

目标设备会把图片保存到图库,方便用户查看和管理。


核心步骤

实现分享图片,就三步:

  1. 构造分享数据:创建 SharedData 对象,utd 类型设置为 general.image
  2. 构建分享控制器:创建 ShareController 对象
  3. 显示分享面板:调用 show 方法显示分享面板

完整代码示例

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

// 步骤1:构造分享数据
let shareData: systemShare.SharedData = new systemShare.SharedData({
  utd: 'general.image',
  uri: 'file://.../xxx.jpg',
  title: '分享图片',
  preview: 'file://.../preview.jpg',
  description: '这是一张分享图片'
});

// 步骤2:构建分享控制器
let controller: systemShare.ShareController = new systemShare.ShareController(shareData);

// 步骤3:显示分享面板
let uiContext: UIContext = this.getUIContext();
let context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext;

controller.show(context, {
  previewMode: systemShare.SharePreviewMode.DEFAULT,
  selectionMode: systemShare.SelectionMode.SINGLE
});

参数详解

utd - 图片类型标识

utd: 'general.image' 表示这是一个图片类型的数据。

🥦 西兰花小贴士
general.image 是通用的图片类型,适用于大部分图片分享场景。如果你需要更精确的图片类型,可以使用具体的图片格式,比如:

  • general.jpeg:JPEG 格式图片
  • general.png:PNG 格式图片
  • general.gif:GIF 格式图片

uri - 图片文件路径

uri: 'file://.../xxx.jpg' 是图片文件的 URI 路径。

这个路径需要指向一个实际存在的图片文件,否则分享会失败。

🥦 西兰花警告
我有个朋友第一次分享图片,随便写了个路径,结果分享面板弹出来但分享失败,debug 了两小时才发现文件不存在!血泪教训啊朋友们!

title - 分享标题

title: '分享图片' 是分享内容的标题,会在分享面板中显示。

这个标题要简洁明了,让用户一眼就知道分享的是什么内容。

preview - 预览图

preview: 'file://.../preview.jpg' 是预览图的 URI 路径。

预览图会在分享面板中显示,提升用户体验。如果不需要预览图,可以不设置这个参数。

description - 分享描述

description: '这是一张分享图片' 是分享内容的描述信息,会在分享面板中显示。

描述信息可以更详细地说明分享的内容,帮助用户理解。


在实际项目中怎么用?

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

示例:分享商品图片

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

@Entry
@Component
struct ProductPage {
  // 商品数据
  productName: string = '西兰花';
  productImage: string = 'file://.../broccoli.jpg';
  productDescription: string = '新鲜西兰花,营养丰富,口感清脆';

  // 分享商品图片
  onShareProduct() {
    // 构造分享数据
    let shareData: systemShare.SharedData = new systemShare.SharedData({
      utd: 'general.image',
      uri: this.productImage,
      title: this.productName,
      preview: this.productImage,
      description: this.productDescription
    });

    // 构建分享控制器
    let controller: systemShare.ShareController = new systemShare.ShareController(shareData);

    // 显示分享面板
    let uiContext: UIContext = this.getUIContext();
    let context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext;

    controller.show(context, {
      previewMode: systemShare.SharePreviewMode.DEFAULT,
      selectionMode: systemShare.SelectionMode.SINGLE
    });
  }

  build() {
    Column() {
      Image(this.productImage)
        .width(200)
        .height(200)
        .margin(20);

      Text(this.productName)
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ left: 20, right: 20, bottom: 10 })
        .fontColor(Color.Black);

      Text(this.productDescription)
        .fontSize(16)
        .margin({ left: 20, right: 20, bottom: 20 })
        .fontColor(Color.Gray);

      Button('分享商品')
        .onClick(() => {
          this.onShareProduct();
        })
        .margin(20);
    }
    .width('100%')
    .height('100%');
  }
}

如何分享多张图片?

分享多张图片和分享单张图片的方式类似,只需要创建多个 SharedData 对象,然后一次性分享即可。

示例:分享多张图片

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

@Entry
@Component
struct MultiImageSharePage {
  // 图片列表
  imageList: string[] = [
    'file://.../image1.jpg',
    'file://.../image2.jpg',
    'file://.../image3.jpg'
  ];

  // 分享多张图片
  onShareMultiImage() {
    // 构造分享数据列表
    let shareDataList: systemShare.SharedData[] = this.imageList.map(imagePath => {
      return new systemShare.SharedData({
        utd: 'general.image',
        uri: imagePath,
        title: '分享图片',
        preview: imagePath
      });
    });

    // 构建分享控制器
    let controller: systemShare.ShareController = new systemShare.ShareController(shareDataList);

    // 显示分享面板
    let uiContext: UIContext = this.getUIContext();
    let context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext;

    controller.show(context, {
      previewMode: systemShare.SharePreviewMode.DEFAULT,
      selectionMode: systemShare.SelectionMode.MULTIPLE
    });
  }

  build() {
    Column() {
      Text('分享多张图片示例')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin(20)
        .fontColor(Color.Black);

      ForEach(this.imageList, (imagePath: string) => {
        Image(imagePath)
          .width(100)
          .height(100)
          .margin(10);
      });

      Button('分享多张图片')
        .onClick(() => {
          this.onShareMultiImage();
        })
        .margin(20);
    }
    .width('100%')
    .height('100%');
  }
}

🥦 西兰花小贴士
分享多张图片时,需要把 selectionMode 设置为 systemShare.SelectionMode.MULTIPLE,这样用户才能选择多张图片。


如何从相册选择图片并分享?

上面的示例中,图片路径是固定的。但在实际项目中,你可能需要让用户从相册选择图片,然后分享。

示例:从相册选择图片并分享

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

@Entry
@Component
struct GallerySharePage {
  // 选中的图片路径
  selectedImage: string = '';

  // 从相册选择图片
  async selectImageFromGallery(): Promise<void> {
    try {
      // 创建图片选择器
      let photoPicker = new picker.PhotoViewPicker();

      // 选择图片
      let result = await photoPicker.select({
        MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE,
        maxSelectNumber: 1
      });

      // 获取选中的图片路径
      if (result.photoUris && result.photoUris.length > 0) {
        this.selectedImage = result.photoUris[0];
      }
    } catch (e) {
      console.error(`选择图片失败:${e}`);
    }
  }

  // 分享选中的图片
  onShareSelectedImage() {
    if (!this.selectedImage) {
      console.error('请先选择图片');
      return;
    }

    // 构造分享数据
    let shareData: systemShare.SharedData = new systemShare.SharedData({
      utd: 'general.image',
      uri: this.selectedImage,
      title: '分享图片',
      preview: this.selectedImage
    });

    // 构建分享控制器
    let controller: systemShare.ShareController = new systemShare.ShareController(shareData);

    // 显示分享面板
    let uiContext: UIContext = this.getUIContext();
    let context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext;

    controller.show(context, {
      previewMode: systemShare.SharePreviewMode.DEFAULT,
      selectionMode: systemShare.SelectionMode.SINGLE
    });
  }

  build() {
    Column() {
      Text('从相册选择图片并分享')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin(20)
        .fontColor(Color.Black);

      if (this.selectedImage) {
        Image(this.selectedImage)
          .width(200)
          .height(200)
          .margin(20);
      }

      Row() {
        Button('选择图片')
          .onClick(() => {
            this.selectImageFromGallery();
          })
          .margin(10);

        Button('分享图片')
          .onClick(() => {
            this.onShareSelectedImage();
          })
          .margin(10);
      }
      .margin(20);
    }
    .width('100%')
    .height('100%');
  }
}

🥦 西兰花小贴士
使用 picker.PhotoViewPicker 可以让用户从相册选择图片,这个 API 非常方便,不用自己实现相册选择功能。


常见问题

Q1:分享图片时提示"文件不存在"怎么办?

检查以下几点:

  1. 文件路径是否正确

    • 确认 uri 指向的文件是否存在
    • 确认 uri 格式是否正确(file:// 开头)
  2. 文件权限是否正确

    • 确认应用是否有读取该文件的权限

Q2:如何分享不同格式的图片?

不同格式的图片,分享方式是一样的,只需要确保 uri 指向正确格式的图片文件即可:

  • JPEG 格式file://.../xxx.jpg
  • PNG 格式file://.../xxx.png
  • GIF 格式file://.../xxx.gif

Q3:如何限制分享图片的大小?

Share Kit 对分享数据量有限制,单次分享的分享数据描述信息总量不能超过 200KB。

如果图片过大,可以考虑:

  1. 压缩图片:在分享前先压缩图片
  2. 缩放图片:缩小图片尺寸
  3. 改为分享链接:如果图片是网络图片,可以改为分享图片链接

下一步学什么?

看完这篇,你应该已经能实现分享图片功能了。接下来可以深入学习:

  1. 分享视频内容:分享视频文件,支持生成封面图
  2. 分享链接内容:分享 App Linking 或普通链接
  3. 高级功能:自定义分享面板、获取分享结果
  4. 目标应用接入:让你的应用能接收其他应用分享的图片

推荐资料

📚 官方文档


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

Logo

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

更多推荐