本文是「鸿蒙 6.1 API 23 开发坑系列」第 14 篇(非 UI 系第 8 篇)。本篇讲 @ohos.multimedia.camera namespace(API 10+,鸿蒙 6.1 API 23 基座)—— 相机管理 camera.getCameraManager(context) 工厂造 CameraManager 实例 + CameraManager.createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession 工厂造 CameraInput/PreviewOutput/PhotoOutput/CaptureSession 实例 + CameraPosition/CameraType/CameraFormat/CameraStatus enum + CameraInput/PreviewOutput/PhotoOutput/CaptureSession/CameraDevice/CameraOutputCapability/Profile/CameraManager interface 不能 new。鸿蒙坑根因:① camera.getCameraManager(context: Context): CameraManager 是工厂函数造 CameraManager 实例——CameraManager 是 interface 不能 new camera.CameraManager()(跟篇 7 HttpRequest interface 不能 new、篇 13 ImageSource interface 不能 new 同理);② CameraManager.getSupportedCameras(): Array<CameraDevice> 同步获取相机设备列表——CameraDevice 是 interface 不能 new,含 cameraId: string + cameraPosition: CameraPosition + cameraType: CameraType + connectionType: ConnectionType 字段;③ CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2 不是字符串 'CAMERA_POSITION_BACK'(传字符串编译错,enum 值是数字 0/1/2 不是字符串);④ CameraManager.createCameraInput(position: CameraPosition, type: CameraType): CameraInput 工厂造 CameraInput 实例——CameraInput 是 interface 不能 new,需先 open() 异步打开相机;⑤ CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂造 PreviewOutput 实例——surfaceId 来自 XComponentgetXComponentSurfaceId()ProfilegetSupportedOutputCapability().previewProfiles[0];⑥ CameraManager.createCaptureSession(): CaptureSession 工厂造 CaptureSession 实例——CaptureSession 是 interface 不能 new,会话流程 beginConfig()addInput(cameraInput)addOutput(previewOutput)commitConfig()start()

一、开篇:鸿蒙 camera 不是浏览器 navigator.mediaDevices.getUserMedia,是「getCameraManager 工厂造 CameraManager」

你写 Web 前端时,相机预览用 navigator.mediaDevices.getUserMedia({ video: true })(返回 Promise<MediaStream><video> 元素 srcObject = stream 显示预览):

// Web:navigator.mediaDevices.getUserMedia 获取相机流
const stream: MediaStream = await navigator.mediaDevices.getUserMedia({
  video: { facingMode: 'user' }  // ✅ 前置摄像头('user')/ 后置摄像头('environment')
})
const video: HTMLVideoElement = document.querySelector('video')!
video.srcObject = stream  // ✅ video.srcObject 显示预览
video.play()

你写鸿蒙 ArkTS 时,相机预览用 camera.getCameraManager(context) 工厂造 CameraManager 实例 + getSupportedCameras() 获取相机设备列表 + createCameraInput()/createPreviewOutput()/createCaptureSession() 工厂造 CameraInput/PreviewOutput/CaptureSession 实例:

// ArkTS camera.getCameraManager:工厂造 CameraManager(interface 不能 new)
import camera from '@ohos.multimedia.camera'  // ✅ default import(camera 是 namespace)
import common from '@ohos.app.ability.common'

// ✅ getCameraManager 工厂造 CameraManager 实例(传 Context,interface 不能 new camera.CameraManager)
const cameraManager: camera.CameraManager = camera.getCameraManager(context as common.Context)

// ✅ getSupportedCameras 同步获取相机设备列表(CameraDevice[] 数组)
const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
console.info('相机数量: ' + cameras.length)  // ✅ 通常 2 个(后置 + 前置)

// ✅ getSupportedOutputCapability 获取相机输出能力(previewProfiles/photoProfiles)
const capability: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameras[0])
const previewProfile: camera.Profile = capability.previewProfiles[0]  // ✅ 预览 Profile
// 鸿蒙坑根因:getCameraManager 工厂造 CameraManager(interface 不能 new),CameraPosition enum 非字符串

Web vs 鸿蒙 camera 的区别:Web 把相机当 navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' } })(返回 Promise<MediaStream>facingMode: 'user'/'environment' 字符串关键字选前后置),ArkTS 把相机当 camera.getCameraManager(context) 工厂造 CameraManager 实例 + getSupportedCameras() 获取相机设备列表(CameraDevice[] 数组,含 cameraPosition: CameraPosition enum 常量)+ createCameraInput()/createPreviewOutput()/createCaptureSession() 工厂造 CameraInput/PreviewOutput/CaptureSession 实例。根因不是 Promise 是工厂——鸿蒙 CameraManager 是 interface 不能 new camera.CameraManager()(用 camera.getCameraManager(context) 工厂造实例,context 必传),CameraInput/PreviewOutput/PhotoOutput/CaptureSession 都是 interface 不能 new(用 CameraManager.createCameraInput()/createPreviewOutput()/createPhotoOutput()/createCaptureSession() 工厂造实例),CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2 不是字符串 'CAMERA_POSITION_BACK'(传字符串触发 Type 'string' is not assignable to type 'CameraPosition' 编译错,enum 值是数字 0/1/2 不是字符串)。

二、根因:鸿蒙 @ohos.multimedia.camera 的六个绑定机制

鸿蒙 @ohos.multimedia.camera namespace(API 10+)核心导出 camera.getCameraManager(context) 工厂函数(造 CameraManager 实例)+ CameraManager interface(含 getSupportedCameras/getSupportedOutputCapability/createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession 方法)+ CameraInput/PreviewOutput/PhotoOutput/CaptureSession/CameraDevice/CameraOutputCapability/Profile/CameraStatus interface + CameraPosition/CameraType/CameraFormat/ConnectionType/SceneMode enum。绑定机制来自六重根因。

机制 1:camera.getCameraManager(context) 工厂造 CameraManager——CameraManager interface 不能 new

鸿蒙坑根因:camera.getCameraManager(context: Context): CameraManager 是工厂函数造 CameraManager 实例——CameraManager 是 interface 不能 new camera.CameraManager()

// ❌ 鸿蒙坑:CameraManager 是 interface 不能 new camera.CameraManager()
import camera from '@ohos.multimedia.camera'
import common from '@ohos.app.ability.common'

// ❌ new camera.CameraManager() 编译错(CameraManager 是 interface 不是 class,没有 constructor)
const manager1 = new camera.CameraManager()  // ❌ 'CameraManager' only refers to a type

// ❌ new camera.CameraManager(context) 编译错(interface 没有 constructor 带参)
const manager2 = new camera.CameraManager(context as common.Context)  // ❌ interface 不能 new

