在调用Vision API interactiveLiveness进入活体检测页面,点击活体检测页面返回或者侧滑手机返回原来的页面,原来页面的沉浸式效果会消失,运行的demo如下:
import { abilityAccessCtrl, Context } from '@kit.AbilityKit';
import { interactiveLiveness } from '@kit.VisionKit';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = 'FaceManager';
export class FaceManager {
// 校验CAMERA权限
public static privateStartDetection(context: Context) {
let res = abilityAccessCtrl.createAtManager().verifyAccessTokenSync(100, 'ohos.permission.CAMERA');
if (res === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
FaceManager.privateRouterLibrary();
} else {
abilityAccessCtrl.createAtManager()
.requestPermissionsFromUser(context, ['ohos.permission.CAMERA'], (err, res) => {
console.info(TAG, `res==${JSON.stringify(res)}`);
for (let i = 0; i < res.permissions.length; i++) {
if (res.permissions[i] === 'ohos.permission.CAMERA' && res.authResults[i] === 0) {
FaceManager.privateRouterLibrary();
}
}
});
}
}
// 路由跳转到人脸活体验证控件
public static privateRouterLibrary() {
console.info(TAG, `camera open time start1==${new Date().getTime()}`);
let routerOptions: interactiveLiveness.InteractiveLivenessConfig = {
'isSilentMode': 'INTERACTIVE_MODE' as interactiveLiveness.DetectionMode,
'actionsNum': 1
};
interactiveLiveness.startLivenessDetection(routerOptions).then((DetectState: boolean) => {
console.info(TAG, `DetectState==${DetectState}`);
}).catch((e: BusinessError) => {
console.info(TAG, `DetectState1111==${JSON.stringify(e)}`);
});
}
}
@Entry
@Component
struct Index {
build() {
Column() {
Text("打开人脸")
.id('HelloWorld1')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
}).onClick(()=>{
const context = this.getUIContext()?.getHostContext();
if (context) {
FaceManager.privateStartDetection(context);
} else {
console.error('FaceManager', 'Context is undefined');
}
})
}
.height('100%')
.width('100%').justifyContent(FlexAlign.Center)
.backgroundColor(Color.Orange)
}
} 通过配置组件的expandSafeArea属性来扩展安全区域,可以实现页面的沉浸式效果。同时需注意一些限制避免沉浸式效果不生效:
通过设置expandSafeArea属性向顶部和底部扩展安全区域以此达到沉浸式效果,具体参考以下代码:
import { abilityAccessCtrl, Context } from '@kit.AbilityKit';
import { interactiveLiveness } from '@kit.VisionKit';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = 'FaceManager';
export class FaceManager {
// 校验CAMERA权限
public static privateStartDetection(context: Context) {
let res = abilityAccessCtrl.createAtManager().verifyAccessTokenSync(100, 'ohos.permission.CAMERA');
if (res === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
FaceManager.privateRouterLibrary();
} else {
abilityAccessCtrl.createAtManager()
.requestPermissionsFromUser(context, ['ohos.permission.CAMERA'], (err, res) => {
console.info(TAG, `res====${JSON.stringify(res)}`);
for (let i = 0; i < res.permissions.length; i++) {
if (res.permissions[i] === 'ohos.permission.CAMERA' && res.authResults[i] === 0) {
FaceManager.privateRouterLibrary();
}
}
});
}
}
// 路由跳转到人脸活体验证控件
public static privateRouterLibrary() {
console.info(TAG, `camera open time start1===${new Date().getTime()}`);
let routerOptions: interactiveLiveness.InteractiveLivenessConfig = {
'isSilentMode': 'INTERACTIVE_MODE' as interactiveLiveness.DetectionMode,
'actionsNum': 1
};
interactiveLiveness.startLivenessDetection(routerOptions).then((DetectState: boolean) => {
console.info(TAG, `DetectState===${DetectState}`);
}).catch((e: BusinessError) => {
console.info(TAG, `DetectState1111===${JSON.stringify(e)}`);
});
}
}
@Entry
@Component
struct FaceDetectionPage {
build() {
Column() {
Text('打开人脸')
.id('HelloWorld1')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(() => {
const context = this.getUIContext()?.getHostContext();
if (context) {
FaceManager.privateStartDetection(context);
} else {
console.error(TAG, 'Context is undefined');
}
});
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.White)
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]);
}
} Q:人脸活体检测是否支持前后置摄像头?
A:目前人脸活体检测仅支持前置摄像头,不支持后置摄像头。
Q:人脸活体检测是否金融级安全,是否支持炫彩,防注入攻击?
A:目前动作活体检测能力已经是金融支付级别的安全等级了,支持防注入攻击暂不支持炫彩。
Q:如何实现人脸活体检测功能?
A:可直接参考官网人脸活体检测API文档。
Q:静默活体人脸检测与动态活体人脸检测的区别是什么?
A:静默活体的安全等级低,检测的是图片,是无法区分图片和真人的。动作活体检测支持实时捕捉人脸,需要用户配合做指定动作就可以判断是真实活体,安全性比较高。
Q:如何在应用中接入生物特征能力?
A:应用接入生物特征能力分为两种。一种是纯本地生物特征接入,使用User Authentication Kit即可。另一种是在线身份认证协议的接入,这种方式本身系统已经完成FIDO和IIFAA协议和本地身份认证的对接,因此只需要调用Online Authentication Kit,具体可参考用户认证服务和人脸活体检测。
Q:活体检测服务是否有进行本人认证?
A:人脸活体检测支持实时捕捉人脸,需要用户配合做指定动作就可以判断是真实活体,还是非活体攻击(比如:打印图片、人脸翻拍视频以及人脸面具等),并没有进行本人认证。当前活体检测成功后会返回最具活体特征的图片,如果要进行本人认证,需开发者自行使用该图片进行后续处理。
Q:活体检测是否可以横屏使用?
A:目前不支持。
Q:人脸活体检测时,输入参数设为空值或自定义测试值,报错17630001。
A:17630001报错是参数格式不对,人脸活体检测SDK不支持自行伪造假输入参数获取返回值,只能使用真实的数据接口,才能去初始化SDK拉起摄像头,通过封装好的回调去获取相应的数据。