现场采集人员打开取景页后,看到预览区域有了画面,或发现取景范围似乎发生变化,很容易说“系统已经帮我自动构图”。对于 AUTO_FRAMING 来说,这个结论通常过早:预览启动、设备会话声明能力、页面请求系统控制中心接管、系统实际调整画面,分别属于不同层次。页面能把它们混成一个绿色状态,用户就会不知道何时该等待、何时该自己调整取景、何时只能记录待验证。

本页以“配电箱巡检”等本地任务样本组织取景前检查,分别展示权限、后摄与预览 Profile、AUTO_FRAMING 能力、回退原因和人工构图确认。它不替用户判断画面是否已经达到业务所需构图,也不把一次本地确认写成图像保存或后台采集完成;它只让用户在每一个状态下知道当前页面究竟获得了什么事实。

一、预览区域有变化时,用户最容易误会什么

1.1 预览启动不等于系统已完成自动构图

页面的取景区域先等待 XComponent 的 Surface 就绪。只有 Surface 已就绪,用户才能点击“启动真实预览”,随后才可能进入权限请求、设备查询和视频会话创建。即使最后页面显示“真实后摄预览运行中”,它也只表示预览会话已走到当前状态,并不表示系统控制中心已经改变了画面构图。

对于采集人员,这两种状态的动作不同:预览尚未启动时,应先完成运行条件检查;预览正在运行而自动构图仍待观察时,应维持对当前画面的人工判断。若页面把两者都写成“构图成功”,用户可能在没有获得系统能力证据时停止调整取景,反而增加采集失败或遗漏主体的风险。

在这里插入图片描述

场景解说:本图待展示任务队列、等待 Surface 的取景区和启用前判定。它能证明页面尚未开始真实相机预览,不能证明任何设备支持或执行了自动构图。

1.2 “能力可用”与“画面已变化”之间仍隔着系统行为

当前工程会在视频会话配置后查询控制中心能力。若会话声明支持 AUTO_FRAMING,页面将请求启用系统控制中心,并显示“AUTO_FRAMING 可用,已请求系统控制中心接管;实际构图由系统决定”。这句话有两个部分:前半句是当前代码可验证的请求链路,后半句是用户仍需保留的观察边界。

系统控制中心是否在某台设备、某个场景下真正调整取景范围,不能从“已请求接管”推导出来。没有对应的设备预览记录时,页面最多可提示“等待系统能力观察”;它不能把控制中心能力声明写成“目标对象已居中”,更不能把画面中看起来居中的主体解释为该能力造成的结果。

1.3 人工调整也会改变画面,不能被页面偷换成系统结果

现场人员在取景时会自然移动设备、改变站位或重新选择任务。这些动作同样会改变预览画面,却不属于 AUTO_FRAMING 的系统效果。工程保留“人工构图确认”入口,正是为了让用户在能力未声明或控制中心无法启用时仍能继续任务,而不是把人工调整藏进“自动构图已完成”的标签里。

产品上应给两类状态不同的名称:系统能力请求可写为“已请求系统控制中心”,人工操作可写为“人工构图已确认”。前者说明页面做了什么请求,后者说明人根据当前预览做了什么选择。两者都不直接说明画面质量、图像保存或业务任务已经完成。

二、页面怎样把自动构图的前置状态拆开

2.1 Surface 未就绪时,不能把启动按钮当作相机已打开

工程在取景承载区域加载完成时,才把 surfaceReady 设为真,并记录“XComponent Surface 已就绪,可请求真实后摄预览”。如果用户提前启动,页面状态会停在“Surface 尚未就绪”,并记录本次没有启动相机的原因。

if (!this.surfaceReady) {
  this.previewState = 'Surface 尚未就绪';
  this.markRuntime('未启动相机:XComponent Surface 未就绪');
  return;
}

这段代码能证明页面把可承载预览的 Surface 作为相机启动前提,并在条件不满足时不继续创建会话。它不能证明 Surface 就绪后权限一定会通过,也不能证明设备一定提供后摄和 AUTO_FRAMING 能力。

这个提示避免用户在黑色预览区域反复点击“启动真实预览”。对用户来说,“等待 Surface”并非相机故障结论,而是页面还没有准备好接收预览输出;下一步应等待页面就绪,而不是先去判断自动构图是否有效。

2.2 权限是相机启动条件,不是自动构图能力证明

Surface 就绪后,工程会向用户请求 ohos.permission.CAMERA。若授权通过,页面把权限写为“已授予”;若拒绝,则停在“权限未授予,未启动预览”,并提示用户到系统设置重新授权。