// ✅ 正确用法:camera.getCameraManager 工厂函数造 CameraManager 实例
const cameraManager: camera.CameraManager = camera.getCameraManager(context as common.Context)  // ✅ 工厂造实例
// 鸿蒙坑根因:getCameraManager 工厂造 CameraManager(interface 不能 new,context 必传)

getCameraManager 工厂 CameraManager interface 不能 new 坑根因:鸿蒙 camera.getCameraManager(context: Context): CameraManager 是工厂函数造 CameraManager 实例(CameraManager 是 interface 不是 class,没有 constructor——new camera.CameraManager() 触发 'CameraManager' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑context: Context 必传(context as common.ContextAbilityContextContext),不传 context 编译错(Expected 1 arguments, but got 0)。React navigator.mediaDevices.getUserMedia() 不需要 context(浏览器全局 navigator 对象),鸿蒙 getCameraManager(context) 必传 context(Android-style Context 依赖注入,AbilityContext 提供 UIAbility 上下文)。CameraManager 是相机管理的总入口,所有相机操作(getSupportedCameras/getSupportedOutputCapability/createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession)都通过 CameraManager 实例调用。

机制 2:CameraManager.getSupportedCameras() 同步获取 CameraDevice[]——CameraDevice 是 interface

鸿蒙坑根因:CameraManager.getSupportedCameras(): Array<CameraDevice> 同步获取相机设备列表——CameraDevice 是 interface 不能 new,含 cameraId/cameraPosition/cameraType/connectionType 字段:

// ✅ 鸿蒙坑:getSupportedCameras 同步获取 CameraDevice[](CameraDevice 是 interface 不能 new)
import camera from '@ohos.multimedia.camera'

const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
console.info('相机数量: ' + cameras.length)  // ✅ 通常 2 个(后置 + 前置)

// ✅ CameraDevice interface 字段(cameraId + cameraPosition + cameraType + connectionType)
cameras.forEach((cam: camera.CameraDevice, index: number) => {
  console.info(`相机[${index}]: id=${cam.cameraId} position=${cam.cameraPosition} type=${cam.cameraType}`)
})

// ✅ 取后置相机(cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK)
const backCamera: camera.CameraDevice | undefined = cameras.find(
  (cam: camera.CameraDevice) => cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK
)
if (!backCamera) {
  console.error('没有后置相机')
  return
}
// ✅ 取前置相机(cameraPosition === camera.CameraPosition.CAMERA_POSITION_FRONT)
const frontCamera: camera.CameraDevice | undefined = cameras.find(
  (cam: camera.CameraDevice) => cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_FRONT
)
// 鸿蒙坑根因:getSupportedCameras 返回 CameraDevice[](interface 不能 new),cameraPosition 是 enum 不是字符串

getSupportedCameras + CameraDevice interface 坑根因:鸿蒙 CameraManager.getSupportedCameras(): Array<CameraDevice> 同步获取相机设备列表(不返回 Promise,直接返回数组),CameraDevice 是 interface 不能 new camera.CameraDevice()(用 getSupportedCameras() 工厂获取实例)。CameraDevice interface 含字段 cameraId: string(相机唯一标识)/cameraPosition: CameraPosition(相机位置 enum 常量)/cameraType: CameraType(相机类型 enum 常量)/connectionType: ConnectionType(连接类型 enum 常量,USB/WIRELESS 等)。鸿蒙坑cameraPositionCameraPosition enum 不是字符串(cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK enum 常量比较,❌ cam.cameraPosition === 'BACK' 字符串比较编译错)。React navigator.mediaDevices.getSupportedConstraints() 返回 MediaTrackSupportedConstraints 对象(含 facingMode: boolean 字段标识支持 facingMode),鸿蒙 getSupportedCameras() 返回 CameraDevice[] 数组(每个 CameraDevicecameraPosition enum 标识前后置)。

机制 3:CameraPosition enum 常量 CAMERA_POSITION_BACK=0/FRONT=1 不是字符串’BACK’

鸿蒙坑根因:CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2 不是字符串 'CAMERA_POSITION_BACK'(传字符串编译错):

// ❌ 鸿蒙坑:CameraPosition enum 常量不是字符串'CAMERA_POSITION_BACK'
import camera from '@ohos.multimedia.camera'

// ❌ 传字符串'CAMERA_POSITION_BACK'编译错(CameraPosition 类型是 enum 不是 string)
const pos1: camera.CameraPosition = 'CAMERA_POSITION_BACK'  // ❌ Type 'string' is not assignable to type 'CameraPosition'

// ❌ 传数字 0 编译错(enum 值是数字但类型必须 enum 常量不是 number)
const pos2: camera.CameraPosition = 0  // ❌ Type 'number' is not assignable to type 'CameraPosition'

// ❌ 传简写字符串'BACK'编译错(CameraPosition enum 没有'BACK'常量)
const pos3: camera.CameraPosition = 'BACK'  // ❌ Type 'string' is not assignable to type 'CameraPosition'

// ✅ 正确用法:camera.CameraPosition.CAMERA_POSITION_BACK enum 常量(不是字符串,不是数字)
const pos4: camera.CameraPosition = camera.CameraPosition.CAMERA_POSITION_BACK  // ✅ enum 常量 = 0
const pos5: camera.CameraPosition = camera.CameraPosition.CAMERA_POSITION_FRONT  // ✅ enum 常量 = 1
const pos6: camera.CameraPosition = camera.CameraPosition.CAMERA_POSITION_UNSPECIFIED  // ✅ enum 常量 = 2
// ✅ CameraPosition enum 常量语义:
// CAMERA_POSITION_BACK=0:后置相机(对应 React facingMode: 'environment')
// CAMERA_POSITION_FRONT=1:前置相机(对应 React facingMode: 'user')
// CAMERA_POSITION_UNSPECIFIED=2:未指定位置(通常外接 USB 相机)
// 鸿蒙坑根因:CameraPosition enum 常量 CAMERA_POSITION_BACK/FRONT/UNSPECIFIED 不是字符串 enum 值数字

CameraPosition enum 常量不是字符串坑根因:鸿蒙 CameraPosition enum 的三个常量是 CAMERA_POSITION_BACK=0(后置相机)/CAMERA_POSITION_FRONT=1(前置相机)/CAMERA_POSITION_UNSPECIFIED=2(未指定位置,通常外接 USB 相机)。鸿蒙坑:传字符串 'CAMERA_POSITION_BACK'/'BACK' 触发 Type 'string' is not assignable to type 'CameraPosition' 编译错——必须传 camera.CameraPosition.CAMERA_POSITION_BACK enum 常量(enum 值是数字 0 不是字符串)。传数字 0 也编译错(Type 'number' is not assignable to type 'CameraPosition',ArkTS 严格模式 enum 类型不接受裸数字)。React getUserMedia({ video: { facingMode: 'user' } }) 用字符串关键字 'user'/'environment' 选前后置(浏览器解析字符串),鸿蒙 camera.CameraPosition.CAMERA_POSITION_FRONT 用 enum 常量选前后置(编译期类型检查,enum 值是数字)。

机制 4:CameraManager.createCameraInput(position, type) 工厂造 CameraInput——CameraInput interface 不能 new

鸿蒙坑根因:CameraManager.createCameraInput(position: CameraPosition, type: CameraType): CameraInput 工厂造 CameraInput 实例——CameraInput 是 interface 不能 new,需先 open() 异步打开相机:

// ❌ 鸿蒙坑:CameraInput 是 interface 不能 new camera.CameraInput()
import camera from '@ohos.multimedia.camera'

// ❌ new camera.CameraInput() 编译错(CameraInput 是 interface 不是 class)
const input1 = new camera.CameraInput()  // ❌ 'CameraInput' only refers to a type

// ✅ 正确用法:createCameraInput 工厂造 CameraInput 实例(两种重载)
// ✅ 重载 1:createCameraInput(camera: CameraDevice) 传 CameraDevice
const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
const backCamera: camera.CameraDevice = cameras[0]  // ✅ 取后置相机
const cameraInput1: camera.CameraInput = cameraManager.createCameraInput(backCamera)  // ✅ 传 CameraDevice

// ✅ 重载 2:createCameraInput(position: CameraPosition, type: CameraType) 传 enum 常量
const cameraInput2: camera.CameraInput = cameraManager.createCameraInput(
  camera.CameraPosition.CAMERA_POSITION_BACK,  // ✅ CameraPosition enum 常量不是字符串
  camera.CameraType.CAMERA_TYPE_WIDE_ANGLE  // ✅ CameraType enum 常量不是字符串
)

// ✅ CameraInput.open() 异步打开相机(返回 Promise<void>)
await cameraInput1.open()  // ✅ 异步打开相机,必须 await
console.info('相机已打开')
// 鸿蒙坑根因:createCameraInput 工厂造 CameraInput(interface 不能 new),open() 异步打开相机

createCameraInput 工厂 CameraInput interface 不能 new 坑根因:鸿蒙 CameraManager.createCameraInput(camera: CameraDevice): CameraInputcreateCameraInput(position: CameraPosition, type: CameraType): CameraInput 两种重载工厂函数造 CameraInput 实例(CameraInput 是 interface 不是 class,没有 constructor——new camera.CameraInput() 触发 'CameraInput' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑CameraInput.open(): Promise<void> 异步打开相机(必须 await,不 await 后续操作会报错「相机未打开」),CameraInput.close(): Promise<void> 异步关闭相机(aboutToDisappear 生命周期调 close 释放资源),CameraInput.on('error', callback) 监听相机错误事件。React getUserMedia 打开相机直接返回 MediaStream(一步到位),鸿蒙 createCameraInput + open() 两步(先工厂造 CameraInput 实例,再 open 异步打开相机)。

机制 5:CameraManager.createPreviewOutput(profile, surfaceId) 工厂造 PreviewOutput——surfaceId 来自 XComponent

鸿蒙坑根因:CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂造 PreviewOutput 实例——surfaceId 来自 XComponentgetXComponentSurfaceId()ProfilegetSupportedOutputCapability().previewProfiles[0]

// ❌ 鸿蒙坑:PreviewOutput 是 interface 不能 new camera.PreviewOutput()
import camera from '@ohos.multimedia.camera'

// ❌ new camera.PreviewOutput() 编译错(PreviewOutput 是 interface 不是 class)
const output1 = new camera.PreviewOutput()  // ❌ 'PreviewOutput' only refers to a type

// ✅ 正确用法:createPreviewOutput 工厂造 PreviewOutput 实例(传 Profile + surfaceId)
// ✅ step 1:getSupportedOutputCapability 获取相机输出能力
const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
const capability: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameras[0])
const previewProfile: camera.Profile = capability.previewProfiles[0]  // ✅ 取第一个预览 Profile

// ✅ step 2:XComponent 获取 surfaceId(预览渲染表面 ID)
// XComponent({ type: XComponentType.SURFACE, controller: this.xcomponentController })
//   .onLoad(() => {
//     const surfaceId: string = this.xcomponentController.getXComponentSurfaceId()  // ✅ surfaceId 字符串
//     this.startPreview(surfaceId, previewProfile)
//   })

// ✅ step 3:createPreviewOutput 工厂造 PreviewOutput 实例
const previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId)
// 鸿蒙坑根因:createPreviewOutput 工厂造 PreviewOutput(interface 不能 new),surfaceId 来自 XComponent

