1

最近老板给我安排了一个新任务:要把鸿蒙系统的相机功能集成到我们的应用里,让用户可以直接用手机拍照或者录制视频。当时我一看这个需求,心里有点发毛,因为鸿蒙的相机模块我完全没接触过。但是不管怎么样,既然任务来了,那就只能硬着头皮上,学习是开发者的本职工作嘛。其实,每次遇到这种完全陌生的技术,我心里总是有点忐忑,但也有一丝兴奋,因为这代表着新的挑战和学习的机会。

image.png

初步了解与计划

首先,我赶紧翻看了一下鸿蒙的官方文档,找到了相机相关的接口。鸿蒙的相机功能叫做“Camera Picker”,可以让应用拉起系统相机来拍照或者录像。这些接口从 API 11 开始支持,但我这次需要用的版本是 API 12,也就是最新的元服务 API。我的目标是让用户可以通过应用直接调用系统相机,并根据需要选择拍照或录像模式。

image.png

在研究文档的过程中,我也参考了一些社区开发者的经验分享,了解了一些相机模块集成中可能会遇到的坑。很多时候,官方文档会写得比较简洁,具体实现中还是会有一些细节需要摸索。于是我在笔记本上写下了几个关键步骤,包括模块导入、上下文获取、相机配置和异常处理等等,把整个任务拆解成一个个小目标,逐步攻克。

开始集成相机功能

首先,我们需要导入相机模块,这样才能在代码中使用鸿蒙提供的这些相机功能。导入模块的代码如下:

import { cameraPicker as picker } from '@kit.CameraKit';

然后我们就可以使用 picker.pick() 这个接口来拉起系统相机。这个接口需要三个参数:应用上下文 context,媒体类型 mediaTypes,以及相机配置 pickerProfile。其中,mediaTypes 决定了相机是进入拍照模式还是录像模式,而 pickerProfile 可以用来配置相机的一些基本设置,比如是使用前置摄像头还是后置摄像头。

写代码的时候,我遇到的第一个问题就是如何正确获取上下文 context。由于相机功能需要在应用的界面能力(UIAbility)中调用,所以我需要确保从当前页面获取上下文对象。以下是完整的代码示例:

import { cameraPicker as picker } from '@kit.CameraKit';
import { camera } from '@kit.CameraKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
let mContext = getContext(this) as common.Context;

async function demo() {
  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}`);
  }
}

代码分析与开发过程中的挑战

在这个代码里,我首先定义了一个 pickerProfile 对象,用于配置相机的基本设置,比如这里我选择了后置摄像头(CAMERA_POSITION_BACK)。接着,我调用了 picker.pick() 方法,传入了上下文 mContext、媒体类型数组以及相机配置。

mediaTypes 数组包含了两个枚举值:picker.PickerMediaType.PHOTO 和 picker.PickerMediaType.VIDEO,这意味着用户在调用相机时可以选择拍照或者录像模式。如果操作成功,picker.pick() 会返回一个 pickerResult 对象,其中包含了拍摄结果的信息,比如结果的 URI 地址、媒体类型等等。最后,我把这个结果打印出来,方便调试。

在开发过程中,我踩了一个比较深的坑,那就是在调试模式下调用相机接口会显示异常。后来我才发现,文档中明确说明只有在发布模式(release mode)下,这个接口才会正常工作,而在调试模式(debug mode)下是无法正常拉起相机的。所以在调试阶段,我不得不先模拟一些返回结果,确保后续逻辑可以顺利进行。这一点让我认识到,认真阅读文档并理解其中的细节是多么重要,尤其是对于系统级的功能开发。

另外一个挑战是上下文的正确获取。鸿蒙系统的开发和传统的 Android 开发有所不同,在获取上下文时有自己的一些规则和限制。如果上下文获取不对,就会导致相机无法拉起。刚开始的时候,我尝试了几次都没成功,经过反复查阅文档和调试,最终才找到了正确的调用方式。

异常处理与用户体验的考虑

在调用相机功能的时候,难免会遇到各种异常情况,比如用户拒绝授权、相机被其他应用占用等等。所以我在代码里加入了异常捕获逻辑,确保即使调用失败,也能获取到具体的错误信息并进行相应的处理。

比如在代码中,catch 部分捕获了所有可能的异常,并打印出了错误码(err.code)。通过这些错误码,我可以快速定位问题所在,查看相应的文档来解决问题。在处理这些错误的过程中,我对鸿蒙系统的错误码体系也有了更深的理解,知道哪些情况是用户操作导致的,哪些是系统资源问题。尤其是对于用户拒绝授权的情况,我还特地增加了一些提示信息,引导用户去设置页面开启相机权限,以提升用户体验。

另外,考虑到用户在拍照和录像时的体验,我还对拍摄结果进行了简单的处理,比如把结果显示在应用的某个区域,让用户可以确认是否满意。如果用户不满意,还可以重新进行拍摄或录制。这些小细节虽然不复杂,但能显著提升用户对应用的好感度。

image.png

最终成果与收获

经过一段时间的开发和调试,我终于把相机功能顺利集成到了应用里。用户可以通过按钮拉起系统相机,选择拍照或者录制视频,完成操作后,应用会拿到相应的结果并显示在页面上。看到自己写的代码在手机上跑起来,画面流畅地切换,心里真的有一种莫名的成就感。

老板对这个功能也非常满意,说以后类似的多媒体功能还会交给我来做。虽然整个过程有点曲折,但我学到了很多关于鸿蒙系统相机接口的知识,也掌握了如何处理上下文和异常情况。尤其是对于 Promise 的异步处理和错误捕获,我感觉自己又有了一些新的理解。

这次的开发经历让我明白了一点:面对新技术不要害怕,只要认真查资料、阅读文档,并不断地尝试和调试,最终一定能把问题解决。开发者的工作就是在解决一个个问题中不断成长,每一个解决的问题都是进步的证明。

我也想和正在学习鸿蒙相机功能的小伙伴们分享一些心得:首先,要有足够的耐心,遇到问题不要慌张,很多坑其实是因为文档细节没注意到;其次,要多参考社区的案例,别人的经验往往能帮你少走弯路。希望你们在开发中遇到问题时,可以参考我的这些代码和思路,祝你们也能顺利完成任务!一起加油吧!

最后,如果你们在实际项目中遇到了类似的问题,不妨和我交流一下,一起进步。
当然大家也可以关注我,我会继续和大家一起分享鸿蒙的开发故事。

image.png


郝敬学
22 声望1 粉丝