const result = await atManager.requestPermissionsFromUser(
  getContext(this), ['ohos.permission.CAMERA']
);
const granted = result.authResults.length > 0 && result.authResults[0] === 0;
this.permissionState = granted ? '已授予' : '被拒绝';

这段代码能证明页面会请求并保存本次相机权限的返回状态。它不能证明后摄设备存在,不能证明视频预览已运行,也不能证明系统控制中心支持或启用了 AUTO_FRAMING

页面不能在权限变绿后写“自动构图已开启”。更恰当的下一步文案是“已取得相机权限,等待查询设备与预览能力”。用户据此知道授权只是放行下一段,不会把系统弹窗的同意动作误当作画面效果。

在这里插入图片描述

场景解说:本图待展示 Surface 就绪后启动真实预览、请求相机权限以及授权拒绝时的反馈。它能证明页面处在启动前检查或被权限阻断,不能证明自动构图能力已被声明。

2.3 后摄与预览 Profile 缺一项,用户应看到具体回退原因

获得权限后,工程从 CameraManager 的支持设备中选择后摄,再取得普通视频场景的输出能力和第一个预览 Profile。若没有后摄,页面写“未发现后摄设备”;若没有预览 Profile,则写“设备未提供视频预览输出能力”。它们都让启动流程停在不可用状态,而不是继续请求自动构图。

const device = this.selectBackCamera(manager.getSupportedCameras());
if (device === undefined) {
  this.deviceState = '未发现后摄设备';
  this.previewState = '设备不支持后摄预览';
  return;
}
const capability = manager.getSupportedOutputCapability(device, camera.SceneMode.NORMAL_VIDEO);
const previewProfile = capability.previewProfiles.length > 0 ? capability.previewProfiles[0] : undefined;

这段代码能证明页面先查找真实后摄设备与预览输出条件,再进入 VideoSession 创建。它不能证明所选 Profile 已经成功显示画面,也不能证明设备支持任何控制中心效果。

对产品来说,具体原因比“相机异常”更可行动:没有后摄时,用户需要换到合适的设备;没有预览 Profile 时,不能把问题交给人工构图确认;只有预览能力具备且会话启动后,才有资格继续阅读 AUTO_FRAMING 状态。每一层都保留自己的出口,用户不会为了继续任务而把一个不支持的设备硬说成已启用自动构图。

2.4 页面必须先有预览会话,才谈得上控制中心查询

后摄和 Profile 可用后,工程才创建 CameraInputPreviewOutputVideoSession,将输入和输出写入配置并提交。随后调用 setupFocusAndFraming() 查询控制中心支持情况,再启动会话。也就是说,AUTO_FRAMING 不是一个孤立开关;它依赖当前会话已按真实设备能力完成配置。

这条顺序对读者的意义在于:不要在相机还没给出可用预览时就问“自动构图为什么没生效”。当前页面设计把前置条件放进启用前判定区,让用户依次看到权限、后摄与 Profile、自动构图能力、回退原因和人工确认时间。它没有省略前面的相机条件,也没有用一个状态色覆盖整条启动链。

三、AUTO_FRAMING 能力被声明时,页面究竟可以说到哪里

3.1 控制中心支持是能力门槛,不是画面验收

会话创建后,工程先调用 session.isControlCenterSupported()。如果控制中心不支持,页面进入人工构图回退;如果支持,才读取 getSupportedEffectTypes(),检查结果中是否含有 camera.ControlCenterEffectType.AUTO_FRAMING

if (!session.isControlCenterSupported()) {
  this.enterManualFramingFallback('控制中心不支持,切换人工构图');
  return;
}
const supportedEffects = session.getSupportedEffectTypes();
if (!supportedEffects.includes(camera.ControlCenterEffectType.AUTO_FRAMING)) {
  this.enterManualFramingFallback('AUTO_FRAMING 未声明,切换人工构图');
  return;
}

这段代码能证明页面把“控制中心可用”和“当前会话声明 AUTO_FRAMING”分成两道检查,任一项不满足就给出明确的人工回退原因。它不能证明设备声明能力后一定会对本次预览调整构图,也不能说明页面已经观察到任何画面变化。

产品提示中,“系统支持自动构图”仍应带上来源范围,例如“当前会话声明支持”。这样用户知道它是能力查询的结果,不会把不同设备、不同会话或下一次重新启动时的表现都当成同一条已验证结论。

在这里插入图片描述

场景解说:本图待展示启用前判定中的控制中心能力、AUTO_FRAMING 状态和回退原因。它能证明页面读取到的会话支持信息,不能证明实际画面已经自动调整。

3.2 启用控制中心是一次请求,不是系统效果回执

AUTO_FRAMING 出现在支持效果中,工程调用 session.enableControlCenter(true),把构图模式设为 system_available,并在页面写明“已请求系统控制中心接管;实际构图由系统决定”。

