基于Picker的受限权限适配方案

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

类型

受限权限

使用的picker

音频

ohos.permission.READ_AUDIO,ohos.permission.WRITE_AUDIO

AudioViewPicker

文件

ohos.permission.READ_DOCUMENT,ohos.permission.WRITE_DOCUMENT

DocumentViewPicker

照片

ohos.permission.READ_IMAGEVIDEO,ohos.permission.WRITE_IMAGEVIDEO

PhotoViewPicker

联系人

ohos.permission.READ_CONTACTS

Contacts Picker

相机

ohos.permission.CAMERA

Camera 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替代,使用方式请参考:使用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%')
  }
}

 

<think>好的,我现在需要解决用户在uni-app中使用uni-file-picker组件时,在企业微信环境下遇到不支持某个功能的问题。根据用户提供的引用内容,我需要先了解现有的问题和可能的解决方案。 首先,用户提到了微信开发者工具更新导致的上传问题,解决方法是回退基础库版本[^1]。这可能意味着环境兼容性是一个常见问题。不过现在的问题是企业微信环境下uni-file-picker不支持某个功能,需要替代方案或更新说明。 接下来,参考引用[3],用户提到uni-file-picker需要依赖uniCloud服务空间,如果超出免费额度会导致链接失效[^3]。这可能意味着在企业微信中,如果服务空间配置不当,也会出现问题。需要检查服务空间的配置是否适用于企业微信环境。 用户的需求是寻找替代方案或者官方是否有更新说明。可能的解决方案包括: 1. **检查uni-file-picker的兼容性文档**:查看uni-app官方文档是否有说明企业微信的支持情况,或者是否有已知的问题和解决方案。如果官方有更新,可能需要升级uni-app版本或相关依赖。 2. **使用原生企业微信API**:如果uni-file-picker在企业微信中确实不支持,可能需要调用企业微信的原生API来实现文件上传功能。例如,使用wx.chooseMessageFile等接口,然后通过uni.uploadFile进行上传。 3. **自定义上传组件**:根据引用[2]中的代码示例,用户已经使用了uni-file-picker,但如果该组件不支持,可能需要自行实现一个上传组件,利用uni.chooseImage或企业微信特定的API选择文件,然后处理上传逻辑。 4. **服务空间配置检查**:确保uniCloud服务空间在企业微信环境中正确配置,并且没有超出免费额度,避免链接失效的问题[^3]。 5. **社区或官方支持**:查看uni-app社区或企业微信开发者论坛,是否有其他开发者遇到类似问题,并找到临时解决方案或官方回复。 需要注意的是,企业微信和普通微信的环境可能存在差异,特别是在API支持和权限配置上。因此,直接使用uni-file-picker可能遇到兼容性问题,需要针对企业微信进行适配。 可能的步骤验证: - 确认uni-file-picker在企业微信中的具体不支持的功能是什么。例如,是否无法选择文件,上传失败,还是其他问题。 - 如果是API限制,可能需要使用企业微信提供的JSAPI来处理文件选择。 - 检查uni-app的更新日志,查看是否有针对企业微信的修复或功能支持。 - 如果必须使用uni-file-picker,可能需要等待官方更新,或者提交反馈给uni-app团队。 总结,解决方案可能涉及使用替代API、自定义组件或调整服务配置。需要具体问题具体分析,但根据现有信息,建议尝试使用企业微信的原生API作为替代方案,并确保服务空间配置正确。</think>关于uni-app中`uni-file-picker`在企业微信环境下功能受限的解决方案如下: --- ### 问题分析 企业微信环境与普通微信小程序存在接口差异,可能导致`uni-file-picker`某些功能无法直接使用(如文件选择或上传)。根据引用内容,可能的原因包括: 1. 企业微信JSAPI限制或兼容性问题; 2. `uni-file-picker`依赖的uniCloud服务空间配置问题[^3]; 3. 基础库版本或运行环境差异(类似微信开发者工具更新引发的问题)[^1]。 --- ### 解决方案 #### 方案一:使用企业微信原生API替代 1. **通过企业微信JSAPI选择文件** 调用企业微信的`wx.chooseMessageFile`或`wx.chooseImage`实现文件选择: ```javascript wx.chooseMessageFile({ count: 1, type: 'all', success: (res) => { const file = res.tempFiles[0]; uni.uploadFile({ url: 'YOUR_UPLOAD_URL', filePath: file.path, name: 'file', success: (uploadRes) => { console.log('上传成功', uploadRes.data); } }); } }); ``` 2. **自定义上传逻辑** 将选择的文件通过`uni.uploadFile`发送至服务器,替代`uni-file-picker`的自动上传功能[^2]。 --- #### 方案二:检查uniCloud服务空间配置 1. 确保uniCloud服务空间未超限且配置正确(引用提到超限会导致链接失效); 2. 若需长期使用,建议绑定付费套餐或自建存储服务。 --- #### 方案三:环境适配与降级 1. **调整基础库版本** 参考微信开发者工具基础库降级方法[^1],检查企业微信客户端版本是否支持,必要时联系企业微信管理员升级环境; 2. **条件编译适配** 在代码中通过条件编译区分企业微信和普通微信环境: ```javascript // #ifdef QYWX 使用企业微信API // #endif // #ifdef MP-WEIXIN 使用uni-file-picker // #endif ``` --- #### 方案四:关注官方更新 1. 查看uni-app官方[更新日志](https://ask.dcloud.net.cn/),确认是否有针对企业微信的适配; 2. 在[DCloud社区](https://ask.dcloud.net.cn/)提交问题,获取官方支持。 --- ### 替代方案示例代码 ```html <template> <button @click="chooseFile">选择文件</button> </template> <script> export default { methods: { chooseFile() { // 企业微信环境选择文件 // #ifdef QYWX wx.chooseMessageFile({ count: 1, success: (res) => { this.uploadFile(res.tempFiles[0].path); } }); // #endif // 普通微信环境使用uni-file-picker // #ifdef MP-WEIXIN // 原有uni-file-picker逻辑 // #endif }, uploadFile(filePath) { uni.uploadFile({ url: 'https://your-server.com/upload', filePath: filePath, name: 'file', success: (res) => { console.log('上传成功', res.data); } }); } } }; </script> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值