鸿蒙开发5.0【Picker的受限权限适配方案】

Picker由系统独立进程实现,应用可以通过拉起Picker组件,用户在Picker上选择对应的资源(如图片、文档等),应用可以获取Picker返回的结果。

类型受限权限使用的picker
音频ohos.permission.READ_AUDIO,ohos.permission.WRITE_AUDIOAudioViewPicker
文件ohos.permission.READ_DOCUMENT,ohos.permission.WRITE_DOCUMENTDocumentViewPicker
照片ohos.permission.READ_IMAGEVIDEO,ohos.permission.WRITE_IMAGEVIDEOPhotoViewPicker
联系人ohos.permission.READ_CONTACTSContacts Picker
相机ohos.permission.CAMERACamera Picker
扫码ohos.permission.CAMERA扫码Picker
卡证识别ohos.permission.CAMERA卡证识别Picker
文档扫描ohos.permission.CAMERA文档扫描Picker

目前支持的Picker组件有:

  • 音频Picker(AudioViewPicker):选择、保存音频文件。
  • 文件Picker(DocumentViewPicker):选择、保存文档文件。
  • 照片Picker(PhotoViewPicker):选择、保存图片文件。
  • 联系人Picker(Contacts Picker):选择联系人。
  • 相机Picker (Camera Picker):拍照、录制。
  • 扫码Picker:扫码。
  • 卡证识别Picker:识别并提取卡证信息。
  • 文档扫描Picker:拍摄文档并转化为高清扫描件。
  • 投播组件Picker:可用于将音视频资源投放到其它设备播放。

音频Picker

使用音频Picker(AudioViewPicker)可访问、保存用户公共目录的音频文件。

  • 在应用需要申请权限ohos.permission.READ_AUDIO以访问用户公共目录的音频文件时,可以使用FilePicker中的AudioViewPicker替代

    async function example13() {
      try {
        let audioSelectOptions = new picker.AudioSelectOptions();
        let audioPicker = new picker.AudioViewPicker();
        audioPicker.select(audioSelectOptions).then((audioSelectResult: Array<string>) => {
          console.info('AudioViewPicker.select successfully, audioSelectResult uri: ' + JSON.stringify(audioSelectResult));
        }).catch((err: BusinessError) => {
          console.error('AudioViewPicker.select failed with err: ' + JSON.stringify(err));
        });
      } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error('AudioViewPicker failed with err: ' + JSON.stringify(err));
      }
    }
    
  • 在应用需要申请权限ohos.permission.WRITE_AUDIO以修改用户公共目录的音频文件时,可以使用FilePicker中的AudioViewPicker替代

    async function example16() {
      try {
        let audioSaveOptions = new picker.AudioSaveOptions();
        audioSaveOptions.newFileNames = ['AudioViewPicker01.mp3'];
        let audioPicker = new picker.AudioViewPicker();
        audioPicker.save(audioSaveOptions).then((audioSaveResult: Array<string>) => {
          console.info('AudioViewPicker.save successfully, audioSaveResult uri: ' + JSON.stringify(audioSaveResult))
        }).catch((err: BusinessError) => {
          console.error('AudioViewPicker.save failed with err: ' + JSON.stringify(err));
        });
      } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error('AudioViewPicker failed with err: ' + JSON.stringify(err));
      }
    }
    
  • save返回的uri权限是读写权限,可以根据结果集中uri进行文件读写等操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,使用类似一个按钮去触发打开文件。使用fs.openSync接口,通过uri打开这个文件得到fd。这里需要注意接口权限参数是fs.OpenMode.READ_WRITE。最后再将通过fs.read读取到selecturi的音频文件的buffer,再通过fd使用fs.writeSync接口将buffer写入这个音频文件,编辑修改完成后关闭fd。

    Button('写入音频')
      .backgroundColor('#0D9FFB')
      .fontSize(20)
      .fontColor('#FFFFFF')
      .fontWeight(FontWeight.Normal)
      .align(Alignment.Center)
      .type(ButtonType.Capsule)
      .width('90%')
      .height(40)
      .margin({ top: 5, bottom: 5 })
      .onClick(() => {
        let file = fs.openSync(selecturi, fs.OpenMode.READ_WRITE)
        let file1 = fs.openSync(saveuri, fs.OpenMode.READ_WRITE)
        let arrayBuffer = new ArrayBuffer(5120000);
        fs.read(file.fd, arrayBuffer)
        fs.writeSync(file1.fd, arrayBuffer);
        fs.close(file1)
        fs.close(file)
      })
    