createPreviewOutput 工厂 PreviewOutput interface 不能 new 坑根因:鸿蒙 CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂函数造 PreviewOutput 实例(PreviewOutput 是 interface 不是 class,没有 constructor——new camera.PreviewOutput() 触发 'PreviewOutput' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑profile: Profile 必须用 getSupportedOutputCapability(cameras[0]).previewProfiles[0] 获取(不能手动构造 Profile 对象,Profile 是 interface 不能 new);surfaceId: string 必须来自 XComponentgetXComponentSurfaceId()XComponent 是 ArkUI 的原生组件渲染表面,surfaceId 是底层 Surface 的唯一标识字符串)。React <video srcObject={stream}> 直接用 <video> 元素显示预览(浏览器渲染),鸿蒙 XComponent + PreviewOutput + surfaceId 三件套(XComponent 提供渲染表面,PreviewOutput 绑定 surfaceId 输出预览帧,底层 SurfaceFlinger 渲染)。

机制 6:CameraManager.createCaptureSession() 工厂造 CaptureSession——会话流程 beginConfig→addInput→addOutput→commitConfig→start

鸿蒙坑根因:CameraManager.createCaptureSession(): CaptureSession 工厂造 CaptureSession 实例——CaptureSession 是 interface 不能 new,会话流程 beginConfig()addInput(cameraInput)addOutput(previewOutput)commitConfig()start()

// ❌ 鸿蒙坑:CaptureSession 是 interface 不能 new camera.CaptureSession()
import camera from '@ohos.multimedia.camera'

// ❌ new camera.CaptureSession() 编译错(CaptureSession 是 interface 不是 class)
const session1 = new camera.CaptureSession()  // ❌ 'CaptureSession' only refers to a type

// ✅ 正确用法:createCaptureSession 工厂造 CaptureSession 实例
const captureSession: camera.CaptureSession = cameraManager.createCaptureSession()

// ✅ 会话流程:beginConfig → addInput → addOutput → commitConfig → start
// ✅ step 1:beginConfig 开始配置会话
captureSession.beginConfig()

// ✅ step 2:addInput 添加 CameraInput(相机输入流)
await captureSession.addInput(cameraInput)

// ✅ step 3:addOutput 添加 PreviewOutput(预览输出流)
await captureSession.addOutput(previewOutput)

