鸿蒙学习实战之路-Share Kit系列(3/17)-分享文本内容实战

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

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


分享文本是啥?

分享文本就是把一段纯文本内容分享到其他应用或设备。比如:

  • 分享文章摘要到微信
  • 分享商品描述到微博
  • 分享一段话到华为笔记

目标设备会把文本保存为 txt 文件,方便用户查看和编辑。


核心步骤

实现分享文本,就三步:

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

完整代码示例

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

// 步骤1:构造分享数据
let shareData: systemShare.SharedData = new systemShare.SharedData({
  utd: 'general.text',
  uri: 'file://.../xxx.txt',
  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.text' 表示这是一个文本类型的数据。

🥦 西兰花小贴士
utd 类型需要遵循 UDMF(统一数据管理框架)定义的 UTD(统一类型描述符)规范。general.text 是通用的文本类型,适用于大部分文本分享场景。

uri - 文本文件路径

uri: 'file://.../xxx.txt' 是文本文件的 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 ArticlePage {
  // 文章数据
  articleTitle: string = '西兰花的烹饪秘籍';
  articleSummary: string = '西兰花是一种营养丰富的蔬菜,富含维生素C、维生素K、膳食纤维等。烹饪西兰花时,要注意火候,避免过度烹饪导致营养流失。';
  articlePreview: string = 'file://.../preview.jpg';

  // 分享文章摘要
  onShareArticle() {
    // 构造分享数据
    let shareData: systemShare.SharedData = new systemShare.SharedData({
      utd: 'general.text',
      uri: 'file://.../article_summary.txt',
      title: this.articleTitle,
      preview: this.articlePreview,
      description: this.articleSummary
    });

    // 构建分享控制器
    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(this.articleTitle)
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin(20)
        .fontColor(Color.Black);

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

      Button('分享文章')
        .onClick(() => {
          this.onShareArticle();
        })
        .margin(20);
    }
    .width('100%')
    .height('100%');
  }
}

如何创建文本文件?

上面的代码中,uri 指向一个文本文件。那么如何创建这个文本文件呢?

方法 1:使用文件管理 API 创建

import { fileIo } from '@kit.CoreFileKit';

// 创建文本文件
async function createTextFile(content: string, filePath: string): Promise<void> {
  try {
    // 打开文件,如果不存在则创建
    let file = await fileIo.open(filePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY);

    // 写入内容
    await fileIo.write(file.fd, content);

    // 关闭文件
    await fileIo.close(file.fd);
  } catch (e) {
    console.error(`创建文本文件失败:${e}`);
  }
}

// 使用示例
createTextFile('这是一段分享文本', 'file://.../xxx.txt');

方法 2:使用临时文件

import { fileIo } from '@kit.CoreFileKit';

// 创建临时文本文件
async function createTempTextFile(content: string): Promise<string> {
  try {
    // 创建临时文件
    let tempFile = await fileIo.createTempFile('.txt', 'share_');

    // 打开文件
    let file = await fileIo.open(tempFile.path, fileIo.OpenMode.WRITE_ONLY);

    // 写入内容
    await fileIo.write(file.fd, content);

    // 关闭文件
    await fileIo.close(file.fd);

    // 返回文件路径
    return `file://${tempFile.path}`;
  } catch (e) {
    console.error(`创建临时文本文件失败:${e}`);
    return '';
  }
}

// 使用示例
let filePath = await createTempTextFile('这是一段分享文本');
console.log(`临时文件路径:${filePath}`);

🥦 西兰花小贴士
使用临时文件的好处是,系统会自动清理这些文件,不需要手动删除。分享完成后,临时文件会被自动删除。


完整示例:创建并分享文本

把上面的代码整合起来,就是一个完整的创建并分享文本的实现:

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

@Entry
@Component
struct ShareTextPage {
  // 文本内容
  shareText: string = '西兰花的烹饪秘籍:\n\n西兰花是一种营养丰富的蔬菜,富含维生素C、维生素K、膳食纤维等。烹饪西兰花时,要注意火候,避免过度烹饪导致营养流失。';

  // 创建临时文本文件
  async createTempTextFile(content: string): Promise<string> {
    try {
      // 创建临时文件
      let tempFile = await fileIo.createTempFile('.txt', 'share_');

      // 打开文件
      let file = await fileIo.open(tempFile.path, fileIo.OpenMode.WRITE_ONLY);

      // 写入内容
      await fileIo.write(file.fd, content);

      // 关闭文件
      await fileIo.close(file.fd);

      // 返回文件路径
      return `file://${tempFile.path}`;
    } catch (e) {
      console.error(`创建临时文本文件失败:${e}`);
      return '';
    }
  }

  // 分享文本
  async onShareText() {
    // 创建临时文本文件
    let filePath = await this.createTempTextFile(this.shareText);
    if (!filePath) {
      console.error('创建临时文本文件失败');
      return;
    }

    // 构造分享数据
    let shareData: systemShare.SharedData = new systemShare.SharedData({
      utd: 'general.text',
      uri: filePath,
      title: '分享文本',
      description: this.shareText
    });

    // 构建分享控制器
    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);

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

      Button('分享文本')
        .onClick(() => {
          this.onShareText();
        })
        .margin(20);
    }
    .width('100%')
    .height('100%');
  }
}

常见问题

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

检查以下几点:

  1. 文件路径是否正确

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

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

Q2:如何分享多行文本?

多行文本和单行文本的分享方式是一样的,只需要在文本内容中包含换行符 \n 即可:

let shareText: string = '第一行\n第二行\n第三行';

Q3:如何分享超长文本?

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

如果文本超长,可以考虑:

  1. 截断文本:只分享文本的前面部分
  2. 分段分享:把文本分成多段,分别分享
  3. 改为分享链接:如果文本是文章内容,可以改为分享文章链接

下一步学什么?

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

  1. 分享图片内容:分享单张或多张图片
  2. 分享视频内容:分享视频文件,支持生成封面图
  3. 分享链接内容:分享 App Linking 或普通链接
  4. 高级功能:自定义分享面板、获取分享结果

推荐资料

📚 官方文档


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

Logo

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

更多推荐