try {
  session.enableControlCenter(true);
  this.framingMode = 'system_available';
  this.autoFramingState = 'AUTO_FRAMING 可用,已请求系统控制中心接管;实际构图由系统决定';
} catch (error) {
  this.enterManualFramingFallback(`控制中心启用失败,切换人工构图:${formatRuntimeError(error as Error)}`);
}

这段代码能证明页面对控制中心发起了启用请求,并将“启用异常”分流到人工构图回退。它不能证明系统控制中心已经接管成功,更不能证明画面中的对象已被自动定位、缩放或居中。

对现场用户而言,页面应该把这一时刻提示为“等待系统能力观察”,而非“构图已完成”。若后续有支持设备上的实际预览录屏或可重复截图,才可以把“画面是否发生系统调整”作为独立证据补入;在此之前,用户仍应按当前画面人工确认主体是否落在需要的位置。

3.3 预览运行中的状态,不替用户判断采集是否可开始

工程成功启动 VideoSession 后,会显示“真实后摄预览运行中”。当构图模式是系统可用时,本地任务状态写为“预览会话已启动,现场人员可确认取景稳定后开始采集”;当处于人工回退时,则写为“预览可用,等待人工构图确认”。

这两种文案共同避免了“预览运行中 = 可以直接交付图像”的误解。预览运行只表明当前会话阶段;是否应开始采集,仍需要现场人员根据任务对象、画面完整度和业务规则判断。页面没有任何保存图片、上传文件或业务回写代码,因此不能用预览状态推导采集已完成。

四、自动构图不可用时,人工构图如何接住用户任务

4.1 回退不是一个笼统失败,而是四种不同缺口

本页可能在不同阶段无法继续系统自动构图:相机权限被拒绝、没有后摄、没有预览 Profile、控制中心不支持、AUTO_FRAMING 未声明,或启用控制中心时发生错误。其中前几项会阻断预览启动;后几项会在预览仍可继续的前提下进入人工构图回退。

用户需要看见这一区别。没有后摄或预览 Profile 时,不应出现“确认人工构图”按钮可用,因为页面连可供人工观察的真实预览都未建立;只有状态为 previewing 且构图模式为 manual_pending 时,按钮才允许操作。把回退条件写清,是为了让用户不在空白页面上做一项看似完成的确认。

4.2 进入人工构图回退后,页面保留预览而不是停止任务

控制中心不支持、能力未声明或启用失败时,工程调用 enterManualFramingFallback():将构图模式标为 manual_pending,写入具体回退原因,并提示“预览会话继续启动中;运行后可进行人工构图确认”。

private enterManualFramingFallback(reason: string): void {
  this.framingMode = 'manual_pending';
  this.framingFallbackReason = reason;
  this.autoFramingState = `${reason};预览继续使用人工构图`;
  this.localTaskState = '自动构图不可用,预览会话继续启动中;运行后可进行人工构图确认';
}

这段代码能证明页面把系统能力不可用转换为可解释的本地回退状态,并仍尝试保留预览会话供人工取景。它不能证明人工已经看清画面,也不能证明人工构图符合任何业务质量标准。

这类回退对产品体验很关键。用户不需要在“系统不支持”后重新寻找另一个页面或猜测任务是否作废;页面告诉他能继续做什么,也把不能自动完成的部分保留为明确边界。对不同失败原因,应显示不同文案,避免把“设备没有后摄”和“自动构图未声明”都压成一个无法行动的“相机异常”。

在这里插入图片描述

场景解说:本图待展示 AUTO_FRAMING 未声明或控制中心不可用后的回退原因、真实预览状态和“确认人工构图”入口。它能证明页面提供了人工回退路径,不能证明画面已经满足采集质量。

4.3 人工构图确认记录的是用户动作,不是画面质量结论

“确认人工构图”只有在真实预览运行中且当前正处于人工回退时才允许执行。执行后,工程记录一个本地时间,并把任务状态写为“人工构图已确认,仅登记当前页面本地状态,不回写后台”。

if (this.phase !== 'previewing' || this.framingMode !== 'manual_pending') {
  this.localTaskState = '人工构图确认被阻断:请先启动处于回退状态的真实预览';
  return;
}
this.framingMode = 'manual_confirmed';
this.manualFramingConfirmedAt = timestamp();
this.localTaskState = '人工构图已确认,仅登记当前页面本地状态,不回写后台';

这段代码能证明页面限制人工确认发生的前置状态,并保存用户在当前会话做出的本地动作。它不能证明图像清晰、主体完整、照片已经拍摄或文件已经保存;更不能说明系统已重新启用 AUTO_FRAMING