// ✅ step 4:commitConfig 提交配置(异步,返回 Promise<void>)
await captureSession.commitConfig()

// ✅ step 5:start 启动会话(异步,返回 Promise<void>,预览开始)
await captureSession.start()
console.info('相机预览已启动')

// ✅ step 6:stop 停止会话(aboutToDisappear 生命周期调)
await captureSession.stop()
// 鸿蒙坑根因:createCaptureSession 工厂造 CaptureSession(interface 不能 new),会话流程 5 步

createCaptureSession 工厂 CaptureSession interface 不能 new 坑根因:鸿蒙 CameraManager.createCaptureSession(): CaptureSession 工厂函数造 CaptureSession 实例(CaptureSession 是 interface 不是 class,没有 constructor——new camera.CaptureSession() 触发 'CaptureSession' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑CaptureSession 会话流程严格 5 步——beginConfig()(开始配置会话,同步方法)→ addInput(cameraInput)(添加 CameraInput 相机输入流,异步返回 Promise<void>)→ addOutput(previewOutput)(添加 PreviewOutput 预览输出流,异步返回 Promise<void>)→ commitConfig()(提交配置,异步返回 Promise<void>)→ start()(启动会话,异步返回 Promise<void>,预览开始)。鸿蒙坑:必须严格按 beginConfigaddInputaddOutputcommitConfigstart 顺序调用,颠倒顺序或跳步会报错(如 addInputaddOutput 报「会话未配置」错,commitConfigaddInput 报「会话已提交不能再配置」错)。React getUserMedia 直接返回 MediaStream(一步到位,无会话流程),鸿蒙 CaptureSession 会话流程 5 步(Android Camera2 API 风格,CaptureSession 对应 Android CameraCaptureSessionbeginConfig/commitConfig 对应 Android SessionConfiguration)。

三、真机配图:鸿蒙 @ohos.multimedia.camera 相机坑——getCameraManager 工厂非 new + CameraPosition enum 非字符串

camera 初始态 getCameraManager 工厂态 CameraPosition enum 态 createPreviewOutput 态 CaptureSession 会话态

真机配图展示鸿蒙 @ohos.multimedia.camera 相机坑:

  • camera 初始态:鸿蒙 6.1 @ohos.multimedia.camera 相机坑标题,5 个验证按钮(① getCameraManager 工厂非 new / ② CameraPosition enum 非字符串 / ③ createCameraInput 工厂非 new / ④ createPreviewOutput 工厂非 new / ⑤ createCaptureSession 会话流程 5 步),要点说明 7 条
  • getCameraManager 工厂态:点击「① 验证 getCameraManager 工厂非 new」按钮,显示「✅ camera.getCameraManager(context) 工厂造 CameraManager 实例(interface 不能 new camera.CameraManager)」+ cameraManager 值——getCameraManager 工厂造 CameraManager(interface 不能 new)验证
  • CameraPosition enum 态:点击「② 验证 CameraPosition enum 非字符串」按钮,显示「✅ CameraPosition enum 常量 CAMERA_POSITION_BACK=0 / CAMERA_POSITION_FRONT=1 / CAMERA_POSITION_UNSPECIFIED=2 不是字符串」+ cameras 数组——CameraPosition enum 常量非字符串验证
  • createPreviewOutput 态:点击「④ 验证 createPreviewOutput 工厂非 new」按钮,显示「✅ createPreviewOutput(profile, surfaceId) 工厂造 PreviewOutput 实例(surfaceId 来自 XComponent)」+ previewOutput 值——createPreviewOutput 工厂造 PreviewOutput(surfaceId 来自 XComponent)验证
  • CaptureSession 会话态:点击「⑤ 验证 createCaptureSession 会话流程 5 步」按钮,显示「✅ beginConfig → addInput → addOutput → commitConfig → start 会话流程 5 步」+ captureSession 值——CaptureSession 会话流程 5 步验证

四、真解法:鸿蒙 @ohos.multimedia.camera 的四个场景

场景 1:getCameraManager + getSupportedCameras + getSupportedOutputCapability 初始化相机

基础相机初始化用 camera.getCameraManager(context) 工厂造 CameraManager 实例 + getSupportedCameras() 获取相机设备列表 + getSupportedOutputCapability() 获取相机输出能力:

// ✅ 场景 1:getCameraManager + getSupportedCameras + getSupportedOutputCapability 初始化相机(API 10)
import camera from '@ohos.multimedia.camera'  // ✅ default import(camera 是 namespace)
import common from '@ohos.app.ability.common'

@Entry
@Component
struct Index {
  private cameraManager: camera.CameraManager | null = null
  @State cameraInfo: string = '未初始化'

  async initCamera(context: common.Context) {
    // ✅ getCameraManager 工厂造 CameraManager 实例(interface 不能 new camera.CameraManager)
    this.cameraManager = camera.getCameraManager(context)
    if (!this.cameraManager) {
      console.error('CameraManager 创建失败')
      return
    }

    // ✅ getSupportedCameras 同步获取相机设备列表(CameraDevice[] 数组)
    const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
    if (cameras.length === 0) {
      console.error('没有可用相机')
      return
    }

    // ✅ getSupportedOutputCapability 获取相机输出能力(previewProfiles/photoProfiles)
    const capability: camera.CameraOutputCapability = this.cameraManager.getSupportedOutputCapability(cameras[0])
    const previewProfile: camera.Profile = capability.previewProfiles[0]  // ✅ 预览 Profile

    this.cameraInfo = `相机数量: ${cameras.length}\n` +
      `后置相机: ${cameras.find(c => c.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK)?.cameraId ?? '无'}\n` +
      `前置相机: ${cameras.find(c => c.cameraPosition === camera.CameraPosition.CAMERA_POSITION_FRONT)?.cameraId ?? '无'}`
  }

  build() {
    Column({ space: 8 }) {
      Button('初始化相机').onClick(() => this.initCamera(getContext(this) as common.Context))
      Text(this.cameraInfo).fontSize(16).margin({ top: 20 })
    }
  }
}
// getCameraManager 工厂造 CameraManager(interface 不能 new)+ getSupportedCameras 获取 CameraDevice[]

鸿蒙 @ohos.multimedia.camera API 真名坑import camera from '@ohos.multimedia.camera'(default import,camera 是 namespace);camera.getCameraManager(context: Context): CameraManager(工厂函数造 CameraManager 实例,context 必传从 AbilityContextContext);CameraManager.getSupportedCameras(): Array<CameraDevice>(同步获取相机设备列表,CameraDevice interface 含 cameraId/cameraPosition/cameraType/connectionType 字段);CameraManager.getSupportedOutputCapability(camera: CameraDevice): CameraOutputCapability(同步获取相机输出能力,CameraOutputCapability interface 含 previewProfiles: Array<Profile>/photoProfiles: Array<Profile>/videoProfiles: Array<VideoProfile> 字段);CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2(不是字符串 'BACK',enum 值是数字);SysCap SystemCapability.Multimedia.Camera.Core / SystemCapability.Multimedia.Camera.Front / SystemCapability.Multimedia.Camera.Back@atomicservice 原子化服务(API 11+)。

场景 2:createCameraInput + open 打开相机——CameraPosition/CameraType enum 常量

打开相机用 CameraManager.createCameraInput(position, type) 工厂造 CameraInput 实例 + CameraInput.open() 异步打开相机:

// ✅ 场景 2:createCameraInput + open 打开相机(API 10)
import camera from '@ohos.multimedia.camera'

@Entry
@Component
struct Index {
  private cameraManager: camera.CameraManager | null = null
  private cameraInput: camera.CameraInput | null = null
  @State openStatus: string = '未打开'

  async openCamera() {
    if (!this.cameraManager) {
      this.cameraManager = camera.getCameraManager(getContext(this) as common.Context)
    }

    // ✅ createCameraInput 工厂造 CameraInput 实例(两种重载)
    // ✅ 重载 1:createCameraInput(camera: CameraDevice) 传 CameraDevice
    const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
    const backCamera: camera.CameraDevice = cameras.find(
      (cam: camera.CameraDevice) => cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK
    )!
    this.cameraInput = this.cameraManager.createCameraInput(backCamera)  // ✅ 传 CameraDevice

    // ✅ 重载 2:createCameraInput(position: CameraPosition, type: CameraType) 传 enum 常量
    // this.cameraInput = this.cameraManager.createCameraInput(
    //   camera.CameraPosition.CAMERA_POSITION_BACK,  // ✅ CameraPosition enum 常量不是字符串
    //   camera.CameraType.CAMERA_TYPE_WIDE_ANGLE  // ✅ CameraType enum 常量不是字符串
    // )

    // ✅ CameraInput.open() 异步打开相机(返回 Promise<void>,必须 await)
    await this.cameraInput.open()
    this.openStatus = '相机已打开'
    console.info('相机已打开')

    // ✅ CameraInput.on('error', callback) 监听相机错误事件
    this.cameraInput.on('error', (error: camera.CameraInputErrorCode) => {
      console.error('相机错误: ' + error)
    })
  }

  build() {
    Column({ space: 8 }) {
      Button('打开相机').onClick(() => this.openCamera())
      Text(this.openStatus).fontSize(16).margin({ top: 20 })
    }
  }
}
// createCameraInput 工厂造 CameraInput(interface 不能 new)+ open() 异步打开相机

鸿蒙 createCameraInput + open API 真名坑CameraManager.createCameraInput(camera: CameraDevice): CameraInputcreateCameraInput(position: CameraPosition, type: CameraType): CameraInput 两种重载工厂函数造 CameraInput 实例(CameraInput 是 interface 不能 new);CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2(不是字符串 'BACK',enum 值是数字);CameraType enum 常量 CAMERA_TYPE_WIDE_ANGLE=0(广角)/CAMERA_TYPE_TELEPHOTO=1(长焦)/CAMERA_TYPE_ULTRA_WIDE=2(超广角)/CAMERA_TYPE_DEFAULT=3(默认)(不是字符串 'WIDE_ANGLE',enum 值是数字);CameraInput.open(): Promise<void> 异步打开相机(必须 await);CameraInput.close(): Promise<void> 异步关闭相机(aboutToDisappear 生命周期调 close 释放资源);CameraInput.on('error', callback: (error: camera.CameraInputErrorCode) => void) 监听相机错误事件;React getUserMedia({ video: { facingMode: 'user' } }) 用字符串关键字 'user'/'environment' 选前后置(浏览器解析字符串),鸿蒙 CameraPosition enum 常量选前后置(编译期类型检查,enum 值是数字)。

场景 3:createPreviewOutput + XComponent 预览相机流——surfaceId 来自 XComponent

预览相机流用 CameraManager.createPreviewOutput(profile, surfaceId) 工厂造 PreviewOutput 实例 + XComponent 获取 surfaceId

// ✅ 场景 3:createPreviewOutput + XComponent 预览相机流(API 10)
import camera from '@ohos.multimedia.camera'
import common from '@ohos.app.ability.common'
import { XComponent, XComponentType } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  private cameraManager: camera.CameraManager | null = null
  private cameraInput: camera.CameraInput | null = null
  private previewOutput: camera.PreviewOutput | null = null
  private captureSession: camera.CaptureSession | null = null
  private xcomponentController: XComponentController = new XComponentController()
  @State previewStarted: boolean = false

  async startPreview(surfaceId: string, previewProfile: camera.Profile) {
    // ✅ createCameraInput 工厂造 CameraInput 实例
    const cameras: Array<camera.CameraDevice> = this.cameraManager!.getSupportedCameras()
    this.cameraInput = this.cameraManager!.createCameraInput(cameras[0])
    await this.cameraInput.open()  // ✅ 异步打开相机

    // ✅ createPreviewOutput 工厂造 PreviewOutput 实例(传 Profile + surfaceId)
    this.previewOutput = this.cameraManager!.createPreviewOutput(previewProfile, surfaceId)

    // ✅ createCaptureSession 工厂造 CaptureSession 实例
    this.captureSession = this.cameraManager!.createCaptureSession()

    // ✅ 会话流程 5 步:beginConfig → addInput → addOutput → commitConfig → start
    this.captureSession.beginConfig()
    await this.captureSession.addInput(this.cameraInput)
    await this.captureSession.addOutput(this.previewOutput)
    await this.captureSession.commitConfig()
    await this.captureSession.start()  // ✅ 启动预览

    this.previewStarted = true
  }

  build() {
    Column({ space: 8 }) {
      // ✅ XComponent 提供渲染表面,onLoad 回调获取 surfaceId
      XComponent({ type: XComponentType.SURFACE, controller: this.xcomponentController })
        .onLoad(() => {
          // ✅ getXComponentSurfaceId 获取 surfaceId(字符串,来自底层 Surface)
          const surfaceId: string = this.xcomponentController.getXComponentSurfaceId()
          // ✅ 初始化相机管理器
          this.cameraManager = camera.getCameraManager(getContext(this) as common.Context)
          // ✅ 获取预览 Profile
          const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
          const capability: camera.CameraOutputCapability =
            this.cameraManager.getSupportedOutputCapability(cameras[0])
          const previewProfile: camera.Profile = capability.previewProfiles[0]
          // ✅ 启动预览
          this.startPreview(surfaceId, previewProfile)
        })
        .width('100%').height(400)
      Text(this.previewStarted ? '预览已启动' : '预览启动中...').fontSize(16)
    }
  }
}
// createPreviewOutput 工厂造 PreviewOutput(interface 不能 new)+ XComponent surfaceId

