【问题大类】HarmonyOS开发应用如何调用华为打印

鸿蒙使小强 2023-03-13 17:40:59

1 关键字

HarmonyOS;鸿蒙OS;应用沙盒;华为打印;Intent跳转;FileAbility;

2 问题描述

  • 问题现象:
  1. ETS/JAVA框架开发鸿蒙应用无法拉起华为打印。
  2. ETS/JAVA框架开发鸿蒙应用无法将沙盒文件传递给华为打印。
  • 测试步骤:
  1. 将开发好的HarmonyOS应用安装到对应的HarmonyOS设备上
  2. 运行应用
  3. 测试点击华为打印按钮
  4. 期望能正常打开华为打印,并能将需要打印的文档传递给华为打印

3 问题原因

  1. API 6中的ohos.data.file类中新增了FileAbility类,提供应用沙盒文件分享的能力,用于沙盒内文件的分享。开发者开发的鸿蒙应用需要不同的应用间文件共享,可以添加FileAbility的相关配置,用于沙盒内文件的分享。
  2. 鸿蒙OS提供了跳转第三方非鸿蒙应用的能力,在Intent中添加对应的flag显示申明,则可以跳转非鸿蒙应用。
  3. 跳转华为打印,需要传递对应的参数以及需要打印的资源Uri。

4 解决方案

通过下面的方式,可以使用HarmonyOS api 快速实现一个打开华为打印的示例:

4.1 在DevEco Stuido新建HarmonyOS工程

  • 新建HarmonyOS工程选择可以选择java框架开发,JS开发框架开发,ets开发框架开发。

  • 版本支持

    API6才开始支持FileAbility和APP文件沙盒,低于API6需要用DataAbility替代下文中用到的FileAbility

    开发框架API版本HarmonyOS版本
    JAVA>=6HarmonyOS2.X
    JS>=6HarmonyOS2.X
    ETS>=7HarmonyOS3.X

4.2 配置沙盒文件分享能力

将应用沙盒内的文件传递给华为打印,需要在应用中配置沙盒文件分享能力,按照以下步骤,可以轻松的实现沙盒文件分享。

  • 配置config.json:在app的config.json的abilities节点下面添加FileAbility配置
{
  "name": "ohos.data.file.FileAbility",
  "icon": "$media:icon",
  "description": "$string:dataability_description",
  "type": "data",
  "uri": "dataability://ohos.data.file.FileAbility",
  "grantPermission": true
}
  • 配置fileability.json:在resources\rawfile目录下,新建fileability.json,内容如下
{
  "paths": [
    {
      "tag": "fileability-external-path",
      "name": "external_storage_root",
      "path": "."
    },
    {
      "tag": "fileability-files-path",
      "name": "files-path",
      "path": "."
    },
    {
      "tag": "fileability-cache-path",
      "name": "cache-path",
      "path": "."
    },
    {
      "tag": "fileability-external-files-path",
      "name": "external_file_path",
      "path": "."
    },
    {
      "tag": "fileability-external-cache-path",
      "name": "external_cache_path",
      "path": "."
    },
    {
      "tag": "fileability-root-path",
      "name": "root-path",
      "path": ""
    }
  ]
}

4.3 跳转华为打印示例

现提供Java和JS/ETS 2种语言跳转华为打印App的事例。

4.3.1 JAVA API 示例

使用JAVA开发框架开发鸿蒙应用可以参考此方法,该方法详细讲述了如何跳转华为打印以及如何传递需要打印的资源到华为打印中。

  • 打印预览resources\rawfile目录下的文件

    1.新增文件读取权限