文件Picker

使用文件Picker(DocumentViewPicker)可访问、保存公共目录中非媒体类型的文件。

  • 在应用需要申请权限ohos.permission.READ_DOCUMENT以访问用户公共目录中非媒体类型的文件时,可以使用FilePicker中的DocumentViewPicker替代

    async function example07() {
      try {
        let documentSelectOptions = new picker.DocumentSelectOptions();
        let documentPicker = new picker.DocumentViewPicker();
        documentPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => {
          console.info('DocumentViewPicker.select successfully, documentSelectResult uri: ' + JSON.stringify(documentSelectResult));
        }).catch((err: BusinessError) => {
          console.error('DocumentViewPicker.select failed with err: ' + JSON.stringify(err));
        });
      } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error('DocumentViewPicker failed with err: ' + JSON.stringify(err));
      }
    }
    
  • 在应用需要申请权限ohos.permission.WRITE_DOCUMENT以修改用户公共目录中非媒体类型的文件时,可以使用FilePicker中的DocumentViewPicker替代

    async function example10() {
      try {
        let documentSaveOptions = new picker.DocumentSaveOptions();
        documentSaveOptions.newFileNames = ['DocumentViewPicker01.txt'];
        let documentPicker = new picker.DocumentViewPicker();
        documentPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
          console.info('DocumentViewPicker.save successfully, documentSaveResult uri: ' + JSON.stringify(documentSaveResult));
        }).catch((err: BusinessError) => {
          console.error('DocumentViewPicker.save failed with err: ' + JSON.stringify(err));
        });
      } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error('DocumentViewPicker failed with err: ' + JSON.stringify(err));
      }
    }
    
  • save返回的uri权限是读写权限,可以根据结果集中uri进行文件读写等操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,使用类似一个按钮去触发打开文件。使用fs.openSync接口,通过uri打开这个文件得到fd。这里需要注意接口权限参数是fs.OpenMode.READ_WRITE。最后通过fd使用fs.writeSync接口对这个文件进行编辑修改,编辑修改完成后关闭fd。

    Button('写入文件')
      .backgroundColor('#0D9FFB')
      .fontSize(20)
      .fontColor('#FFFFFF')
      .fontWeight(FontWeight.Normal)
      .align(Alignment.Center)
      .type(ButtonType.Capsule)
      .width('90%')
      .height(40)
      .margin({ top: 5, bottom: 5 })
      .onClick(() => {
        let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
        console.info('file fd: ' + file.fd);
        let writeLen = fs.writeSync(file.fd, 'hello, world');
        console.info('write data to file succeed and size is:' + writeLen);
        fs.closeSync(file);
      })
    

照片Picker