鸿蒙 createPreviewOutput + XComponent API 真名坑CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂函数造 PreviewOutput 实例(PreviewOutput 是 interface 不能 new);profile: Profile 必须用 getSupportedOutputCapability(cameras[0]).previewProfiles[0] 获取(Profile 是 interface 不能 new,含 width: number/height: number/format: CameraFormat 字段);surfaceId: string 必须来自 XComponentgetXComponentSurfaceId()XComponent 是 ArkUI 原生组件渲染表面,surfaceId 是底层 Surface 的唯一标识字符串);CameraFormat enum 常量 CAMERA_FORMAT_RGBA_8888=3/CAMERA_FORMAT_YUV_420_SP=1003/CAMERA_FORMAT_JPEG=2000(不是字符串 'RGBA_8888',enum 值是数字);React <video srcObject={stream}> 直接用 <video> 元素显示预览(浏览器渲染),鸿蒙 XComponent + PreviewOutput + surfaceId 三件套(XComponent 提供渲染表面,PreviewOutput 绑定 surfaceId 输出预览帧,底层 SurfaceFlinger 渲染)。

场景 4:createCaptureSession 会话流程 5 步——beginConfig→addInput→addOutput→commitConfig→start

会话流程用 CameraManager.createCaptureSession() 工厂造 CaptureSession 实例 + 5 步会话流程 beginConfigaddInputaddOutputcommitConfigstart

