【鸿蒙实战开发】基于Picker的受限权限适配方案

179 篇文章 0 订阅
179 篇文章 2 订阅

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

目前支持的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替代,使用方式请参考:​​使用Picker选择媒体库资源​​。
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替代,使用方式请参考:​​cameraPicker.pick​​。

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可调用相机,拍摄文档并转化为高清扫描件。

在应用需要申请权限ohos.permission.CAMERA以使用相机扫描文档时,可以使用文档扫描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%') 
  } 
}

写在最后

●如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
●点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
●关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
●更多鸿蒙最新技术知识点,请移步前往小编:https://gitee.com/

在这里插入图片描述

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值