使用照片Picker(PhotoViewPicker)可访问、保存公共目录的图片或视频文件。

  • 在应用需要申请权限ohos.permission.READ_IMAGEVIDEO以访问用户公共目录的图片或视频文件时,可以使用PhotoViewPicker替代

    async function example01() {
      try {
        let photoSelectOptions = new picker.PhotoSelectOptions();
        photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
        photoSelectOptions.maxSelectNumber = 5;
        let photoPicker = new picker.PhotoViewPicker();
        photoPicker.select(photoSelectOptions).then((photoSelectResult: picker.PhotoSelectResult) => {
          console.info('PhotoViewPicker.select successfully, photoSelectResult uri: ' + JSON.stringify(photoSelectResult));
        }).catch((err: BusinessError) => {
          console.error('PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
        });
      } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error('PhotoViewPicker failed with err: ' + JSON.stringify(err));
      }
    }
    
  • 在应用需要申请权限ohos.permission.WRITE_IMAGEVIDEO以保存用户公共目录的图片或视频文件时,可以使用安全控件替代

    @Entry
    @Component
    struct Index {
      @State message: string = 'Hello World'
      @State saveButtonOptions: SaveButtonOptions = {
        icon: SaveIconStyle.FULL_FILLED,
        text: SaveDescription.SAVE_IMAGE,
        buttonType: ButtonType.Capsule
      } // 设置安全控件按钮属性
    
      build() {
        Row() {
          Column() {
            Text(this.message)
              .fontSize(50)
              .fontWeight(FontWeight.Bold)
            SaveButton(this.saveButtonOptions)// 创建安全控件按钮
              .onClick(async (event, result: SaveButtonOnClickResult) => {
                if (result == SaveButtonOnClickResult.SUCCESS) {
                  try {
                    let context = getContext();
                    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
                    // 需要确保fileUri对应的资源存在
                    let fileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';
                    let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest =
                      photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri);
                    await phAccessHelper.applyChanges(assetChangeRequest);
                    console.info('createAsset successfully, uri: ' + assetChangeRequest.getAsset().uri);
                  } catch (err) {
                    console.error(`create asset failed with error: ${err.code}, ${err.message}`);
                  }
                } else {
                  console.error('SaveButtonOnClickResult create asset failed');
                }
              })
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    

联系人Picker

使用联系人Picker(Contacts Picker)可读取联系人数据。

在应用需要申请权限ohos.permission.READ_CONTACTS以读取联系人数据时,可以使用Contacts Picker替代

async function demo() {
  contact.selectContacts((err: BusinessError, data) => {
    if (err) {
      console.log(`selectContacts callback: err->${JSON.stringify(err)}`);
      return;
    }
    console.log(`selectContacts callback: success data->${JSON.stringify(data)}`);
  });
}

相机Picker

使用相机Picker (Camera Picker)可实现拍照、录制。

在应用需要申请权限ohos.permission.CAMERA以使用相机时,可以使用Camera Picker替代

async function demo1() {
  try {
    let pickerProfile: picker.PickerProfile = {
      cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
    };
    let pickerResult: picker.PickerResult = await picker.pick(mContext,
      [picker.PickerMediaType.PHOTO, picker.PickerMediaType.VIDEO], pickerProfile);
    console.log("the pick pickerResult is:" + JSON.stringify(pickerResult));
  } catch (error) {
    let err = error as BusinessError;
    console.error(`the pick call failed. error code: ${err.code}`);
  }
}

扫码Picker

使用扫码Picker可调用相机,实现默认界面扫码。

在应用需要申请权限ohos.permission.CAMERA以使用相机扫码时,可以使用扫码Picker替代

// 定义扫码参数options
let options: scanBarcode.ScanOptions = {
  scanTypes: [scanCore.ScanType.ALL],
  enableMultiMode: true,
  enableAlbum: true
};
// 可调用getContext接口获取当前页面关联的UIAbilityContext
scanBarcode.startScanForResult(getContext(this), options).then((result: scanBarcode.ScanResult) => {
  // 收到扫码结果后返回
  hilog.info(0x0001, '[Scan CPSample]', `Succeeded in getting ScanResult by promise with options, result is ${JSON.stringify(result)}`);
}).catch((error: BusinessError) => {
  hilog.error(0x0001, '[Scan CPSample]',
    `Failed to get ScanResult by promise with options. Code:${error.code}, message: ${error.message}`);
});

卡证识别Picker

使用卡证识别Picker可调用相机,识别各类证件并提取卡证信息。

在应用需要申请权限ohos.permission.CAMERA以使用相机识别卡证时,可以使用卡证识别Picker替代

Stack({ alignContent: Alignment.Top }) {
  CardRecognition({
    // 此处选择身份证类型作为示例
    supportType: CardType.CARD_ID,
    callback: ((params: CallbackParam) => {
      hilog.info(0x0001, TAG, `params code: ${params.code}`)
      hilog.info(0x0001, TAG, `params cardType: ${params.cardType}`)
      hilog.info(0x0001, TAG, `params cardInfo front: ${JSON.stringify(params.cardInfo?.front)}`)
      hilog.info(0x0001, TAG, `params cardInfo back: ${JSON.stringify(params.cardInfo?.back)}`)
    })
  })

文档扫描Picker

使用文档扫描Picker可调用相机,拍摄文档并转化为高清扫描件。

@Component
struct DocDemoPage {
  @State docImageUris: string[] = []
  private docScanConfig = new DocumentScannerConfig()

  aboutToAppear() {
    this.docScanConfig.supportType = [DocType.DOC, DocType.SHEET]
    this.docScanConfig.isGallerySupported = true
    this.docScanConfig.editTabs = []
    this.docScanConfig.maxShotCount = 3
    this.docScanConfig.defaultFilterId = FilterId.ORIGINAL
    this.docScanConfig.defaultShootingMode = ShootingMode.MANUAL
    this.docScanConfig.isShareable = true
    this.docScanConfig.originalUris = []
  }

  build() {
    Stack({ alignContent: Alignment.Top }) {
      DocumentScanner({
        scannerConfig: this.docScanConfig,
        onResult: (code: number, saveType: SaveOption, uris: string[]) => {
          hilog.info(0x0001, TAG, `result code: ${code}, save: ${saveType}`)
          uris.forEach(uriString => {
            hilog.info(0x0001, TAG, `uri: ${uriString}`)
          })
          this.docImageUris = uris
        }
      })
        .size({ width: '100%', height: '100%' })
    }
    .width('100%')
    .height('100%')
  }
}

投播组件Picker

使用投播组件Picker,可用于将音视频资源投放到其它设备播放。

@Component
struct Index {
  private onStateChange(state: AVCastPickerState) {
    if (state == AVCastPickerState.STATE_APPEARING) {
      console.log('The picker starts showing.')
    } else if (state == AVCastPickerState.STATE_DISAPPEARING) {
      console.log('The picker finishes presenting.')
    }
  }

  build() {
    Row() {
      Column() {
        AVCastPicker({ normalColor: Color.Red, activeColor: Color.Blue, onStateChange: this.onStateChange })
          .width('40vp')
          .height('40vp')
          .border({ width: 1, color: Color.Red })
      }.height('50%')
    }.width('50%')
  }
}

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

2

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!
3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/873128.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java JVM 垃圾回收算法详解

Java 虚拟机&#xff08;JVM&#xff09;是运行 Java 应用程序的核心&#xff0c;它的垃圾回收&#xff08;Garbage Collection, GC&#xff09;机制是 JVM 中非常重要的一个部分。垃圾回收的主要任务是自动管理内存&#xff0c;回收那些不再被使用的对象&#xff0c;从而释放内…

linux编译器——gcc/g++

1.gcc linux上先要安装&#xff0c; sudo yum install gcc gcc --version 可以查看当前的版本 &#xff0c;我们默认安装的是4.8.5的版本&#xff0c;比较低&#xff0c; gcc test.c -stdc99 可以使他支持更高版本的c标准 -o 可以殖指明生成文件的名字&#xff0c;可以自己…

自用NAS系列1-设备

拾光坞 拾光坞多账号绑定青龙面板SMBWebdav小雅alist下载到NASDocker安装迅雷功能利用qBittorrentEEJackett打造一站式下载工具安装jackett插件 外网访问内网拾光客户端拾光穿透公网ipv6路由器配置ipv6拾光坞公网验证拾光坞域名验证 拾光坞 多账号绑定 手机注册拾光坞账号&am…

解决面板安装Node.js和npm后无法使用的问题

使用面板&#xff08;BT&#xff09;安装Node.js和npm后&#xff0c;可能会遇到如下问题&#xff1a;即使成功安装了Node.js和npm&#xff0c;服务器仍提示“未安装”&#xff0c;在命令行中使用 node -v 或 npm -v 也没有任何响应。这种问题通常是由于环境变量配置错误或路径问…

设置Virtualbox虚拟机共享文件夹

由于工作环境的原因&#xff0c;选择Virtualbox的方式安装虚拟操作系统&#xff0c;常用的操作系统为ubuntu&#xff0c;不知道道友是否也曾遇到这样的问题&#xff0c;就是虚拟机和主机进行文件拖拽的时候&#xff0c;会因为手抖造成拖拽失败&#xff0c;虚拟机界面显示大个的…

触想全新Z系列工控机扩展IIoT应用潜能

8月31日&#xff0c;触想重磅推出全新Z系列高性能、扩展型工控机——TPC05/06/07-WIPC&#xff0c;提供标准版/双卡槽/四卡槽3款机型选择。 作为边缘计算、机器视觉、AI智能和工业应用的理想机型&#xff0c;Z系列工控机支持Intel第12/13/14代Core™ i3/i5/i7/i9处理器&#xf…

鸿蒙Next-拉起支付宝的三种方式——教程

鸿蒙Next-拉起支付宝的三种方式——教程 鸿蒙Next系统即将上线&#xff0c;应用市场逐渐丰富、很多APP都准备接入支付宝做支付功能&#xff0c;目前来说有三种方式拉起支付宝&#xff1a;通过支付宝SDK拉起、使用OpenLink拉起、传入支付宝包名使用startAbility拉起。以上的三种…

顶踩Emlog插件源码

源码介绍 顶踩Emlog插件源码 前些天看到小刀娱乐网的文章页面有了一些变化&#xff0c;那就是增加了一个有价值/无价值的顶踩按钮。 样式也是非常的好看 再加上两个表情包是非常的有趣。 写到了Emlog系统&#xff0c;效果如上图。 如何使用&#xff1a; 需要在echo_log.…

(二)ASP.NET Core WebAPI项目的启动地址设置

上一篇介绍了ASP.NET Core WebAPI项目创建&#xff0c;可参考&#xff1a; 1.webAPI的访问地址 1) 启动时&#xff0c;选择CoreWebAPI(项目名称)运行项目 可以看到打开浏览器后的地址是&#xff1a;applicationUrl"\"launchUrl 2) 启动时&#xff0c;选择IIS Expre…

ELK学习笔记(一)——使用K8S部署ElasticSearch8.15.0集群

一、下载镜像 #1、下载官方镜像 docker pull elasticsearch:8.15.0 #2、打新tag docker tag elasticsearch:8.15.0 192.168.9.41:8088/new-erp-common/elasticsearch:8.15.0 #3、推送到私有仓库harbor docker push 192.168.9.41:8088/new-erp-common/elasticsearch:8.15.0二、…

一文理解粒子滤波

0. 粒子滤波流程 之前学习记录的文档&#xff0c;这里也拿出来分享一下~ 基本原理&#xff1a;随机选取预测域的 N NN 个点&#xff0c;称为粒子。以此计算出预测值&#xff0c;并算出在测量域的概率&#xff0c;即权重&#xff0c;加权平均就是最优估计。之后按权重比例&…

英文翻译工具怎么选?这4款值得收藏。

英语作为国际通用语言&#xff0c;在我们的日常生活中一直有着很重要的地位&#xff0c;往大了说可以促进国际交流&#xff0c;实现文化传播&#xff1b;往小了说&#xff0c;可以解决很多生活中的小问题。但是在很多情况下英文仍旧是我们一个语言障碍&#xff0c;所以好的翻译…

网络学习-eNSP配置ACL

AR1路由器配置 <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]undo info-center enable Info: Information center is disabled. [Huawei]interface gigabitethernet 0/0/0 [Huawei-GigabitEthernet0/0/0]ip address 192.168.2.254 24 …

MapSet之相关概念

系列文章&#xff1a; 1. 先导片--Map&Set之二叉搜索树 2. Map&Set之相关概念 目录 1.搜索 1.1 概念和场景 1.2 模型 2.Map的使用 2.1 关于Map的说明 2.2 关于Map.Entry的说明 2.3 Map的常用方法说明 3.Set的说明 3.1关于Set说明 3.2 常见方法说明 1.搜…

windows 环境下搭建mysql cluster 集群详细步骤

1、环境准备 下载mysql集群版本&#xff0c;我这里下载的是mysql-cluster-8.0.39-winx64 https://dev.mysql.com/downloads/cluster/ 2、创建配置文件 mysql集群版本下载以后解压后目录如下&#xff0c;创建配置文件 config.ini(集群配置文件&#xff0c;my.ini mysql配置…

【大模型基础】P0 大模型之路 —— 窗外灯火阑珊

目录 前言 —— 本系列博文内容何谓语言语言、图形符号、编码与解码基于规则、基于统计 语言模型&#xff08;Language Model&#xff09;预训练语言模型BERT 与 GPT 大模型范式预训练 微调大模型提示 / 指令 OpenAI 若一个语言模型亮起一盏灯&#xff0c;你会发现&#xff0c…

三维布尔运算对不规范几何数据的兼容处理

1.前言 上一篇文章谈过八叉树布尔运算&#xff0c;对于规范几何数据的情况是没有问题的。 在实际情况中&#xff0c;由于几何数据来源不一&#xff0c;处理和生成方式不一&#xff0c;我们无法保证进行布尔运算的几何数据都是规范的&#xff0c;对于不规范情况有时候也有需求…

vue3写一个无限树形菜单,递归组件

原本使用element plus的el-tree&#xff0c;可是他的UI不匹配&#xff0c;狠难改成自己想要的&#xff0c;所以只能自己去写一个&#xff0c;做法&#xff1a;使用递归组件 效果 组件代码itemDir.vue // itemDir.vue<template><div><ul v-for"node in li…

【AcWing】852. spfa判断负环

#include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std;const int N 1e510;int n,m; int h[N],w[N],e[N],ne[N],idx; int dist[N],cnt[N];//cnt存最短路径的边数 bool st[N];void add(int a,int b,int c){e[…

前端:Vue3学习-2

前端:Vue3学习-2 1. vue3 新特性-defineOptions2. vue3 新特性-defineModel3. vue3 Pinia-状态管理工具4. Pinia 持久化插件 -> pinia-plugin-persistedstate 1. vue3 新特性-defineOptions 如果要定义组件的name或其他自定义的属性&#xff0c;还是得回归原始得方法----再…