// ✅ 场景 4:createCaptureSession 会话流程 5 步(API 10)
import camera from '@ohos.multimedia.camera'

@Entry
@Component
struct Index {
  private cameraManager: camera.CameraManager | null = null
  private cameraInput: camera.CameraInput | null = null
  private previewOutput: camera.PreviewOutput | null = null
  private captureSession: camera.CaptureSession | null = null

  async startSession() {
    if (!this.cameraManager) {
      this.cameraManager = camera.getCameraManager(getContext(this) as common.Context)
    }

    // ✅ step 1:createCameraInput 工厂造 CameraInput 实例 + open 异步打开相机
    const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
    this.cameraInput = this.cameraManager.createCameraInput(cameras[0])
    await this.cameraInput.open()  // ✅ 异步打开相机

    // ✅ step 2:createPreviewOutput 工厂造 PreviewOutput 实例(surfaceId 从 XComponent 获取)
    const capability: camera.CameraOutputCapability =
      this.cameraManager.getSupportedOutputCapability(cameras[0])
    const previewProfile: camera.Profile = capability.previewProfiles[0]
    // const surfaceId: string = this.xcomponentController.getXComponentSurfaceId()
    this.previewOutput = this.cameraManager.createPreviewOutput(previewProfile, surfaceId)

    // ✅ step 3:createCaptureSession 工厂造 CaptureSession 实例(interface 不能 new)
    this.captureSession = this.cameraManager.createCaptureSession()

    // ✅ 会话流程 5 步(严格按顺序调用)
    // ✅ step 3a:beginConfig 开始配置会话(同步方法)
    this.captureSession.beginConfig()

    // ✅ step 3b:addInput 添加 CameraInput(相机输入流,异步返回 Promise<void>)
    await this.captureSession.addInput(this.cameraInput)

    // ✅ step 3c:addOutput 添加 PreviewOutput(预览输出流,异步返回 Promise<void>)
    await this.captureSession.addOutput(this.previewOutput)

    // ✅ step 3d:commitConfig 提交配置(异步返回 Promise<void>)
    await this.captureSession.commitConfig()

    // ✅ step 3e:start 启动会话(异步返回 Promise<void>,预览开始)
    await this.captureSession.start()
    console.info('相机预览已启动')
  }

  // ✅ aboutToDisappear 生命周期释放资源(避免内存泄漏)
  async aboutToDisappear() {
    if (this.captureSession) {
      await this.captureSession.stop()  // ✅ stop 停止会话
    }
    if (this.cameraInput) {
      await this.cameraInput.close()  // ✅ close 关闭相机
    }
    if (this.previewOutput) {
      await this.previewOutput.release()  // ✅ release 释放 PreviewOutput
    }
    if (this.captureSession) {
      await this.captureSession.release()  // ✅ release 释放 CaptureSession
    }
  }

  build() {
    Column({ space: 8 }) {
      Button('启动会话').onClick(() => this.startSession())
    }
  }
}
// createCaptureSession 工厂造 CaptureSession(interface 不能 new)+ 会话流程 5 步

鸿蒙 createCaptureSession 会话流程 5 步 API 真名坑CameraManager.createCaptureSession(): CaptureSession 工厂函数造 CaptureSession 实例(CaptureSession 是 interface 不能 new);会话流程严格 5 步——beginConfig()(开始配置会话,同步方法,无返回值)→ addInput(cameraInput: CameraInput): Promise<void>(添加 CameraInput 相机输入流,异步)→ addOutput(previewOutput: PreviewOutput): Promise<void>(添加 PreviewOutput 预览输出流,异步)→ commitConfig(): Promise<void>(提交配置,异步)→ start(): Promise<void>(启动会话,异步,预览开始);鸿蒙坑:必须严格按 beginConfigaddInputaddOutputcommitConfigstart 顺序调用,颠倒顺序或跳步会报错(如 addInputaddOutput 报「会话未配置」错,commitConfigaddInput 报「会话已提交不能再配置」错);CaptureSession.stop(): Promise<void> 停止会话(aboutToDisappear 生命周期调);CaptureSession.release(): Promise<void> 释放会话资源(避免内存泄漏);aboutToDisappear 生命周期必须调 stop() + close() + release() 释放资源(相机硬件资源不释放会导致后续应用无法使用相机);React getUserMedia 直接返回 MediaStream(一步到位,无会话流程),鸿蒙 CaptureSession 会话流程 5 步(Android Camera2 API 风格,CaptureSession 对应 Android CameraCaptureSessionbeginConfig/commitConfig 对应 Android SessionConfiguration)。

五、一句话哲学

