T-M3-07 PhotoProvider:getphoto 批量下载到资源根 photos/(file:// 白名单内) → 出站 getphoto[{pid,photourl}],复用 Downloader 并行
T-M3-08 ShakeProvider:startshake/SwitchShake/stopshake,@ohos.sensor 加速度合力阈值检测+节流,~1s 后出站 shakeEnd(空串),反馈震动
T-M3-11 ScanProvider:opensaoma → @kit.ScanKit 默认界面扫码(免权限) → 出站 getsaomaData(originalValue)
T-M3-12 CameraProvider:opencamera → @kit.CameraKit cameraPicker.pick(免权限) → 出站 getcameraaAddress(resultUri)
T-M3-09 LocationProvider:startlocation(连续/单次,用时申请权限)/getlocationinfo(同步) → geoLocationManager 定位+逆地理编码 →
出站 getlocationinfo(MaplocationInfo;错误码 0/-1未就绪/-2权限拒绝)
module.json5 增 ACCELEROMETER/LOCATION/APPROXIMATELY_LOCATION;组装根装配 5 者
devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
49 lines
1.9 KiB
Plaintext
49 lines
1.9 KiB
Plaintext
/**
|
||
* 相机拍照能力(契约 §8.8/§9,T-M3-12)。@kit.CameraKit CameraPicker。
|
||
* - opencamera:拉起系统相机拍照 → 出站 getcameraaAddress(拼写原样双 a,照片 uri 裸串)。
|
||
* 系统相机选择器无需申请相机权限。
|
||
*/
|
||
import { camera, cameraPicker } from '@kit.CameraKit';
|
||
import { BusinessError } from '@kit.BasicServicesKit';
|
||
import { common } from '@kit.AbilityKit';
|
||
import { BridgeController } from 'feature_bridge';
|
||
import { InboundHandlers, OutboundHandlers } from 'contracts';
|
||
import { Logger } from 'common';
|
||
import { CapabilityContext, CapabilityProvider } from '../core/CapabilityProvider';
|
||
|
||
export class CameraProvider implements CapabilityProvider {
|
||
readonly name: string = 'camera';
|
||
private readonly log: Logger = Logger.tag('CameraProvider');
|
||
private bridge: BridgeController | undefined = undefined;
|
||
private context: common.UIAbilityContext | undefined = undefined;
|
||
|
||
register(bridge: BridgeController, ctx: CapabilityContext): void {
|
||
this.bridge = bridge;
|
||
this.context = ctx.uiAbilityContext;
|
||
bridge.registerHandler(InboundHandlers.OpenCamera, (_d: string, _cb: (resp: string) => void) => {
|
||
this.capture();
|
||
});
|
||
}
|
||
|
||
private capture(): void {
|
||
const ctx = this.context;
|
||
if (ctx === undefined) {
|
||
return;
|
||
}
|
||
const profile: cameraPicker.PickerProfile = {
|
||
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,
|
||
};
|
||
cameraPicker.pick(ctx, [cameraPicker.PickerMediaType.PHOTO], profile)
|
||
.then((result: cameraPicker.PickerResult) => {
|
||
if (result.resultCode === 0 && result.resultUri !== '') {
|
||
this.bridge?.callHandler(OutboundHandlers.GetCameraAddress, result.resultUri);
|
||
} else {
|
||
this.log.i(`camera canceled: resultCode=${result.resultCode}`);
|
||
}
|
||
})
|
||
.catch((e: BusinessError) => {
|
||
this.log.i(`camera failed: ${e.code} ${e.message}`);
|
||
});
|
||
}
|
||
}
|