用户看到“人工构图已确认”时,应把它理解为“我选择依据当前预览继续下一步”,而不是“相机自动完成了构图”。这一区分让现场人员既能保持任务连续,也不会因为一次点击而失去后续质检、拍摄和留存所需的人工判断。

4.4 切换任务和释放会话,会结束当前页面状态

工程的任务队列是本地演示样本,切换任务只更新页面的当前任务描述,不写入后台。用户释放会话时,工程停止并释放会话、预览输出和相机输入,然后把页面状态改为“会话已释放”。这些行为提醒用户:当前页面中的能力查询、回退原因和人工确认时间都属于一次运行会话,不能替代持续保存的采集记录。

因此需要交接时,用户应在释放会话前保留当前任务名、权限与设备查询结果、构图模式、回退原因和人工确认时间;若没有其他经过核验的业务系统承接这些内容,就不能期待重新打开页面后仍能从本地状态恢复同一条取景判断。

五、在尚无设备实测时,用户应如何阅读这页工程

5.1 当前能核对的是源码状态链,不是运行结论

当前页面已登记路由 pages/article05/CameraAutoFramingFocusPage,源码可以核对 Surface 前置、相机权限、后摄和预览 Profile 查询、VideoSession 创建、控制中心支持查询、AUTO_FRAMING 声明检查、启用请求与人工回退。但本过程稿尚未取得构建成功、页面启动、权限弹窗、真实后摄预览或系统控制中心效果记录。

因此,本文中“可用”“已请求”“回退”“人工确认”等表述均指代码设计和页面本地状态应如何呈现,不能被读作某台设备已经完成的运行结果。后续补拍时,模拟器截图最多先证明页面路由、构建、权限反馈和本地状态;实际构图变化仍需要支持设备上的独立观察证据。

5.2 模拟器和支持设备各自回答不同问题

模拟器或通用运行环境可优先验证:页面是否能进入、Surface 是否就绪、点击启动后权限状态怎样显示、设备查询或失败原因如何反馈、人工回退入口是否被正确阻断或放行。这些证据适合检查产品文案是否让用户知道下一步。

支持设备则用于观察更严格的问题:后摄预览是否存在、当前会话是否声明 AUTO_FRAMING、启用控制中心后系统是否实际调整构图。后一个问题不能被前一个环境代替;即使模拟器顺利启动页面,也不能得出自动构图已经生效。同样,单张设备预览图也不能单独证明由 AUTO_FRAMING 引起了何种变化,仍需要操作前后和能力状态相邻取证。

5.3 推荐交接摘要:保留能力层级,而不是只写“相机正常”

当这页进入真实测试或现场使用后,交接信息可按五层组织:

  1. 运行入口:页面是否启动、Surface 是否就绪、当前任务只是本地样本还是已有其他业务记录。
  2. 设备门槛:相机权限、后摄和预览 Profile 各自的状态与错误文本。
  3. 能力请求:控制中心是否支持、AUTO_FRAMING 是否出现在本次会话声明中、是否已请求启用。
  4. 观察结果:是否获得支持设备上的实际构图观察;未观察时明确标“待设备核验”。
  5. 回退动作:如已走人工构图,记录回退原因和人工确认时间,并注明它不等于拍摄、保存或后台完成。

例如可以写:“本页已进入预览前检查,设备能力结果待实测;若本次会话未声明 AUTO_FRAMING,则保留预览并转人工构图,人工确认仅为当前页面本地状态;尚无支持设备记录,不认定系统已自动调整画面。”这种摘要既让下一位人员知道任务并未丢失,也防止把候选工程的源码能力包装成已经交付的现场效果。

必要条件|运行门禁

G1:SDK/API门禁

确认 HarmonyOS 6.1.1 API 24 已安装,Hvigor 能构建 entry 模块。

在这里插入图片描述
在这里插入图片描述

G2:Kit门禁

确认本文页面的 Kit import 可解析,并使用 API 24 支持的接口。

G3:模块/页面门禁

确认 Stage 模块、页面路由、设备类型和相关模块配置完整。

G4:权限门禁

确认静态声明存在;Camera/AI字幕等运行时能力在真正调用前完成动态授权。

在这里插入图片描述

G5:系统能力门禁

确认目标设备声明并实际提供所需摄像头、麦克风、地图、视觉或文件能力。任一门禁未通过,停止进入核心操作。

在这里插入图片描述

MapKit文章在 G5 放行前增加服务配置门禁:AppGallery Connect 中已选择正确项目,应用包名和签名证书与工程一致,MapKit 服务已开通且应用服务凭据/授权配置已完成。不得在文章或源码中暴露服务密钥。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