写鸿蒙 ArkTS 记住:camera 不是浏览器 navigator.mediaDevices.getUserMedia 是「getCameraManager 工厂造 CameraManager」——鸿蒙 6.1 API 23 @ohos.multimedia.camera namespace(API 10+,鸿蒙 6.1 API 23 基座,camera.getCameraManager(context) 工厂造 CameraManager 实例 + CameraManager.createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession 工厂造 CameraInput/PreviewOutput/PhotoOutput/CaptureSession 实例 + CameraPosition/CameraType/CameraFormat/CameraStatus/ConnectionType/SceneMode enum + CameraInput/PreviewOutput/PhotoOutput/CaptureSession/CameraDevice/CameraOutputCapability/Profile/CameraManager interface 不能 new + InitializationOptions/DecodingOptions/ImageInfo/Size/Region 类型,SysCap SystemCapability.Multimedia.Camera.Core / SystemCapability.Multimedia.Camera.Front / SystemCapability.Multimedia.Camera.Back,@atomicservice)。根因不是 Promise 是工厂——camera.getCameraManager(context: Context): CameraManager 工厂函数造 CameraManager 实例(✅ const cameraManager: camera.CameraManager = camera.getCameraManager(context as common.Context) 工厂造实例,❌ new camera.CameraManager() 触发 'CameraManager' only refers to a type, but is being used as a value here 编译错,CameraManager 是 interface 不是 class 没有 constructor,context: Context 必传从 AbilityContextContext,不传 context 编译错 Expected 1 arguments, but got 0,跟篇 7 HttpRequest interface 不能 new 用 http.createHttp() 工厂造实例、篇 13 ImageSource interface 不能 new 用 image.createImageSource() 工厂造实例同理,React navigator.mediaDevices.getUserMedia() 不需要 context 浏览器全局 navigator 对象差异,鸿蒙 getCameraManager(context) 必传 context Android-style Context 依赖注入 AbilityContext 提供 UIAbility 上下文),CameraManager.getSupportedCameras(): Array<CameraDevice> 同步获取相机设备列表(不返回 Promise 直接返回数组,CameraDevice 是 interface 不能 new camera.CameraDevice()getSupportedCameras() 工厂获取实例,含 cameraId: string/cameraPosition: CameraPosition/cameraType: CameraType/connectionType: ConnectionType 字段,cameraPositionCameraPosition enum 不是字符串 cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK enum 常量比较 ❌ cam.cameraPosition === 'BACK' 字符串比较编译错),CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2 不是字符串 'CAMERA_POSITION_BACK'(❌ 'CAMERA_POSITION_BACK' 触发 Type 'string' is not assignable to type 'CameraPosition' 编译错,❌ 0 触发 Type 'number' is not assignable to type 'CameraPosition' 编译错 ArkTS 严格模式 enum 类型不接受裸数字,✅ camera.CameraPosition.CAMERA_POSITION_BACK enum 常量 enum 值是数字 0/1/2 不是字符串,对应 React getUserMedia({ video: { facingMode: 'user' } }) 字符串关键字 'user'/'environment' 选前后置浏览器解析字符串差异,鸿蒙 CameraPosition enum 常量选前后置编译期类型检查 enum 值是数字),CameraManager.createCameraInput(camera: CameraDevice): CameraInputcreateCameraInput(position: CameraPosition, type: CameraType): CameraInput 两种重载工厂函数造 CameraInput 实例(CameraInput 是 interface 不能 new camera.CameraInput() 触发 'CameraInput' only refers to a type, but is being used as a value here 编译错,CameraInput.open(): Promise<void> 异步打开相机必须 await 不 await 后续操作会报错「相机未打开」,CameraInput.close(): Promise<void> 异步关闭相机 aboutToDisappear 生命周期调 close 释放资源,CameraInput.on('error', callback: (error: camera.CameraInputErrorCode) => void) 监听相机错误事件,CameraType enum 常量 CAMERA_TYPE_WIDE_ANGLE=0/CAMERA_TYPE_TELEPHOTO=1/CAMERA_TYPE_ULTRA_WIDE=2/CAMERA_TYPE_DEFAULT=3 不是字符串 'WIDE_ANGLE' enum 值是数字,React getUserMedia 打开相机直接返回 MediaStream 一步到位差异,鸿蒙 createCameraInput + open() 两步先工厂造 CameraInput 实例再 open 异步打开相机),CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂函数造 PreviewOutput 实例(PreviewOutput 是 interface 不能 new camera.PreviewOutput() 触发 'PreviewOutput' only refers to a type, but is being used as a value here 编译错,profile: Profile 必须用 getSupportedOutputCapability(cameras[0]).previewProfiles[0] 获取不能手动构造 Profile 对象 Profile 是 interface 不能 new 含 width: number/height: number/format: CameraFormat 字段,surfaceId: string 必须来自 XComponentgetXComponentSurfaceId() XComponent 是 ArkUI 原生组件渲染表面 surfaceId 是底层 Surface 的唯一标识字符串,CameraFormat enum 常量 CAMERA_FORMAT_RGBA_8888=3/CAMERA_FORMAT_YUV_420_SP=1003/CAMERA_FORMAT_JPEG=2000 不是字符串 'RGBA_8888' enum 值是数字,React <video srcObject={stream}> 直接用 <video> 元素显示预览浏览器渲染差异,鸿蒙 XComponent + PreviewOutput + surfaceId 三件套 XComponent 提供渲染表面 PreviewOutput 绑定 surfaceId 输出预览帧底层 SurfaceFlinger 渲染),CameraManager.createCaptureSession(): CaptureSession 工厂函数造 CaptureSession 实例(CaptureSession 是 interface 不能 new camera.CaptureSession() 触发 'CaptureSession' only refers to a type, but is being used as a value here 编译错,会话流程严格 5 步——beginConfig() 开始配置会话同步方法无返回值 → addInput(cameraInput: CameraInput): Promise<void> 添加 CameraInput 相机输入流异步 → addOutput(previewOutput: PreviewOutput): Promise<void> 添加 PreviewOutput 预览输出流异步 → commitConfig(): Promise<void> 提交配置异步 → start(): Promise<void> 启动会话异步预览开始,必须严格按 beginConfigaddInputaddOutputcommitConfigstart 顺序调用颠倒顺序或跳步会报错如 addInputaddOutput 报「会话未配置」错 commitConfigaddInput 报「会话已提交不能再配置」错,CaptureSession.stop(): Promise<void> 停止会话 aboutToDisappear 生命周期调,CaptureSession.release(): Promise<void> 释放会话资源避免内存泄漏,aboutToDisappear 生命周期必须调 stop() + close() + release() 释放资源相机硬件资源不释放会导致后续应用无法使用相机,React getUserMedia 直接返回 MediaStream 一步到位无会话流程差异,鸿蒙 CaptureSession 会话流程 5 步 Android Camera2 API 风格 CaptureSession 对应 Android CameraCaptureSession beginConfig/commitConfig 对应 Android SessionConfiguration)。getCameraManager 工厂造 CameraManager(interface 不能 new,context 必传)+ getSupportedCameras 同步获取 CameraDevice[](CameraDevice 是 interface 不能 new)+ CameraPosition enum 常量 CAMERA_POSITION_BACK=0/FRONT=1/UNSPECIFIED=2 不是字符串 enum 值数字 + createCameraInput 工厂造 CameraInput(interface 不能 new)+ open() 异步打开相机 + CameraType enum 常量 CAMERA_TYPE_WIDE_ANGLE=0/TELEPHOTO=1/ULTRA_WIDE=2/DEFAULT=3 不是字符串 + createPreviewOutput 工厂造 PreviewOutput(interface 不能 new)+ surfaceId 来自 XComponent + Profile 用 getSupportedOutputCapability().previewProfiles[0] + CameraFormat enum 常量 CAMERA_FORMAT_RGBA_8888=3/YUV_420_SP=1003/JPEG=2000 不是字符串 + createCaptureSession 工厂造 CaptureSession(interface 不能 new)+ 会话流程 5 步 beginConfig→addInput→addOutput→commitConfig→start 严格顺序 + aboutToDisappear 生命周期 stop+close+release 释放资源 是鸿蒙 6.1 @ohos.multimedia.camera 相机坑核心!