"reqPermissions": [
      {
        "name": "ohos.permission.WRITE_USER_STORAGE",
        "reason": "读取文件",
        "usedScene": {
          "ability": [
            "com.ohos.clientdemo.MainAbility"
          ],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.READ_USER_STORAGE",
        "reason": "读取文件",
        "usedScene": {
          "ability": [
            "com.ohos.clientdemo.MainAbility"
          ],
          "when": "always"
        }
      }
    ]

2.复制文件到APP沙盒

将resources/rawfile/目录下的test.docx 文档复制到手机本地存储对应的APP的沙盒中(/storage/emulated/0/Android/data/com.ohos.clientdemo/files/Documents/test.docx)

class MyRunnable implements Runnable {

        private void copyFile(String fileName) {
            Context context = getAbility();
            Resource resource = null;
            FileOutputStream fileOutputStream = null;
            try {
                resource = context.getResourceManager()
                 .getRawFileEntry("resources/rawfile/" + fileName).openRawFile();
                File externalFilesDir = context
                 .getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
                if (!externalFilesDir.exists()) {
                    externalFilesDir.mkdirs();
                }
                File file = new File(externalFilesDir, fileName);
                if (!file.exists()) {
                    file.createNewFile();
                }
                Log.i(fileName + " 文件开始复制  " + file.getAbsolutePath());
                fileOutputStream = new FileOutputStream(file.getAbsoluteFile());
                byte[] buffer = new byte[4096];
                int count = 0;
                while ((count = resource.read(buffer)) >= 0) {
                    fileOutputStream.write(buffer, 0, count);
                }
                Log.i(fileName + " 文件复制成功 " + file.length());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    resource.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void run() {
            copyFile("test.docx");
        }
    }

    private void saveFile() {
        new Thread(new MyRunnable()).start();
    }
  • 打印预览APP沙盒中的文件
 Intent intent = new Intent();
    // 华为打印的包名
    intent.setBundle("com.huawei.printservice");
    // 申明跳转的APP为非鸿蒙APP
    intent.addFlags(Intent.FLAG_NOT_OHOS_COMPONENT);
    // 赋予华为打印文件读取的临时权限
    intent.addFlags(0x00000001);
    // 传递给华为打印的参数
    intent.setParam("ActionType", "Print");
    File externalFilesDir = getAbility().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
    File file = new File(externalFilesDir, "test.docx");
    Log.i("file ------ " + file.getPath());
    // /storage/emulated/0/Android/data/com.ohos.clientdemo/files/Documents/test.docx
    Uri uri = FileAbility.getUriViaFile(getContext(), "ohos.data.file.FileAbility", file);
    Log.i("uri ------ " + uri.toString());
    // dataability:///ohos.data.file.FileAbility/external_storage_root/test.docx
    // 方法 1
    // 对应的华为打印Action
    intent.setAction("android.intent.action.SEND");
    // 需要打印的文件对应的uri
    intent.setParam("android.intent.extra.STREAM", uri);
    // 需要打印的文件的文件类型,可以不设置
    intent.setType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
    // 方法 2
    // intent.setAction("android.intent.action.VIEW");
    // intent.setUriAndType(uri,   "application/vnd.openxmlformatsofficedocument.wordprocessingml.document");
    getAbility().startAbility(intent);
  1. com.huawei.printservice为华为打印的应用包名;
  2. addFlags(Intent.FLAG_NOT_OHOS_COMPONENT)跳转非鸿蒙APP需要添加此flag
  3. addFlags(0x00000001)赋予华为打印文件读取的临时权限
  4. FileAbility.getUriViaFile可以将文件在沙盒中的路径转化为鸿蒙系统中的Uri对象;
  5. setAction("android.intent.action.SEND")跳转华为打印APP的action
  6. setParam("android.intent.extra.STREAM", uri)跳转华为打印需要转递的资源
4.3.2 JS/ETS API 示例

使用JS/ETS开发框架开发鸿蒙应用可以参考此方法,该方法详细讲述了如何跳转华为打印以及如何传递需要打印的资源到华为打印中。

  • 打印预览APP沙盒中的文件
import featureAbility from '@ohos.ability.featureAbility'
import wantConstant from '@ohos.ability.wantConstant'
  featureAbility.startAbility({ want: {
                  bundleName: 'com.huawei.printservice',
                  action: "android.intent.action.VIEW",
                  flags: wantConstant.Flags.FLAG_NOT_OHOS_COMPONENT | 0x00000001,
                  "type": "image/*",
                  uri: "dataability:///ohos.data.file.FileAbility/root-path/storage/emulated/0/Android/data/com.ohos.clienttest/files/Documents/icon.png",
                  parameters: { "ActionType": "Print" }
                } }).then(() => {
                  console.info(`${TAG} start success`)
                }).catch(() => {
                  console.info(`${TAG} start fail`)
                })

uri中的“storage/emulated/0/Android/data/com.ohos.clienttest/files/Documents/icon.png” 为图片在应用沙盒中的实际存储路径,开发者可以根据文件在沙盒中的实际路径进行拼接。

附录:Data Ability基本概念

...全文
12 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

527

社区成员

发帖
与我相关
我的任务
社区描述
OpenHarmony开发者社区
其他 企业社区
社区管理员
  • csdnsqst0025
  • shewaliujingli
  • BaoWei
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