鸿蒙---图片上传/下载

1,339 阅读3分钟

鸿蒙---上传/下载


回顾

在前两篇的记录中,对于鸿蒙的UI搭建基本熟悉,包括普通页面的布局,常用组件,轮播图,列表等 。 也提到了鸿蒙提供的几种弹窗方式(提示警告性弹窗,列表选择,日期时间选择,文本选择等)。 还有权限配置,查询,授权的相关代码。

再第一篇中,还记录了http网络请求,这个请求相较于Android提供的API,还是好用很多的,与小程序 提供的API倒是很像。基本没什么难点,就没有过多的记录。常见的GET请求,怎么完成就不说了, 再POST请求中,需要根据请求体的类型,拼接对应的请求体参数。比如 ‘application/x-www-form-urlencoded’ 表单提交,用 ‘&’ 拼接各个请求参数。

在请求中,还有上传下载及WebView未涉及到,将会再这篇文章记录。

本篇上传就以选择图片开始。

选择图片

  1. 从相册获取

    鸿蒙有提供PhotoViewPicker、DocumentViewPicker、AudioViewPicker用于选择用户文件。

       showPhotoPicker() {
          let photoPicker = new picker.PhotoViewPicker()
    
          photoPicker.select({
             maxSelectNumber: 2,
             MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE
          }).then(result => {
             console.log("upload333 image::",this.imagePath)
             if (result.photoUris.length > 0) {
                this.imagePath = result.photoUris[0]
    
                console.log("upload111 image::",this.imagePath)
             }
             console.log("select path:" + result.photoUris[0] + "__origin:" + result.isOriginalPhoto)
          }).catch(err => {
             console.log("error::",err);
          })
     }
    
  2. 拍照

    调用系统相机进行拍照并返回。参考UIAbility组件间交互,此处为隐式Want启动。

       let context = getContext(this) as common.UIAbilityContext
       context.startAbilityForResult({
         uri: '',
         action: wantConstant.Action.ACTION_IMAGE_CAPTURE,
         parameters: {}
       }).then(result => {
         console.log("take photo result: ", result.resultCode + ":" + result.want.uri)
         if (result.resultCode == 0 && result.want && result.want.uri) {
           this.imagePath = result.want.uri
         }
     }).catch(err => {
       console.log("take photo err: ", err.message)
     })
    

文件读写

因为鸿蒙的上传下载,暂只支持应用沙箱特定目录下进行,所以,读取到的图片,需要先拷贝到 应用cacheDir目录下。

当前上传应用文件功能,仅支持上传应用缓存文件路径(cacheDir)下的文件。

当前网络资源文件仅支持下载至应用文件目录。

  1. 文件读取

       let file = fs.openSync(this.imagePath,fs.OpenMode.READ_ONLY)
    
       let fileStat = fs.statSync(file.fd)  // 获取文件属性
       let buf = new ArrayBuffer(fileStat.size) // 根据文件大小 构建文件缓冲区
     
       let readSize = 0
       let n = fs.readSync(file.fd,buf,{offset: readSize}) // offset 起始偏移量
    
       fs.closeSync(file.fd)  // 用完记得关闭文件
    
  2. 文件写入

       // 获取应用文件路径
       let context = getContext(this) as common.UIAbilityContext;
       let filesDir = context.cacheDir;
    
       // 新建并打开文件
       let file = fs.openSync(filesDir + '/test.jpg', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
       // 写入一段内容至文件
       let writeLen = fs.writeSync(file.fd, buf);
       // 关闭文件
       fs.closeSync(file);
    

上传

    request.uploadFile(context, {
     url: url,
     header: {
       'Accept': 'application/json'
     },
     method: 'POST',
     files: [
       {
         filename: 'jpgTest',
         name: 'nnn',
         uri: file, // 文件路径 internal://cache/test.jpg
         type: 'jpg'
       }
     ],
     data: [
         {
           name: 'test',
           value: '123',
         }
     ]
   }, (err, data) => {
     console.log('upload::::',err)
     if (err) {
       console.error('Failed to request the upload. Cause: ' + JSON.stringify(err));
       return;
     }
     data.on('progress',progressCallback) // 上传进度监听
   })

下载

   request.downloadFile(context,{
     url: url,
     filePath: context.filesDir + '/' + name,
     background: true
   })

惊喜的是鸿蒙提供的API中,有个background属性,可以直接开启状态栏通知。

Web网页加载

  1. web组件
       Web({
         src: $rawfile('privacy.html'),
         controller: this.webController
       })
         .javaScriptAccess(true) // 默认开启
         .darkMode(WebDarkMode.On)  // 默认关闭深色模式  Auto跟随系统
         .forceDarkAccess(false)  // 强制开启深色模式
         .geolocationAccess(true) // 开启地理位置权限 默认开启
         .onShowFileSelector((event) => { // 上传文件
           event.result.handleFileList([])  // 传递文件路劲
           return true
         })
         .onUrlLoadIntercept((event) => {  // url 加载拦截
           let url = event.data as string
           // 处理url
           return false // true 阻止此次加载
         })
         .onGeolocationShow(event => {
           // 回调 第二个参数: 允许请求地理位置  第三个参数:保存权限状态到系统中
           event.geolocation.invoke(event.origin,true,false)
         })
         .javaScriptProxy({
           object: this.obj,
           name: 'objName',
           methodList: ['test'],
           controller: this.webController
         })
    
  2. webController
       let webController : webview.WebviewController = new webview.WebviewController();
    
  3. 两端通信
    • 应用调用JavaScript
         this.webController.runJavaScript('test()') // 执行javaScript 
      
    • JavaScript调用应用
        // 也可以直接再Web组件初始化时调用
        this.webController.registerJavaScriptProxy(this.obj,"objName",['test'])
        this.webController.refresh() // 注册时 注意调用refresh 刷新