能力系列回链

  • 鸿蒙 7.0 新特性篇 1~17(沉浸式毛玻璃/Component3D/智能体框架/方舟引擎/星盾安全/星河互联/空间音频/可变字体/游戏快启/分布式数据盾/LTPO 可变帧率/AI 文档识别/多形态服务窗口/AI 反诈/机密计算/空间计算/小艺全面进化)
  • 鸿蒙 6.1 API 23 开发坑系列篇 1「ArkUI.modifier 装饰器坑」——attributeModifier + AttributeModifier 状态化节点修改器
  • 鸿蒙 6.1 API 23 开发坑系列篇 2「arkui.componentSnapshot 组件截图坑」——get/getSync/createFromBuilder 返回 image.PixelMap 像素图
  • 鸿蒙 6.1 API 23 开发坑系列篇 3「arkui.node 节点坑」——NodeController abstract class makeNode override + BuilderNode WrappedBuilder
  • 鸿蒙 6.1 API 23 开发坑系列篇 4「arkui.UIContext UI 上下文坑」——runScopedTask 不是 runScopedOnUiThread + 11 个子管理器
  • 鸿蒙 6.1 API 23 开发坑系列篇 5「arkui.observer UI 观察器坑」——uiObserver namespace 真名不是 observer + on type string literal
  • 鸿蒙 6.1 API 23 开发坑系列篇 6「@ohos.animator 动画器坑」——import @kit.ArkUI 不是 @ohos.animator + onFrame 驼峰不是废弃 onframe + getUIContext().createAnimator 不是废弃 animator.create + 持引用 + aboutToDisappear cancel
  • 鸿蒙 6.1 API 23 开发坑系列篇 7「@ohos.net.http HTTP 请求坑」——HttpDataType 常量是 STRING 不是 STRING_TYPE + HttpRequest 是 interface 不能 new + http.createHttp() 工厂造实例 + on/off 监听不是 addEventListener + header Record 不是 Headers + RequestMethod enum 不是字符串
  • 鸿蒙 6.1 API 23 开发坑系列篇 8「@ohos.file.fs 文件管理坑」——writeSync/readSync 是 namespace 顶层函数不是 File 实例方法 + 第一参传 file.fd 文件描述符 + ReadOptions 无 encoding 读 ArrayBuffer 原字节 + WriteOptions 带 encoding 写字符串指定编码 + closeSync(file) 传 File 不是 fd + OpenMode enum 不是 flags 数字
  • 鸿蒙 6.1 API 23 开发坑系列篇 9「@ohos.router 页面路由坑」——router.push/replace 废弃迁移 pushUrl/replaceUrl + RouterMode enum 常量 Standard/Single 不是字符串 + RouterOptions.url 绝对路径不是相对路径 + getParams 返回 Object 要 as Record 转型 + RouterState 真属性 index/name 不是 stackLength + getLength 返回 string 不是 number
  • 鸿蒙 6.1 API 23 开发坑系列篇 10「@ohos.promptAction 弹窗坑」——showToast/showDialog/showActionMenu 废弃迁移 getPromptAction + ToastType enum 常量 Default/Bottom/Center/Top 不是字符串 + ShowToastOptions.duration 单位 10ms 不是 1ms + showDialog 回调 onAccept/onCancel 不是 onConfirm/onAbort + DialogButton.action 不是 onClick 无 bgColor + showActionMenu buttons 上限 6 不是无限
  • 鸿蒙 6.1 API 23 开发坑系列篇 11「@ohos.measure 文本测量坑」——measureText 返回 number 不是 TextMetrics + measureTextSize 返回 SizeOptions 多行测量 + MeasureOptions 必填 textContent 不是 text + fontSize string 须带 fp/px 单位 + MeasureText static 废弃迁移 getMeasureUtils 实例方法
  • 鸿蒙 6.1 API 23 开发坑系列篇 12「@ohos.curves 动画曲线坑」——init/cubicBezier/spring/steps 废弃返回 string 迁移 initCurve 等返回 ICurve + ICurve interface 不能 new 用工厂函数造实例 + Curve enum 常量 Linear/Ease 等不是字符串 enum 值数字 + cubicBezierCurve 四 number 不是 cubic-bezier 字符串 + springCurve 四 number damping 越大震动越小 + customCurve 回调 fraction [0,1] 返回必须 [0,1]
  • 鸿蒙 6.1 API 23 开发坑系列篇 13「@ohos.multimedia.image 图片处理坑」——createImageSource 工厂造 ImageSource(interface 不能 new)+ PixelMapFormat enum 常量 ALPHA_8/RGB_565/RGBA_8888/ARGB_8888/RGB_888 不是字符串 + createPixelMap 创建空 PixelMap InitializationOptions 三必填 size+pixelFormat+editable + ImageSource.createPixelMap 带 DecodingOptions 解码指定尺寸/区域/旋转 + PixelMap.readPixelsToBuffer 读像素到 ArrayBuffer(不是 getImageData 返回 ImageData)+ createIncrementalSource + updateData 流式解码大图避免 OOM
  • 鸿蒙 6.1 API 23 开发坑系列篇 14「@ohos.multimedia.camera 相机坑」——getCameraManager 工厂造 CameraManager(interface 不能 new,context 必传)+ getSupportedCameras 同步获取 CameraDevice[](CameraDevice 是 interface 不能 new)+ CameraPosition enum 常量 CAMERA_POSITION_BACK=0/FRONT=1/UNSPECIFIED=2 不是字符串 + createCameraInput 工厂造 CameraInput(interface 不能 new)+ open() 异步打开相机 + CameraType enum 常量 CAMERA_TYPE_WIDE_ANGLE=0/TELEPHOTO=1/ULTRA_WIDE=2/DEFAULT=3 不是字符串 + createPreviewOutput 工厂造 PreviewOutput(interface 不能 new)+ surfaceId 来自 XComponent + Profile 用 getSupportedOutputCapability().previewProfiles[0] + CameraFormat enum 常量 CAMERA_FORMAT_RGBA_8888=3/YUV_420_SP=1003/JPEG=2000 不是字符串 + createCaptureSession 工厂造 CaptureSession(interface 不能 new)+ 会话流程 5 步 beginConfig→addInput→addOutput→commitConfig→start 严格顺序 + aboutToDisappear 生命周期 stop+close+release 释放资源(本文)
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