Commit 9a728f77 by sikang

version level up

parent 8e1fdae6
import java.lang.reflect.Type
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
// These docs use an open ended version so that our plugin
// can be updated quickly in response to Android tooling updates
// We recommend changing it to the latest version from our changelog:
// https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.library'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
signingConfigs {
testsign {
keyAlias 'testsign'
keyPassword 'testsign'
storeFile file('testsign.jks')
storePassword 'testsign'
}
}
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 3
versionName "1.10.e"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
versionName "1.10.m"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
repositories {
flatDir {
dirs 'libs'
signingConfig signingConfigs.testsign
}
}
}
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
......@@ -34,10 +63,7 @@ dependencies {
api(name: 'liblivenessdetector2-release', ext: 'aar')
api(name: 'liblivenessdetectionview2-release', ext: 'aar')
api(name: 'libcommon-release', ext: 'aar')
api("com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion", {
exclude module: 'support-v4'
})
api("com.android.support:percent:$rootProject.ext.supportLibraryVersion", {
exclude module: 'support-v4'
})
api "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
api 'com.google.android.gms:play-services-appindexing:8.4.0'
api "com.android.support:percent:$rootProject.ext.supportLibraryVersion"
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.oliveapp.liveness.sample">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<!--<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />-->
<!--<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--<uses-permission android:name="android.permission.READ_PHONE_STATE" />-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<!--<uses-permission android:name="android.permission.VIBRATE" />-->
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application>
<activity android:name=".SampleLaunchActivity"
android:screenOrientation="portrait">
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--</intent-filter>-->
</activity>
<activity android:name=".register.SampleImageCaptureActivity"
android:screenOrientation="portrait"/>
<activity android:name=".SettingActivity"
android:screenOrientation="portrait"/>
<activity android:name=".register.SampleChooseCameraActivity"
android:screenOrientation="portrait"/>
<activity android:name=".register.SampleCameraResultActivity"
android:screenOrientation="portrait"/>
<activity
android:name="SampleStartActivity"
android:label="@string/oliveapp_app_name"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity android:name=".liveness.SampleLivenessActivity"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity
android:name="SampleUnusualResultActivity"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity
android:name=".idcard_captor.SampleIdcardCaptorActivity"
android:screenOrientation="portrait" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE"
tools:node="remove" />
<uses-permission
android:name="android.permission.VIBRATE"
tools:node="remove" />
<uses-permission
android:name="android.permission.RECORD_AUDIO"
tools:node="remove" />
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
tools:node="remove" />
<application>
<activity
android:name=".idcard_captor.SampleIdcardResult"
android:screenOrientation="portrait" />
<activity android:name="SampleSaaSResultActivity"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<meta-data
android:name="io.fabric.ApiKey"
android:value="a5743d4d09caed055bc5d622e1bfe69a509d1add" />
</application>
</manifest>
\ No newline at end of file
package com.oliveapp.liveness.sample;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.liveness.sample.register.SampleChooseCameraActivity;
public class SampleLaunchActivity extends Activity {
public static final String TAG = SampleLaunchActivity.class.getSimpleName();
private Button mCameraButton;
private Button mLivenessButton;
private Button mSettingButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
// 如果有设置全局包名的需要, 在这里进行设置
// PackageNameManager.setPackageName();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_launch);
mCameraButton = (Button) findViewById(R.id.startButton);
mLivenessButton = (Button) findViewById(R.id.livenessButton);
mSettingButton = (Button) findViewById(R.id.settingButton);
mCameraButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(myself(), SampleChooseCameraActivity.class);
startActivity(i);
}
});
mLivenessButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(myself(), SampleStartActivity.class);
startActivity(i);
}
});
mSettingButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(myself(), SettingActivity.class);
startActivity(i);
}
});
requestPermission();
}
private Activity myself() {
return this;
}
//========================================================请求权限===================================================//
private static final int PERMISSION_READ_EXTERNAL_STORAGE = 101;
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 102;
private static final int PERMISSION_CAMERA = 103;
private boolean requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_WRITE_EXTERNAL_STORAGE);
return false;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_READ_EXTERNAL_STORAGE);
return false;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_CAMERA);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
try {
switch (requestCode) {
case PERMISSION_CAMERA: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(this, "没有摄像头权限我什么都做不了哦!", Toast.LENGTH_LONG).show();
}
break;
}
case PERMISSION_READ_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(this, "请打开存储读写权限,确保APP正常运行", Toast.LENGTH_LONG).show();
}
break;
}
case PERMISSION_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(this, "请打开存储读写权限,确保APP正常运行", Toast.LENGTH_LONG).show();
}
break;
}
}
} catch (Exception e) {
LogUtil.e(TAG, "Failed to request Permission", e);
}
}
}
package com.oliveapp.liveness.sample;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.liveness.sample.R;
import com.oliveapp.liveness.sample.SampleLaunchActivity;
import com.oliveapp.liveness.sample.liveness.SampleLivenessActivity;
import com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.DecimalFormat;
public class SampleSaaSResultActivity extends Activity implements View.OnClickListener {
public static final String TAG = SampleSaaSResultActivity.class.getSimpleName();
private ListView mListview;
private ImageView mImageViewClose;
private ImageView mImageViewOpen;
private Button mFinishBtn;
private Button mRetryBtn;
private Button mReturnBtn;
/**
* 存储传回的分析数据
*/
public static String mResultJsonString;
/**
* mIfPassed : 每一个项目是否通过
* mDetail: 每一个项目得到的具体分数
* ITEMS : 显示的所有项目名称
* IFPASSKEY : 用于从json中获取“是否通过”数据的key
* DETAILKEY : 用于从json获取“具体分数”的key
* mImages : 存储传回的两张照片
* mIsFailed : 存储本次检测是否通过
*/
private static final String[] ITEMS = {"大礼包照片是否同一个人", "是否通过防屏幕拍摄", "是否通过防照片翻拍", "是否通过防眼部遮挡", "是否通过防孔洞面具"};
private String[] DETAILKEY = {"is_anti_screen_check_score", "is_anti_picture_check_score", "is_anti_eye_blockage_check_score", "is_anti_hole_check_score"};
private String[] IFPASSKEY = {"is_same_person", "is_anti_screen_check_passed", "is_anti_picture_check_passed", "is_anti_eye_blockage_check_passed", "is_anti_hole_check_passed"};
private boolean[] mIfPassed = new boolean[IFPASSKEY.length];
private String[] mDetail = new String[DETAILKEY.length];
/**
* 大礼包回传两张照片
*/
private static final int BITMAPCOUNT = 2;
private Bitmap[] mImages = new Bitmap[BITMAPCOUNT];
private boolean mIsFailed = false;
private boolean mParseJsonFailed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 先解析json数据,若有一项不通过就表示失败
*/
try {
JSONObject json = new JSONObject(mResultJsonString);
JSONObject queryResult = json.getJSONObject("query_image_package_result");
for (int i = 0; i < IFPASSKEY.length; i++) {
mIfPassed[i] = queryResult.getBoolean(IFPASSKEY[i]);
if (!mIfPassed[i]) {
mIsFailed = true;
}
if (i != DETAILKEY.length) {
mDetail[i] = new DecimalFormat("#.#####").format(queryResult.getDouble(DETAILKEY[i]));
}
}
/**
* 解析返回的照片,并设置界面
*/
JSONArray images = queryResult.getJSONArray("query_image_contents");
if (images.length() >= BITMAPCOUNT) {
String image1Base64 = (String) images.get(0);
byte[] image1 = Base64.decode(image1Base64, Base64.NO_WRAP);
mImages[0] = BitmapFactory.decodeByteArray(image1, 0, image1.length);
String image2Base64 = (String) images.get(1);
byte[] image2 = Base64.decode(image2Base64, Base64.NO_WRAP);
mImages[1] = BitmapFactory.decodeByteArray(image2, 0, image2.length);
}
} catch (JSONException e) {
LogUtil.e(TAG, e.toString());
mParseJsonFailed = true;
} finally {
}
/**
* 设置全屏
*/
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
/**
* 决定显示哪个页面
*/
LogUtil.e(TAG, "setContentView");
setContentView(decideWhichLayout());
LogUtil.e(TAG, "after setContentView");
initViews();
/**
* 数据解析没有异常,就尝试显示数据
*/
if (!mParseJsonFailed) {
/**
* 显示分析数据
*/
OliveappSaasResultAdapter adapter = new OliveappSaasResultAdapter(this);
mListview.setAdapter(adapter);
}
}
//=================================初始化===============================//
public void initViews() {
mListview = (ListView) findViewById(R.id.oliveapp_liveness_saas_list);
mImageViewClose = (ImageView) findViewById(R.id.oliveapp_liveness_result_close);
mImageViewOpen = (ImageView) findViewById(R.id.oliveapp_liveness_result_open);
if (mIsFailed) {
mRetryBtn = (Button) findViewById(R.id.oliveapp_liveness_saas_result_retry);
mReturnBtn = (Button) findViewById(R.id.oliveapp_liveness_saas_result_return);
mRetryBtn.setOnClickListener(this);
mReturnBtn.setOnClickListener(this);
} else {
mFinishBtn = (Button) findViewById(R.id.oliveapp_liveness_saas_result_finish);
mFinishBtn.setOnClickListener(this);
}
mImageViewClose.setImageBitmap(mImages[0]);
mImageViewOpen.setImageBitmap(mImages[1]);
}
//==============================选择布局=====================================//
private int decideWhichLayout() {
int layout = -1;
LogUtil.e(TAG, "choose layout");
switch (SampleScreenDisplayHelper.getFixedOrientation(this)) {
case PORTRAIT:
if (SampleScreenDisplayHelper.ifThisIsPhone(this) && mIsFailed) { //手机竖屏失败页面
layout = R.layout.oliveapp_sample_saas_result_fail_portrait_phone;
LogUtil.e(TAG, "oliveapp_sample_saas_result_fail_portrait_phone");
} else if (mIsFailed){//平板竖屏失败页面
layout = R.layout.oliveapp_sample_saas_result_fail_portrait_tablet;
LogUtil.e(TAG, "oliveapp_sample_saas_result_fail_portrait_tablet");
} else if (SampleScreenDisplayHelper.ifThisIsPhone(this)) {//手机竖屏通过页面
LogUtil.e(TAG, "oliveapp_sample_saas_result_success_portrait_phone");
layout = R.layout.oliveapp_sample_saas_result_success_portrait_phone;
} else {//平板通过竖屏界面
LogUtil.e(TAG, "oliveapp_sample_saas_result_success_portrait_tablet");
layout = R.layout.oliveapp_sample_saas_result_success_portrait_tablet;
}
break;
case LANDSCAPE:
if (SampleScreenDisplayHelper.ifThisIsPhone(this)) {
if (mIsFailed) {
layout = R.layout.oliveapp_sample_saas_result_fail_portrait_phone;
} else {
layout = R.layout.oliveapp_sample_saas_result_success_portrait_phone;
}
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
if (mIsFailed) {//失败横屏
layout = R.layout.oliveapp_sample_saas_result_fail_landscape;
} else {//成功横屏
layout = R.layout.oliveapp_sample_saas_result_success_landscape;
}
}
break;
}
return layout;
}
/**
* 此处界面跳转的时候要考虑到Activity的跳转和后台的回退栈
* 所以有的地方是finish()
* 而有的地方是startActivity()
*/
@Override
public void onClick(View view) {
Intent intent = new Intent();
int i = view.getId();
if (i == R.id.oliveapp_liveness_saas_result_finish) {
intent.setClass(SampleSaaSResultActivity.this, SampleLaunchActivity.class);
} else if (i == R.id.oliveapp_liveness_saas_result_retry) {
finish();
return;
} else if (i == R.id.oliveapp_liveness_saas_result_return) {
intent.setClass(SampleSaaSResultActivity.this, SampleLaunchActivity.class);
}
startActivity(intent);
finish();
}
//===========================================用来显示比对数据的ListView的数据填充===========================================//
class ViewHolder {
TextView item;
TextView detail;
ImageView result;
}
class OliveappSaasResultAdapter extends BaseAdapter {
private Context mContext;
public OliveappSaasResultAdapter(Context context) {
mContext = context;
}
@Override
public int getCount() {
return IFPASSKEY.length;
}
@Override
public Object getItem(int i) {
return i;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.oliveapp_sample_saas_result_item, null);
holder = new ViewHolder();
holder.item = (TextView) view.findViewById(R.id.oliveapp_liveness_result_item);
holder.detail = (TextView) view.findViewById(R.id.oliveapp_liveness_result_detail);
holder.result = (ImageView) view.findViewById(R.id.oliveapp_liveness_result_yesorno);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
if (mIfPassed[i]) {
holder.result.setImageResource(R.mipmap.oliveapp_liveness_result_right);
} else {
holder.result.setImageResource(R.mipmap.oliveapp_liveness_result_wrong);
holder.detail.setTextColor(Color.RED);
}
holder.item.setText(ITEMS[i]);
if (i == 0) {
holder.detail.setText("");
} else {
holder.detail.setText(mDetail[i - 1]);
}
view.setLayoutParams(new ListView.LayoutParams(mListview.getWidth(), mListview.getHeight() / getCount()));
holder.item.setTextSize(TypedValue.COMPLEX_UNIT_PX, mListview.getWidth() / 18);
holder.detail.setTextSize(TypedValue.COMPLEX_UNIT_PX, mListview.getWidth() / 27);
return view;
}
}
}
package com.oliveapp.liveness.sample;
import android.Manifest;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.liveness.sample.R;
import com.oliveapp.liveness.sample.liveness.SampleLivenessActivity;
import com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper;
public class SampleStartActivity extends Activity {
private static final String TAG = SampleStartActivity.class.getSimpleName();
private Button mStartLivenessButton;
private ImageButton mCloseLivenessButton;
private View mAnimCircleView;
private RelativeLayout mAnimLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(decideWhichLayout());
mStartLivenessButton = (Button) findViewById(R.id.oliveappStartLivenessButton);
mCloseLivenessButton = (ImageButton) findViewById(R.id.oliveappCloseLivenessButton);
mStartLivenessButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_UP:
//判断手指抬起时,是否还在按钮范围内
float diffX = motionEvent.getRawX() - mStartLivenessButton.getX();
float diffY = motionEvent.getRawY() - mStartLivenessButton.getY();
// if ((diffX >= 0) && (diffX < mStartLivenessButton.getWidth()) && (diffY >= 0) && (diffY < mStartLivenessButton.getHeight())) {
startAnimation(motionEvent.getRawX(), motionEvent.getRawY(), mStartLivenessButton.getHeight() * 0.6f, 300);
enableStartButton(false);
// }
break;
}
return false;
}
});
mCloseLivenessButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
requestPermission();
}
@Override
protected void onResume() {
super.onResume();
//每次进入,先设置button是否可点击
enableStartButton(true);
}
//=======================================================设置控件====================================================//
public void enableStartButton(boolean enable) {
mStartLivenessButton.setEnabled(enable);
}
//========================================================请求权限===================================================//
private static final int PERMISSION_READ_EXTERNAL_STORAGE = 101;
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 102;
private static final int PERMISSION_CAMERA = 103;
private boolean requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_WRITE_EXTERNAL_STORAGE);
return false;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_READ_EXTERNAL_STORAGE);
return false;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_CAMERA);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
try {
switch (requestCode) {
case PERMISSION_CAMERA: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mStartLivenessButton.callOnClick();
} else {
Toast.makeText(this, "没有摄像头权限我什么都做不了哦!", Toast.LENGTH_LONG).show();
}
break;
}
case PERMISSION_READ_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mStartLivenessButton.callOnClick();
} else {
Toast.makeText(this, "请打开存储读写权限,确保APP正常运行", Toast.LENGTH_LONG).show();
}
break;
}
case PERMISSION_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mStartLivenessButton.callOnClick();
} else {
Toast.makeText(this, "请打开存储读写权限,确保APP正常运行", Toast.LENGTH_LONG).show();
}
break;
}
}
} catch (Exception e) {
LogUtil.e(TAG, "Failed to request Permission", e);
}
}
//==============================================决定采用的布局==============================================//
private int decideWhichLayout() {
int layout = -1;
switch (SampleScreenDisplayHelper.getFixedOrientation(this)) {
case PORTRAIT:
if (SampleScreenDisplayHelper.ifThisIsPhone(this)) {
layout = R.layout.oliveapp_sample_start_portrait_phone;
} else {
layout = R.layout.oliveapp_sample_start_portrait_tablet;
}
break;
case LANDSCAPE:
if (!SampleScreenDisplayHelper.ifThisIsPhone(this)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
layout = R.layout.oliveapp_sample_start_landscape;
} else {
layout = R.layout.oliveapp_sample_start_portrait_phone;
}
break;
}
return layout;
}
//================================================动画相关==============================================//
/**
* 点击“开始检测”按钮的动画调用
*
* @param endX 点击位置的距左边框的距离 单位是像素
* @param endY 点击位置距上边框的距离 单位是像素
* @param radius 需要显示的效果圆型的半径 单位是像素
* @param duration 动画的持续时间,单位毫秒
*/
public void startAnimation(float endX, float endY, float radius, long duration) {
/**
* 1,直接用画圆环的方法
* 2,资源清理
* 3,界面跳转
*/
mAnimLayout = (RelativeLayout) findViewById(R.id.oliveapp_start_button_layout);
mAnimCircleView = new CircleView(this, Color.YELLOW, endX, endY, radius, duration);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mAnimLayout.addView(mAnimCircleView, lp);
}
/**
* 动画结束之后的界面跳转
*/
public void navToDetection() {
if (requestPermission()) {
Intent i = new Intent(SampleStartActivity.this, SampleLivenessActivity.class);
startActivity(i);
}
}
/**
* 清理动画用到的资源
*/
public void sweepUp() {
if (mAnimCircleView != null) {
mAnimLayout.removeView(mAnimCircleView);
}
}
/**
* 具体负责点击动画的实现
*/
class CircleView extends View {
private Paint mPaint;
private float mRadius;
//圆心坐标
private float x;
private float y;
private long mDuration;
private float currentRadius = Float.MAX_VALUE;
public CircleView(Context context, int color, float cx, float cy, float radius, long duration) {
super(context);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeWidth(2);
mPaint.setColor(color);
x = cx;
y = cy;
mRadius = radius;
mDuration = duration;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (currentRadius == Float.MAX_VALUE) {
startAnimation();
} else {
RectF rect = new RectF();
rect.top = y - (currentRadius + mRadius + 2) / 2;
rect.left = x - (currentRadius + mRadius + 2) / 2;
rect.bottom = y + (currentRadius + mRadius + 2) / 2;
rect.right = x + (currentRadius + mRadius + 2) / 2;
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mRadius - currentRadius);
canvas.drawArc(rect, 0, 360, false, mPaint);
}
}
public void startAnimation() {
ValueAnimator anim = ValueAnimator.ofFloat(0f, mRadius);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
currentRadius = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
sweepUp();
navToDetection();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
anim.setDuration(mDuration);
anim.start();
}
}
}
package com.oliveapp.liveness.sample;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.liveness.sample.R;
import com.oliveapp.liveness.sample.liveness.SampleLivenessActivity;
import com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper;
import java.util.HashMap;
import java.util.Map;
public class SampleUnusualResultActivity extends Activity implements View.OnClickListener {
public static final int PARSE_INTENT_FAIL = -1;
public static final int OPERATION_EXCEPTION = 0;
public static final int NETWORK_EXCEPTION = 1;
public static final int TIME_OUT = 2;
public static final int INIT_FAIL = 3;
public static final int PRESTART_FAIL = 4;
public static final int LIVENESS_FAIL = 5;
private final String OPERATION_EXCEPTION_DATA = "操作异常";
private final String NETWORK_EXCEPTION_DATA = "网络异常,请返回重试";
private final String TIME_OUT_DATA = "超时,请返回重试";
private final String INIT_FAIL_DATA = "初始化失败,请检查权限设置和摄像头";
private final String PRESTART_FAIL_DATA = "预检失败, 请检查设置或重试";
private final String LIVENESS_FAIL_DATA = "活检失败,请重试";
private final String PARSE_INTENT_FAIL_DATA = "解析传来的intent失败,请检查";
private Map<Integer, String> mExceptionData;
public static final String keyToGetExtra = "REASON";
public static final String TAG = SampleUnusualResultActivity.class.getSimpleName();
private TextView mOliveappResultTextView;
private Button mOliveappResultReturnBtn;
private Button mOliveappResultRetryBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LogUtil.e(TAG, "[JUMP] enter unusualActivity");
//设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//决定显示哪个页面
setContentView(decideWhichLayout());
init();
//反馈信息
int code = getIntent().getIntExtra(keyToGetExtra, PARSE_INTENT_FAIL);
mOliveappResultTextView.setText(mExceptionData.get(code));
}
//===============================初始化数据=================================//
public void init() {
mExceptionData = new HashMap<>();
mExceptionData.put(PARSE_INTENT_FAIL, PARSE_INTENT_FAIL_DATA);
mExceptionData.put(OPERATION_EXCEPTION, OPERATION_EXCEPTION_DATA);
mExceptionData.put(NETWORK_EXCEPTION, NETWORK_EXCEPTION_DATA);
mExceptionData.put(TIME_OUT, TIME_OUT_DATA);
mExceptionData.put(INIT_FAIL, INIT_FAIL_DATA);
mExceptionData.put(PRESTART_FAIL, PRESTART_FAIL_DATA);
mExceptionData.put(LIVENESS_FAIL, LIVENESS_FAIL_DATA);
mOliveappResultTextView = (TextView) findViewById(R.id.oliveappResultTextView);
mOliveappResultReturnBtn = (Button) findViewById(R.id.oliveapp_liveness_result_return);
mOliveappResultRetryBtn = (Button) findViewById(R.id.oliveapp_liveness_result_retry);
mOliveappResultRetryBtn.setOnClickListener(this);
mOliveappResultReturnBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
/**
* 这里如果点击重试按钮,则不用做任何事情,只要finish掉就好了
*/
if (R.id.oliveapp_liveness_result_return == view.getId()) {
Intent intent = new Intent(SampleUnusualResultActivity.this, SampleLaunchActivity.class);
startActivity(intent);
}
finish();
}
//==================================选择布局=====================================//
private int decideWhichLayout() {
int layout = R.layout.oliveapp_sample_result_unusual_portrait_phone;
//选择布局文件
switch (SampleScreenDisplayHelper.getFixedOrientation(this)) {
case PORTRAIT:
if (SampleScreenDisplayHelper.ifThisIsPhone(this)) {
layout = R.layout.oliveapp_sample_result_unusual_portrait_phone;
} else {
layout = R.layout.oliveapp_sample_result_unusual_portrait_tablet;
}
break;
case LANDSCAPE:
if (!SampleScreenDisplayHelper.ifThisIsPhone(this)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
layout = R.layout.oliveapp_sample_result_unusual_landscape;
} else {
layout = R.layout.oliveapp_sample_result_unusual_portrait_phone;
}
break;
}
return layout;
}
}
package com.oliveapp.liveness.sample;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.util.Log;
import android.view.MenuItem;
import com.oliveapp.libcommon.utility.LogUtil;
/**
* Created by lance on 2016/4/13.
*/
public class SettingActivity extends PreferenceActivity implements Preference.OnPreferenceClickListener,Preference.OnPreferenceChangeListener {
public static final String TAG = SettingActivity.class.getSimpleName();
private SharedPreferences mSharedPrefs = null;
private PreferenceScreen mPreferenceScreen;
private CheckBoxPreference mDebugModePreference;
private EditTextPreference mSaaSUrlPreference;
private EditTextPreference mTestIdPreference;
private ListPreference mFanpaiClsImagePreference;
private ListPreference mFanpaiClsThresholdPreference;
private CheckBoxPreference mSaveRgbPreference;
private CheckBoxPreference mSaveOriginImagePreference;
private CheckBoxPreference mSavePackagePreference;
private CheckBoxPreference mSaveFanpaiClsImagePreference;
private CheckBoxPreference mNewPackagePreference; // 新增收图开关配置
private ListPreference mActionCountsListPreference;
private ListPreference mLivenessDetectionOvertimeListPreference;
private ListPreference mActionOneListPreference;
private ListPreference mActionTwoListPreference;
private ListPreference mActionThreeListPreference;
private CheckBoxPreference mFixActionCheckBoxPreference;
private PreferenceCategory mActionSequencePreferenceCategory;
private ListPreference mDarkDetectionListPreference;
private String mActionCountsStr;
private String mActionTimesStr;
private String mFanpaiClsCountStr;
private int mActionCount;
private int mActionTime;
private final int mInf=1000000;
private boolean mFixActionList;
private String[] mActionListArray;
private String mActionOneStr;
private String mActionTwoStr;
private String mActionThreeStr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_setting);
// getSupportActionBar().setTitle(R.string.titleSetting);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
addPreferencesFromResource(R.xml.preferences);
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mPreferenceScreen = (PreferenceScreen) findPreference("pref_liveness_dection");
mDebugModePreference = (CheckBoxPreference) findPreference("pref_debug_mode");
mSaaSUrlPreference = (EditTextPreference) findPreference("pref_saas_url");
mTestIdPreference = (EditTextPreference) findPreference("pref_test_id");
mFanpaiClsImagePreference = (ListPreference) findPreference("pref_fanpaicls_counts_list");
mFanpaiClsThresholdPreference = (ListPreference) findPreference("pref_fanpaicls_threshold_list");
mSaveRgbPreference = (CheckBoxPreference) findPreference("pref_save_rgb");
mSaveOriginImagePreference = (CheckBoxPreference) findPreference("pref_save_origin_image");
mSavePackagePreference = (CheckBoxPreference) findPreference("pref_save_package");
mNewPackagePreference = (CheckBoxPreference) findPreference("pref_new_package");
mDarkDetectionListPreference = (ListPreference) findPreference("pref_dark_detect_list");
mActionSequencePreferenceCategory = (PreferenceCategory) findPreference("pref_action_sequence_category");
mLivenessDetectionOvertimeListPreference = (ListPreference)findPreference("pref_liveness_detection_overtime_list");
mActionOneListPreference = (ListPreference)findPreference("pref_action_one_list");
mActionTwoListPreference = (ListPreference)findPreference("pref_action_two_list");
mActionThreeListPreference = (ListPreference)findPreference("pref_action_three_list");
mActionCountsListPreference = (ListPreference)findPreference("pref_action_counts_list");
mActionCountsListPreference.setOnPreferenceChangeListener(this);
mLivenessDetectionOvertimeListPreference.setOnPreferenceChangeListener(this);
mActionOneListPreference.setOnPreferenceChangeListener(this);
mActionTwoListPreference.setOnPreferenceChangeListener(this);
mActionThreeListPreference.setOnPreferenceChangeListener(this);
mDebugModePreference.setOnPreferenceChangeListener(this);
mSaaSUrlPreference.setOnPreferenceChangeListener(this);
mTestIdPreference.setOnPreferenceChangeListener(this);
mFanpaiClsImagePreference.setOnPreferenceChangeListener(this);
mFanpaiClsThresholdPreference.setOnPreferenceChangeListener(this);
mSaveRgbPreference.setOnPreferenceChangeListener(this);
mSaveOriginImagePreference.setOnPreferenceChangeListener(this);
mSavePackagePreference.setOnPreferenceChangeListener(this);
mNewPackagePreference.setOnPreferenceChangeListener(this);
mDarkDetectionListPreference.setOnPreferenceChangeListener(this);
mActionCountsStr = mSharedPrefs.getString("pref_action_counts_list","default");
mActionTimesStr = mSharedPrefs.getString("pref_liveness_detection_overtime_list","default");
mFanpaiClsCountStr = mSharedPrefs.getString("pref_fanpaicls_counts_list","default");
String actionOne = mSharedPrefs.getString("pref_action_one_list","default");
String actionTwo = mSharedPrefs.getString("pref_action_two_list","default");
String actionThree = mSharedPrefs.getString("pref_action_three_list","default");
CharSequence[] entries = mActionOneListPreference.getEntries();
int indexOne = mActionOneListPreference.findIndexOfValue(actionOne);
int indexTwo = mActionTwoListPreference.findIndexOfValue(actionTwo);
int indexThree = mActionThreeListPreference.findIndexOfValue(actionThree);
mActionCountsListPreference.setSummary(mActionCountsStr);
mFanpaiClsImagePreference.setSummary(mFanpaiClsCountStr);
mActionOneListPreference.setSummary(entries[indexOne]);
mActionTwoListPreference.setSummary(entries[indexTwo]);
mActionThreeListPreference.setSummary(entries[indexThree]);
mSaaSUrlPreference.setSummary(mSharedPrefs.getString("pref_saas_url","default"));
mTestIdPreference.setSummary(mSharedPrefs.getString("pref_test_id","default"));
mFanpaiClsThresholdPreference.setSummary(mSharedPrefs.getString("pref_fanpaicls_threshold_list","default"));
mDarkDetectionListPreference.setSummary(mSharedPrefs.getString("pref_dark_detect_list", "无"));
setActionSequenceCounts(mActionCountsStr);
setFanpaiClsCount(mActionCountsStr);
mActionCount= Integer.valueOf(mActionCountsStr);
mFixActionCheckBoxPreference = (CheckBoxPreference)getPreferenceManager().findPreference("pref_fix_action");
mFixActionCheckBoxPreference.setOnPreferenceChangeListener(this);
mFixActionList = mSharedPrefs.getBoolean("pref_fix_action", true);
if(mFixActionList){
mPreferenceScreen.addPreference(mActionSequencePreferenceCategory);
}else{
mPreferenceScreen.removePreference(mActionSequencePreferenceCategory);
}
Log.d(TAG,"this is SettingActivity mActionCount="+mActionCount);
if(mActionTimesStr.equals(String.valueOf(mInf))){
mActionTime = mInf;
mLivenessDetectionOvertimeListPreference.setSummary("永不超时");
}else{
mActionTime = Integer.valueOf(mActionTimesStr);
mLivenessDetectionOvertimeListPreference.setSummary(mActionTime/1000+"秒");
}
Log.d(TAG,"this is SettingActivity mActionTime="+mActionTime);
Log.d(TAG,"this is SettingActivity mInf ="+mInf);
Log.d(TAG,"this is SettingActivity mFixActionList="+mFixActionList);
String[] actionListArray = new String[]{mActionOneStr,mActionTwoStr,mActionThreeStr};
mActionListArray = new String[mActionCount];
for(int i = 0; i < mActionCount; i++){
mActionListArray[i] = actionListArray[i];
}
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void setActionSequenceCounts(String s){
if(s.equals("1")) {
mActionSequencePreferenceCategory.removePreference(mActionTwoListPreference);
mActionSequencePreferenceCategory.removePreference(mActionThreeListPreference);
mActionSequencePreferenceCategory.addPreference(mActionOneListPreference);
}else if(s.equals("2")) {
mActionSequencePreferenceCategory.removePreference(mActionThreeListPreference);
mActionSequencePreferenceCategory.addPreference(mActionOneListPreference);
mActionSequencePreferenceCategory.addPreference(mActionTwoListPreference);
}else if(s.equals("3")) {
mActionSequencePreferenceCategory.addPreference(mActionOneListPreference);
mActionSequencePreferenceCategory.addPreference(mActionTwoListPreference);
mActionSequencePreferenceCategory.addPreference(mActionThreeListPreference);
}
}
private void setFanpaiClsCount(String s){
if(s.equals("1")) {
CharSequence[] entries = {"1"};
mFanpaiClsImagePreference.setEntries(entries);
mFanpaiClsImagePreference.setEntryValues(entries);
} else {
CharSequence[] entries = {"1", s};
mFanpaiClsImagePreference.setEntries(entries);
mFanpaiClsImagePreference.setEntryValues(entries);
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
LogUtil.i(TAG, "[onPreferenceChange] newValue: " + newValue);
if(ListPreference.class.isInstance(preference)){
Log.d(TAG, "[onPreferenceChange] preference is ListPreference");
String textValue = newValue.toString();
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(textValue);
CharSequence[] entries = listPreference.getEntries();
CharSequence[] entryValues = listPreference.getEntryValues();
Log.d(TAG, "this is lance tag entries[index]=" + entries[index]);
listPreference.setSummary(listPreference.getEntry() == null ? listPreference.getSummary() : entries[index]);
if(listPreference == mLivenessDetectionOvertimeListPreference) {
String value = String.valueOf(entryValues[index]);
if(value.equals(String.valueOf(mInf))){
mActionTime = mInf;
}
mActionTime = Integer.valueOf(value);
Log.d(TAG,"this is Setting mActionTime="+mActionTime);
} else if(listPreference == mActionCountsListPreference) {
mActionCountsStr = String.valueOf(entries[index]);
mActionCount = Integer.valueOf(mActionCountsStr);
setActionSequenceCounts(String.valueOf(entries[index]));
setFanpaiClsCount(String.valueOf(entries[index]));
//重置成1
SharedPreferences.Editor editor = mSharedPrefs.edit();
editor.putString("pref_fanpaicls_counts_list", "1");
editor.commit();
mFanpaiClsImagePreference.setSummary("1");
} else if(listPreference == mActionOneListPreference){
mActionOneStr = String.valueOf(entries[index]);
}else if(listPreference == mActionTwoListPreference){
mActionTwoStr = String.valueOf(entries[index]);
}else if(listPreference == mActionThreeListPreference){
mActionThreeStr = String.valueOf(entries[index]);
}
} else if(CheckBoxPreference.class.isInstance(preference)){
Log.d(TAG, "[onPreferenceChange] preference is CheckBoxPreference");
boolean myValue = (Boolean) newValue;
if(preference == mFixActionCheckBoxPreference){
mFixActionList = myValue;
Log.d(TAG,"this is Setting mFixActionList="+mFixActionList);
if(myValue){
mPreferenceScreen.addPreference(mActionSequencePreferenceCategory);
}else{
mPreferenceScreen.removePreference(mActionSequencePreferenceCategory);
}
}
LogUtil.i(TAG, "[onPreferenceChanged] writeLivenessRuntimeConfig::Custom mode");
} else if (EditTextPreference.class.isInstance(preference)) {
LogUtil.i(TAG, "[onPreferenceChanged] setSummary");
preference.setSummary(newValue.toString());
}
return true;
}
@Override
public boolean onPreferenceClick(Preference preference) {
return true;
}
}
package com.oliveapp.liveness.sample.idcard_captor;
import android.content.Intent;
import android.os.Bundle;
import com.oliveapp.face.idcardcaptorsdk.captor.CapturedIDCardImage;
import com.oliveapp.liveness.sample.idcard_captor.view_controller.SampleIdcardCaptorMainActivity;
/**
* SampleIdcardCaptorActivity
* 如果不想关心界面实现细节,可以直接在此Activity中实现界面跳转逻辑
*/
public class SampleIdcardCaptorActivity extends SampleIdcardCaptorMainActivity {
@Override
public void onCreate(Bundle savedInstance) {
// 如果有设置全局包名的需要, 在这里进行设置
// PackageNameManager.setPackageName();
super.onCreate(savedInstance);
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onFrameResult(int status) {
super.onFrameResult(status);
}
/**
* 捕获到最好的一张身份证照片
*/
@Override
public void onIDCardCaptured(CapturedIDCardImage data) {
super.onIDCardCaptured(data);
// 处理Activity跳转逻辑
Intent i = new Intent(SampleIdcardCaptorActivity.this, SampleIdcardResult.class);
i.putExtra("image", data.idcardImageData);
startActivity(i);
finish();
}
}
package com.oliveapp.liveness.sample.idcard_captor.view_controller;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.oliveapp.camerasdk.CameraManager;
import com.oliveapp.camerasdk.PhotoModule;
import com.oliveapp.camerasdk.utils.CameraUtil;
import com.oliveapp.face.idcardcaptorsdk.captor.CapturedIDCardImage;
import com.oliveapp.face.idcardcaptorsdk.captor.IDCardCaptor;
import com.oliveapp.face.idcardcaptorsdk.captor.IDCardCaptureEventHandlerIf;
import com.oliveapp.face.idcardcaptorsdk.captor.datatype.FrameData;
import com.oliveapp.face.idcardcaptorsdk.captor.datatype.IDCardStatus;
import com.oliveapp.face.idcardcaptorsdk.nativecode.session_manager.ImageForVerifyConf;
import com.oliveapp.libcommon.uicomponents.VerticalTextView;
import com.oliveapp.libcommon.utility.ApplicationParameters;
import com.oliveapp.libcommon.utility.ImageUtil;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.libcommon.utility.PackageNameManager;
import com.oliveapp.liveness.sample.R;
import junit.framework.Assert;
import java.io.ByteArrayOutputStream;
import java.util.Timer;
import java.util.TimerTask;
import static com.oliveapp.face.idcardcaptorsdk.captor.IDCardCaptor.CARD_TYPE_FRONT;
public class SampleIdcardCaptorMainActivity extends Activity implements CameraManager.CameraPreviewDataCallback, IDCardCaptureEventHandlerIf, CameraManager.CameraPictureCallback {
public static final String TAG = SampleIdcardCaptorMainActivity.class.getSimpleName();
public static final int REQUEST_CODE = 10001;
// Camera Preview Parameter
private static final float TARGET_PREVIEW_RATIO = 16 / 9f; // 摄像头Previwe预览界面的长宽比 默认使用16:9(因为要铺满全屏)
private static final int MAX_PREVIEW_WIDTH = 1920; // 摄像头Preview预览界面的最大宽度,默认使用分辨率1920x1080
private String mPackageName; // 包名
private PhotoModule mPhotoModule; // 摄像头模块
private IDCardCaptor mCaptor; // IDCARD CAPTOR
private VerticalTextView mVerticalTextView;
private ImageButton mTakePictureButton;
private ImageView mIdcardShadeView;
private View mPreview;
private ImageView mScanLineImageView;
private int mIdcardLeft;
private int mIdcardRight;
private int mIdcardTop;
private int mIdcardBottom;
// 真正发生preview的surface或者texture的位置
private int mPreviewLeft;
private int mPreviewRight;
private int mPreviewTop;
private int mPreviewBottom;
private int mPreviewFrameWidth;
private int mPreviewFrameHeight;
// 捕获模式
public static final int CAPTURE_MODE_AUTO = 0x00; // 自动捕获
public static final int CAPTURE_MODE_MANUAL = 0x01; // 手动拍摄
public static final int CAPTURE_MODE_MIXED = 0x10; // 混合模式,首先尝试自动捕获,指定时间后,采取手动拍摄
public int mCaptureMode; // 捕获模式
public int mCardType; // 身份证类型:正面/反面
public int mDurationTime; // 尝试自动捕获时间,单位为秒,仅混合模式有效
public static final String EXTRA_CAPTURE_MODE = "capture_mode";
public static final String EXTRA_CARD_TYPE = "card_type";
public static final String EXTRA_DURATION_TIME = "duration_time";
// 定时器与定时任务,用于混合模式
private Timer mTimer;
private TimerTask mTimerTask;
// 是否处于自动模式/混合模式
private Boolean bIsAuto = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
LogUtil.e(TAG, "Uncaught exception", ex);
}
});
if (!PackageNameManager.isPackageNameSet()) {
PackageNameManager.setPackageName(getPackageName());
}
PackageNameManager.setPackageName(PackageNameManager.getPackageName());
super.onCreate(savedInstanceState);
// DEBUG相关: 可以检测Activity内存泄漏
increaseClassObjectCount();
mPackageName = PackageNameManager.getPackageName();
initData();
// 初始化界面元素
initViews();
// 初始化摄像头
initCamera();
// 如果是自动模式/混合模式,初始化身份证捕获模块,
if(bIsAuto) {
initCaptor();
// 如果是混合模式,启动定时任务
if(mCaptureMode == CAPTURE_MODE_MIXED) {
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// 计时器停止后,析构捕获模块,同时更新界面
synchronized (bIsAuto) {
bIsAuto = false;
mTakePictureButton.setVisibility(View.VISIBLE);
mVerticalTextView.setVisibility(View.INVISIBLE);
mScanLineImageView.setAnimation(null);
mScanLineImageView.setVisibility(View.INVISIBLE);
if (mCaptor != null) {
mCaptor.uninit();
mCaptor = null;
}
}
}
});
}
};
mTimer.schedule(mTimerTask, mDurationTime * 1000);
}
} else {
mTakePictureButton.setVisibility(View.VISIBLE);
mVerticalTextView.setVisibility(View.INVISIBLE);
mScanLineImageView.setVisibility(View.INVISIBLE);
}
}
@Override
public void onResume() {
Log.i(TAG, "[BEGIN] SampleIdcardCaptorMainActivity::onResume()");
super.onResume();
// 恢复摄像头预览和摄像头实时处理回调
if (mPhotoModule != null) {
mPhotoModule.onResume();
try {
mPhotoModule.setPreviewDataCallback(this, mCameraHandler);
} catch (NullPointerException e) {
LogUtil.e(TAG, "PhotoModule set callback failed", e);
}
}
Log.i(TAG, "[END] SampleIdcardCaptorMainActivity::onResume()");
}
@Override
protected void onPause() {
Log.i(TAG, "[BEGIN] SampleIdcardCaptorMainActivity::onPause()");
super.onPause();
// 暂停摄像头预览
if (mPhotoModule != null) {
mPhotoModule.onPause();
}
Log.i(TAG, "[END] SampleIdcardCaptorMainActivity::onPause()");
}
@Override
protected void onDestroy() {
Log.i(TAG, "[BEGIN] SampleIdcardCaptorMainActivity::onDestroy()");
super.onDestroy();
// 关闭摄像头
if (mPhotoModule != null) {
mPhotoModule.onStop();
}
CameraUtil.sContext = null; // 避免出现引用环造成内存泄漏
mPhotoModule = null;
// 析构捕获模块
if (mCaptor != null) {
mCaptor.uninit();
mCaptor = null;
}
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
if (mTimerTask != null) {
mTimerTask.cancel();
mTimerTask = null;
}
Log.i(TAG, "[END] SampleIdcardCaptorMainActivity::onDestroy()");
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if(bIsAuto) {
// 扫描动画效果
ImageView skeletonImageView = (ImageView) findViewById(R.id.oliveapp_face_idcardSkeletonImageView);
int[] location = new int[2];
skeletonImageView.getLocationInWindow(location);
int left = skeletonImageView.getLeft();
int right = skeletonImageView.getRight();
int top = skeletonImageView.getTop();
// 平移位置由skeletonImageView在屏幕上的坐标决定
Animation animation = new TranslateAnimation(left - 20, right - 20, top, top);
animation.setDuration(3000);
animation.setRepeatCount(Animation.INFINITE);
animation.setRepeatMode(Animation.RESTART);
mScanLineImageView.startAnimation(animation);
}
}
private void initData() {
mCaptureMode = getIntent().getIntExtra(EXTRA_CAPTURE_MODE, CAPTURE_MODE_MIXED);
if(mCaptureMode == CAPTURE_MODE_AUTO || mCaptureMode == CAPTURE_MODE_MIXED) {
bIsAuto = true;
} else {
bIsAuto = false;
}
mCardType = getIntent().getIntExtra(EXTRA_CARD_TYPE, CARD_TYPE_FRONT);
// 如果是混合模式,则mDurationTime没有作用
mDurationTime = getIntent().getIntExtra(EXTRA_DURATION_TIME, 10);
}
/**
* 初始化界面元素
*/
private void initViews() {
// Fullscreen looks better
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
/*View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);*/
// Style中已经设置了NoActionBar
// ActionBar actionBar = getActionBar();
// actionBar.hide();
}
setContentView(R.layout.oliveapp_activity_sample_idcard_captor);
mVerticalTextView = (VerticalTextView) findViewById(R.id.oliveapp_face_hintTextView);
mTakePictureButton = (ImageButton) findViewById(R.id.oliveapp_face_takePictureButton);
mIdcardShadeView = (ImageView) findViewById(R.id.oliveapp_face_idcardSkeletonImageView);
mPreview = findViewById(R.id.oliveapp_face_cameraPreviewView);
mTakePictureButton.setOnClickListener(mTakePhotoButtonClickListener);
mScanLineImageView = (ImageView) findViewById(R.id.oliveapp_face_scan_line);
// DEBUG: 调试相关
mFrameRateText = (TextView) findViewById(R.id.oliveapp_frame_rate_text);
}
private Handler mCameraHandler; // 摄像头回调所在的消息队列
private HandlerThread mCameraHandlerThread; // 摄像头回调所在的消息队列线程
/**
* 初始化并打开摄像头
*/
private void initCamera() {
LogUtil.i(TAG, "[BEGIN] initCamera");
// 寻找设备上的后置摄像头
int cameraCount = Camera.getNumberOfCameras();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
int expectCameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
LogUtil.i(TAG, "camera id: " + camIdx + ", facing: " + cameraInfo.facing + ", expect facing: " + expectCameraFacing);
if (cameraInfo.facing == expectCameraFacing) {
getIntent().putExtra(CameraUtil.EXTRAS_CAMERA_FACING, camIdx); // 设置需要打开的摄像头ID
getIntent().putExtra(CameraUtil.MAX_PREVIEW_WIDTH, MAX_PREVIEW_WIDTH); // 设置最大Preview宽度
getIntent().putExtra(CameraUtil.TARGET_PREVIEW_RATIO, TARGET_PREVIEW_RATIO); // 设置Preview长宽比
}
}
mPhotoModule = new PhotoModule();
mPhotoModule.init(this, findViewById(R.id.oliveapp_face_cameraPreviewView)); // 参考layout XML文件里定义的cameraPreviewView对象
mPhotoModule.setPlaneMode(false, false); // 取消拍照和对焦功能
mPhotoModule.setShutterRawDataCallback(this);
// 打开摄像头预览
mPhotoModule.onStart();
// 初始化摄像头处理消息队列
mCameraHandlerThread = new HandlerThread("CameraHandlerThread");
mCameraHandlerThread.start();
mCameraHandler = new Handler(mCameraHandlerThread.getLooper());
LogUtil.i(TAG, "[END] initCamera");
}
/**
* 初始化捕获模块
*/
private void initCaptor() {
mCaptor = new IDCardCaptor();
try {
// 在构造捕获模块时,需要制定身份证正面/反面
// 正面:IDCardCaptor.CARD_TYPE_FRONT
// 反面:IDCardCaptor.CARD_TYPE_BACK
mCaptor.init(this, new Handler(getMainLooper()), this, mCardType);
} catch (Exception e) {
LogUtil.e(TAG, "无法初始化身份证翻拍照捕获模块", e);
}
}
private int mCurrentFrameId; // 当前帧ID
/**
* 摄像头取帧回调函数
*/
@Override
public void onPreviewFrame(byte[] data, CameraManager.CameraProxy camera, int faces) {
if(bIsAuto && mCaptor != null) {
mCurrentFrameId++;
Log.d(TAG, "[BEGIN] onPreviewFrame, frameID: " + mCurrentFrameId);
Camera.Size size = camera.getParameters().getPreviewSize();
prepareImageConfigForVerify(size.width, size.height, 0);
// 不处理摄像头打开的前几帧(一般是10)。这些帧有可能比较黑,影响比对结果
if (mCurrentFrameId < ApplicationParameters.CAMERA_DROP_FIRST_DARK_FRAME) {
LogUtil.i(TAG, "onPreviewFrame, drop frame id: " + mCurrentFrameId);
return;
}
LogUtil.i(TAG, "[BEGIN] onPreviewFrame, frame id: " + mCurrentFrameId);
boolean isFrameHandled = false;
// 当前帧
try {
mCaptor.doDetection(data, size.width, size.height);
} catch (Exception e) {
LogUtil.e(TAG, "doDetection failed with exception", e);
}
LogUtil.i(TAG, "[END] onPreviewFrame, 当前帧处理是否处理成功: " + isFrameHandled);
}
}
/**
* 准备图像变换参数
*/
private void prepareImageConfigForVerify(int width, int height, int preRotateDegree) {
// 如果已经
if (FrameData.sImageConfigForVerify != null)
return;
Display display = getWindowManager().getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
ImageView skeleton = (ImageView) findViewById(R.id.oliveapp_face_idcardSkeletonImageView);
int locationOnScreen[] = new int[2]; // 画面中透明的身份证区域在屏幕上的尺寸
skeleton.getLocationOnScreen(locationOnScreen);
int skeletonWidth = skeleton.getMeasuredWidth(); // 屏幕的尺寸
int skeletonHeight = skeleton.getMeasuredHeight();
Log.i(TAG, "location on screen: " + locationOnScreen[0] + "," + locationOnScreen[1] + "; skeleton size: " + skeletonWidth + "," + skeletonHeight + "; screen size: " + screenSize.x + "," + screenSize.y);
// 需要按照身份证提示框的1.2倍长、宽来截取画面
FrameData.sImageConfigForVerify = new ImageForVerifyConf(width, height,
760, 480, 1.0f * skeletonHeight / screenSize.y * 1.2f, (locationOnScreen[0] - skeletonWidth * 0.1f) / screenSize.x, preRotateDegree, 0, false);
}
/**
* 单帧结果回调
*/
@Override
public void onFrameResult(int status) {
// IDCardStatus.getHintFromStatus函数可以把状态码变成对应的提示文字
// 当然,如果需要自定义界面,您也可以修改这个函数
mVerticalTextView.setText(IDCardStatus.getHintFromStatus(status));
}
/**
* 翻拍照捕获结果回调
*/
@Override
public void onIDCardCaptured(CapturedIDCardImage data) {
// data.idcardImageData里保存了身份证翻拍照的JPEG数据
mVerticalTextView.setText(IDCardStatus.getHintFromStatus(IDCardStatus.SUCCESS));
}
/**
*
* 点击拍照按钮事件
*
*/
private View.OnClickListener mTakePhotoButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// 保存控件位置数据,用于裁剪图片,详情请参照cutIdcardImage方法
LogUtil.i(TAG, "用户按了拍摄按钮");
mIdcardBottom = mIdcardShadeView.getBottom();
mIdcardLeft = mIdcardShadeView.getLeft();
mIdcardRight = mIdcardShadeView.getRight();
mIdcardTop = mIdcardShadeView.getTop();
Point previewSize = mPhotoModule.getPreviewSize();
mPreviewFrameWidth = previewSize.x;
mPreviewFrameHeight = previewSize.y;
int midX = (mPreview.getLeft() + mPreview.getRight())/2;
int midY = (mPreview.getTop() + mPreview.getBottom())/2;
mPreviewLeft = midX - mPreviewFrameWidth/2;
mPreviewRight = midX + mPreviewFrameWidth/2;
mPreviewTop = midY - mPreviewFrameHeight/2;
mPreviewBottom = midX + mPreviewFrameHeight/2;
mPhotoModule.captureWithCallBack(false);
}
};
/////////////////// FOR DEBUG //////////////////////
private TextView mFrameRateText;
private static int classObjectCount = 0;
private void increaseClassObjectCount() {
// DEBUG: 检测是否有Activity泄漏
classObjectCount++;
LogUtil.e(TAG, "SampleIdcardCaptorMainActivity classObjectCount onCreate: " + classObjectCount);
// 预期现象是classObjectCount是<10,如果classObjectCount一直在增长,很可能有内存泄漏
if (classObjectCount == 10) {
System.gc();
}
Assert.assertTrue(classObjectCount < 10); // 超过10个对象肯定是内存泄漏,不如crash掉直接暴露问题
}
@Override
public void finalize() {
try {
super.finalize();
} catch (Throwable e) {
LogUtil.e(TAG, "无法完成finalize...", e);
}
// DEBUG: 检测是否有Activity泄漏。与increaseClassObjectCount对应
classObjectCount--;
LogUtil.e(TAG, "SampleIdcardCaptorMainActivity classObjectCount finalize: " + classObjectCount);
}
// 手动拍摄到照片后的回调函数
@Override
public void onPictureTaken(byte[] data, CameraManager.CameraProxy camera) {
LogUtil.i(TAG, "[BEGIN] onPictureTaken...");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
LogUtil.i(TAG, "original size " + bitmap.getWidth() + "x" + bitmap.getHeight());
bitmap = cutIdcardImage(bitmap);
// 某些手机设置MAX_PICTURE_SIZE无效
int imageHeight;
int imageWidth;
if (bitmap.getWidth() > ApplicationParameters.ID_CARD_UPLOAD_IMAGE_WIDTH + 5) {
imageHeight = (int) (ApplicationParameters.ID_CARD_UPLOAD_IMAGE_WIDTH / (float) bitmap.getWidth() * bitmap.getHeight());
imageWidth = ApplicationParameters.ID_CARD_UPLOAD_IMAGE_WIDTH;
if (1 == (imageHeight & 1)) {
imageHeight -= 1;
}
if (1 == (imageWidth & 1)) {
imageWidth -= 1;
}
bitmap = Bitmap.createScaledBitmap(bitmap, imageWidth, imageHeight, true);
}
// make sure size of image is even, face detect need that
imageWidth = bitmap.getWidth();
imageHeight = bitmap.getHeight();
if ((imageHeight & 1) == 1) {
imageHeight -= 1;
}
if ((imageWidth & 1) == 1) {
imageWidth -= 1;
}
if (imageHeight != bitmap.getHeight() || imageWidth != bitmap.getWidth()) {
bitmap = ImageUtil.getSubBitmap(bitmap, imageWidth, imageHeight);
LogUtil.d(TAG, "get sub image, width: " + bitmap.getWidth() + " imageHeight: " + bitmap.getHeight());
}
LogUtil.i(TAG, "final image size, width: " + bitmap.getWidth() + " height: " + bitmap.getHeight());
byte[] imageContent = ImageUtil.convertBitmapToJPEGByteArray(bitmap, ApplicationParameters.USER_REGISTRATION_UPLOAD_IMAGE_QUALITY);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// TODO: 最好能够根据当前图片大小,调整压缩率
if (imageContent.length > 600 * 1024) {
Bitmap croppedBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 4 , bitmap.getHeight() / 4, false);
croppedBitmap.compress(Bitmap.CompressFormat.JPEG, 25, byteArrayOutputStream);
imageContent = byteArrayOutputStream.toByteArray();
} else if (imageContent.length > 200 * 1024) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 25, byteArrayOutputStream);
imageContent = byteArrayOutputStream.toByteArray();
}
// 调用onIDCardCaptured方法,跳转至结果界面
onIDCardCaptured(new CapturedIDCardImage(imageContent));
LogUtil.d(TAG, "[END] onPictureTaken done");
}
public Bitmap cutIdcardImage(Bitmap originalBitmap) {
// 这个图是横的!
// 非常复杂的裁剪图片逻辑!
// 首先获取真实surfaceHolder 或者 textureHolder的位置(使用mPreview的中点,向上下算,可以超出真实Screen), 然后获取ImageView那个身份证框的位置, 这两个是可除的,
// 都是显示像素作为单位
// 之后按照这个比例切出身份证在jpeg上的子图
// 细节可以参考 PhotoUI 的 setTransformMatrix 函数实现
int imageWidth = originalBitmap.getWidth();
int imageHeight = originalBitmap.getHeight();
int targetX = (int)(imageWidth * ((double)(mIdcardTop - mPreviewTop) / mPreviewFrameHeight));
int targetY = (int)(imageHeight * (((double)(mPreviewRight - mIdcardRight) / mPreviewFrameWidth)));
int targetW = (int)(imageWidth * ((double)(mIdcardBottom - mIdcardTop)) / mPreviewFrameHeight);
int targetH = (int)(imageHeight * ((double)(mIdcardRight - mIdcardLeft)) / mPreviewFrameWidth);
return Bitmap.createBitmap(originalBitmap, targetX, targetY, targetW, targetH);
}
}
package com.oliveapp.liveness.sample.liveness;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Base64;
import android.widget.Toast;
import com.oliveapp.face.livenessdetectorsdk.livenessdetector.datatype.LivenessDetectionFrames;
import com.oliveapp.face.livenessdetectorsdk.livenessdetector.datatype.OliveappFaceInfo;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.liveness.sample.SampleUnusualResultActivity;
import com.oliveapp.liveness.sample.liveness.view_controller.LivenessDetectionMainActivity;
/**
* 样例活体检测Activity
*/
public class SampleLivenessActivity extends LivenessDetectionMainActivity {
public static final String TAG = SampleLivenessActivity.class.getSimpleName();
private ProgressDialog mProgressDialog;
public static String resultString = null;
private LivenessDetectionFrames livenessDetectionFrames;
@Override
protected void onCreate(Bundle savedInstanceState) {
// 如果有设置全局包名的需要, 在这里进行设置
// PackageNameManager.setPackageName();
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
/**
* =====================启动算法===============
**/
@Override
public void onInitializeSucc() {
super.onInitializeSucc();
super.startVerification();
}
@Override
public void onInitializeFail(Throwable e) {
super.onInitializeFail(e);
LogUtil.e(TAG, "无法初始化活体检测...", e);
Toast.makeText(this, "无法初始化活体检测", Toast.LENGTH_LONG).show();
Intent i = new Intent(SampleLivenessActivity.this, SampleUnusualResultActivity.class);
i.putExtra(SampleUnusualResultActivity.keyToGetExtra, SampleUnusualResultActivity.INIT_FAIL);
startActivity(i);
finish();
}
@Override
protected void onPause() {
super.onPause();
if ((mProgressDialog != null) && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
/**===================================活体检测算法的回调==================================**/
/**
* 活体检测成功的回调,同时获取大礼包
* 成功回调的接口在1.7.a_hotfix被拆成了2步,不再使用该接口
*
* @param livenessDetectionFrames 活体检测抓取的图片
* @param faceInfo 捕获到的人脸信息
*/
@Override
public void onLivenessSuccess(final LivenessDetectionFrames livenessDetectionFrames, OliveappFaceInfo faceInfo) {
super.onLivenessSuccess(livenessDetectionFrames, faceInfo);
this.livenessDetectionFrames = livenessDetectionFrames;
CheckImagePackage checkImagePackage = new CheckImagePackage();
checkImagePackage.execute();
}
/*@Override
public void onLivenessSuccess(OliveappFaceInfo oliveappFaceInfo) {
super.onLivenessSuccess(null, oliveappFaceInfo);
CheckImagePackage checkImagePackage = new CheckImagePackage();
checkImagePackage.execute();
}*/
/**
* 活检阶段失败
*/
@Override
public void onLivenessFail(int result, LivenessDetectionFrames livenessDetectionFrames) {
super.onLivenessFail(result, livenessDetectionFrames);
runOnUiThread(new Runnable() {
@Override
public void run() {
// Intent intent = new Intent();
// Bundle bundle = new Bundle();
// bundle.putString("FACE_RESULT", null);
// intent.putExtras(bundle);
setResult(Activity.RESULT_OK);
finish();
}
});
}
/**
* 获取大礼包并访问私有云的样例代码,集成时请不要使用
*/
private class CheckImagePackage extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(SampleLivenessActivity.this,
null, "正在比对,请稍等", true, false);
}
@Override
protected String doInBackground(Void... voids) {
// 获取大礼包,耗时操作,不可在UI线程执行
return Base64.encodeToString(livenessDetectionFrames.verificationData, Base64.NO_WRAP);
}
@Override
protected void onPostExecute(final String result) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
// Intent intent = new Intent();
// Bundle bundle = new Bundle();
// bundle.putString("FACE_RESULT", result);
// intent.putExtras(bundle);
resultString = result;
setResult(Activity.RESULT_OK);
finish();
}
});
}
}
public static class YituFaceResult{
public String resultString;
public YituFaceResult(String result){
resultString = result;
}
}
}
......@@ -6,6 +6,7 @@ import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Typeface;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
......@@ -23,13 +24,15 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.oliveapp.camerasdk.CameraManager;
import com.oliveapp.camerasdk.PhotoModule;
import com.oliveapp.camerasdk.utils.CameraUtil;
import com.oliveapp.camerasdk.MediaRecordConfig;
import com.oliveapp.face.livenessdetectionviewsdk.event_interface.ViewUpdateEventHandlerIf;
import com.oliveapp.face.livenessdetectionviewsdk.verification_controller.VerificationController;
import com.oliveapp.face.livenessdetectionviewsdk.verification_controller
.VerificationControllerFactory;
import com.oliveapp.face.livenessdetectionviewsdk.verification_controller.VerificationControllerFactory;
import com.oliveapp.face.livenessdetectionviewsdk.verification_controller.VerificationControllerIf;
import com.oliveapp.face.livenessdetectorsdk.livenessdetector.IIndependentLivenessStatusListener;
import com.oliveapp.face.livenessdetectorsdk.livenessdetector.datatype.FacialActionType;
import com.oliveapp.face.livenessdetectorsdk.livenessdetector.datatype.ImageProcessParameter;
import com.oliveapp.face.livenessdetectorsdk.livenessdetector.datatype.LivenessDetectionFrames;
......@@ -37,9 +40,10 @@ import com.oliveapp.face.livenessdetectorsdk.livenessdetector.datatype.LivenessD
import com.oliveapp.face.livenessdetectorsdk.livenessdetector.datatype.OliveappFaceInfo;
import com.oliveapp.face.livenessdetectorsdk.prestartvalidator.datatype.PrestartDetectionFrame;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.libcommon.utility.ApplicationParameters;
import com.oliveapp.libcommon.utility.PackageNameManager;
import com.oliveapp.liveness.sample.R;
import com.oliveapp.liveness.sample.SampleUnusualResultActivity;
import com.oliveapp.liveness.sample.utils.AudioModule;
import com.oliveapp.liveness.sample.utils.OliveappAnimationHelper;
import com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper;
......@@ -47,8 +51,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import static com.oliveapp.camerasdk.utils.CameraUtil.CAMERA_RATIO_16_9;
import static com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper.OrientationType
.LANDSCAPE;
import static com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper.OrientationType.LANDSCAPE;
import static com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper.OrientationType.PORTRAIT;
/**
......@@ -57,8 +60,8 @@ import static com.oliveapp.liveness.sample.utils.SampleScreenDisplayHelper.Orien
* 可参考SampleAPP里的ExampleLivenessActivity
*/
public abstract class LivenessDetectionMainActivity extends Activity implements
ViewUpdateEventHandlerIf {
public abstract class LivenessDetectionMainActivity extends Activity implements ViewUpdateEventHandlerIf,
IIndependentLivenessStatusListener, CameraManager.MediaRecordCallback {
public static final String TAG = LivenessDetectionMainActivity.class.getSimpleName();
......@@ -75,21 +78,22 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
private static float mHeightPercent = 0.414f;
private PhotoModule mPhotoModule; // 摄像头模块
// private AudioModule mAudioModule; // 音频播放模块
private AudioModule mAudioModule; // 音频播放模块
private TextView mOliveappDetectedDirectText; //头像上方的指示图像“请眨眼”
private ImageButton mCloseImageBtn; //关闭按钮
private ImageView mCapFrame;
private TextView mCountDownTextView;
private MediaRecordConfig mMediaRecordConfig;
private boolean mIsLivenessSuccess = false;
/**
* 默认无预检动作
* 默认无预检动作
* WITHOUT_PRESTART,无预检过程
* WITH_PRESTART,有预检过程 (推荐)
*/
private VerificationControllerFactory.VCType mVerificationControllerType =
VerificationControllerFactory.VCType.WITH_PRESTART;
private VerificationControllerFactory.VCType mVerificationControllerType = VerificationControllerFactory.VCType.WITH_PRESTART;
private OliveappAnimationHelper mAnimController; //控制动画播放
private static Handler mAnimationHanlder = null; //播放动画的Handler
......@@ -97,11 +101,10 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
private int mCurrentActionType;
private boolean mIsPrestart = false;
/**
* ====================================生命周期相关函数====================================
**/
/**====================================生命周期相关函数====================================**/
@Override
protected void onCreate(Bundle savedInstanceState) {
LogUtil.i(TAG, "[BEGIN] LivenessDetectionMainActivity::onCreate()");
/**
* 有些插件系统用普通方法获取不到PackageName,此代码用于兼容
......@@ -116,16 +119,15 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
/**
* 以下代码是为了配合设置功能,集成时可以删除
*/
// SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences
// (LivenessDetectionMainActivity.this);
// boolean isDebug = sharedPrefs.getBoolean("pref_debug_mode", false);
// if (isDebug) {
// if (sharedPrefs.getBoolean("pref_with_prestart", false)) {
// mVerificationControllerType = VerificationControllerFactory.VCType.WITH_PRESTART;
// } else {
// mVerificationControllerType = VerificationControllerFactory.VCType.WITHOUT_PRESTART;
// }
// }
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(LivenessDetectionMainActivity.this);
boolean isDebug = sharedPrefs.getBoolean("pref_debug_mode", false);
if (isDebug) {
if (sharedPrefs.getBoolean("pref_with_prestart", false)) {
mVerificationControllerType = VerificationControllerFactory.VCType.WITH_PRESTART;
} else {
mVerificationControllerType = VerificationControllerFactory.VCType.WITHOUT_PRESTART;
}
}
/**
* 以上代码是为了配合设置功能,集成时可以删除
*/
......@@ -165,6 +167,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
}
try {
mPhotoModule.setPreviewDataCallback(mVerificationController, mCameraHandler);
mPhotoModule.setMediaRecordCallback(this, mMediaRecordConfig);
} catch (NullPointerException e) {
LogUtil.e(TAG, "PhotoModule set callback failed", e);
}
......@@ -178,7 +181,6 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
}
LogUtil.i(TAG, "[END] LivenessDetectionMainActivity::onResume()");
}
@Override
protected void onPause() {
LogUtil.i(TAG, "[BEGIN] LivenessDetectionMainActivity::onPause()");
......@@ -216,10 +218,10 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
mAnimationHanlder.removeCallbacksAndMessages(null);
mAnimationHanlder = null;
}
// if (mAudioModule != null) {
// mAudioModule.release();
// mAudioModule = null;
// }
if (mAudioModule != null) {
mAudioModule.release();
mAudioModule = null;
}
// 退出摄像头处理线程
if (mCameraHandlerThread != null) {
......@@ -240,9 +242,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
LogUtil.i(TAG, "[END] LivenessDetectionMainActivity::onDestroy()");
}
/**
* ====================================初始化相关函数====================================
**/
/**====================================初始化相关函数====================================**/
private VerificationControllerIf mVerificationController; // 逻辑控制器
private Handler mCameraHandler; // 摄像头回调所在的消息队列
......@@ -261,17 +261,14 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
LogUtil.i(TAG, "camera id: " + camIdx + ", facing: " + cameraInfo.facing + ", expect " +
"facing: " + expectCameraFacing);
LogUtil.i(TAG, "camera id: " + camIdx + ", facing: " + cameraInfo.facing + ", expect facing: " + expectCameraFacing);
if (cameraInfo.facing == expectCameraFacing) {
getIntent().putExtra(CameraUtil.EXTRAS_CAMERA_FACING, camIdx); // 设置需要打开的摄像头ID
getIntent().putExtra(CameraUtil.TARGET_PREVIEW_RATIO, CAMERA_RATIO_16_9); //
// 设置Preview长宽比,默认是16:9
getIntent().putExtra(CameraUtil.TARGET_PREVIEW_RATIO, CAMERA_RATIO_16_9); // 设置Preview长宽比,默认是16:9
}
}
mPhotoModule = new PhotoModule();
mPhotoModule.init(this, findViewById(R.id.oliveapp_cameraPreviewView)); // 参考layout
// XML文件里定义的cameraPreviewView对象
mPhotoModule.init(this, findViewById(R.id.oliveapp_cameraPreviewView)); // 参考layout XML文件里定义的cameraPreviewView对象
mPhotoModule.setPlaneMode(false, false); // 取消拍照和对焦功能
// 打开摄像头预览
mPhotoModule.onStart();
......@@ -287,14 +284,14 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
* 初始化界面元素
*/
private void initViews() {
//设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager
.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(decideWhichLayout());
//音频和动画的Handler
// mAudioModule = new AudioModule();
mAudioModule = new AudioModule();
mAnimationHanlder = new Handler();
//进入活检页面就开启动画
mAnimController = new OliveappAnimationHelper(this);
......@@ -320,21 +317,17 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
*/
mCapFrame = (ImageView) findViewById(R.id.oliveapp_start_frame);
if (!SampleScreenDisplayHelper.ifThisIsPhone(this)) {
PercentRelativeLayout.LayoutParams layoutParams = new PercentRelativeLayout
.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams
.WRAP_CONTENT);
PercentRelativeLayout.LayoutParams layoutParams = new PercentRelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
PercentLayoutHelper.PercentLayoutInfo layoutInfo = layoutParams.getPercentLayoutInfo();
if (SampleScreenDisplayHelper.getFixedOrientation(this) == LANDSCAPE) {
layoutInfo.topMarginPercent = 0.2f;
layoutInfo.heightPercent = 0.6f;
layoutInfo.widthPercent = layoutInfo.heightPercent / (float)
SampleScreenDisplayHelper.getScreenScale(this);
layoutInfo.widthPercent = layoutInfo.heightPercent / (float) SampleScreenDisplayHelper.getScreenScale(this);
layoutInfo.leftMarginPercent = (1 - layoutInfo.widthPercent) / 2;
} else {
layoutInfo.leftMarginPercent = 0.13f;
layoutInfo.widthPercent = 0.74f;
layoutInfo.heightPercent = layoutInfo.widthPercent / (float)
SampleScreenDisplayHelper.getScreenScale(this);
layoutInfo.heightPercent = layoutInfo.widthPercent / (float) SampleScreenDisplayHelper.getScreenScale(this);
layoutInfo.topMarginPercent = (1 - layoutInfo.heightPercent) / 2 - 0.022f;
}
mCapFrame.setLayoutParams(layoutParams);
......@@ -344,12 +337,9 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
* 提示文字的布局要动态调整
* 只有平板竖屏的时候要调整
*/
if ((SampleScreenDisplayHelper.getFixedOrientation(this) == PORTRAIT) &&
(!SampleScreenDisplayHelper.ifThisIsPhone(this))) {
PercentRelativeLayout hintLayout = (PercentRelativeLayout) findViewById(R.id
.oliveapp_detected_hint_text_layout);
PercentRelativeLayout.LayoutParams params = new PercentRelativeLayout.LayoutParams(0,
0);
if ((SampleScreenDisplayHelper.getFixedOrientation(this) == PORTRAIT) && (!SampleScreenDisplayHelper.ifThisIsPhone(this))) {
PercentRelativeLayout hintLayout = (PercentRelativeLayout) findViewById(R.id.oliveapp_detected_hint_text_layout);
PercentRelativeLayout.LayoutParams params = new PercentRelativeLayout.LayoutParams(0, 0);
PercentLayoutHelper.PercentLayoutInfo info = params.getPercentLayoutInfo();
info.widthPercent = 1f;
info.heightPercent = 0.052f;
......@@ -380,7 +370,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
mVerificationController.uninit();
// 重新初始化音频动画
// mAudioModule = new AudioModule();
mAudioModule = new AudioModule();
mAnimationHanlder = new Handler();
// 初始化
......@@ -432,46 +422,49 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
// 使用预设配置: 满足绝大多数常见场景
mLivenessDetectorConfig = new LivenessDetectorConfig();
mLivenessDetectorConfig.usePredefinedConfig(0);
mMediaRecordConfig = new MediaRecordConfig();
// 改变默认的模型路径,不访问sdcard
mLivenessDetectorConfig.sdcardPath = ApplicationParameters.STORAGE_PATH;
mLivenessDetectorConfig.modelPath = ApplicationParameters.STORAGE_PATH + "/model";
mLivenessDetectorConfig.fixedActions = true;
mLivenessDetectorConfig.fixedActionList = Arrays.asList(1, 3);
mLivenessDetectorConfig.minPass = 2;
mLivenessDetectorConfig.maxFail = 1;
/**
* 注意,以下代码是配合SampleApp的设置工程,请在集成时请删除
*/
// SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
// boolean isDebug = sharedPrefs.getBoolean("pref_debug_mode", false);
// if (isDebug) {
// int actionOne = Integer.valueOf(sharedPrefs.getString("pref_action_one_list", "3"));
// int actionTwo = Integer.valueOf(sharedPrefs.getString("pref_action_two_list", "3"));
// int actionThree = Integer.valueOf(sharedPrefs.getString("pref_action_three_list", "3"));
// mLivenessDetectorConfig.totalActions = Integer.valueOf(sharedPrefs.getString
// ("pref_action_counts_list", "3"));
// mLivenessDetectorConfig.timeoutMs = Integer.valueOf(sharedPrefs.getString
// ("pref_liveness_detection_overtime_list", "10000"));
// mLivenessDetectorConfig.fanapaiClsImageNumber = Integer.valueOf(sharedPrefs.getString
// ("pref_fanpaicls_counts_list", "10000"));
// mLivenessDetectorConfig.fixedActions = sharedPrefs.getBoolean("pref_fix_action", false);
// mLivenessDetectorConfig.fixedActionList = Arrays.asList(actionOne, actionTwo,
// actionThree);
// LogUtil.e(TAG, mLivenessDetectorConfig.fixedActionList.toString());
// mLivenessDetectorConfig.saveRgb = sharedPrefs.getBoolean("pref_save_rgb", false);
// mLivenessDetectorConfig.saveOriginImage = sharedPrefs.getBoolean
// ("pref_save_origin_image", false);
// mLivenessDetectorConfig.savePackage = sharedPrefs.getBoolean("pref_save_package",
// false);
// mLivenessDetectorConfig.saveJPEG = sharedPrefs.getBoolean("pref_jpeg_image", false);
// mLivenessDetectorConfig.saveFanpaiCls = sharedPrefs.getBoolean
// ("pref_fanpaicls_image", false);
// mLivenessDetectorConfig.newPackage = sharedPrefs.getBoolean("pref_new_package", true);
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean isDebug = sharedPrefs.getBoolean("pref_debug_mode", false);
if (isDebug) {
int actionOne = Integer.valueOf(sharedPrefs.getString("pref_action_one_list", "3"));
int actionTwo = Integer.valueOf(sharedPrefs.getString("pref_action_two_list", "3"));
int actionThree = Integer.valueOf(sharedPrefs.getString("pref_action_three_list", "3"));
mLivenessDetectorConfig.totalActions = Integer.valueOf(sharedPrefs.getString("pref_action_counts_list", "3"));
mLivenessDetectorConfig.minPass = mLivenessDetectorConfig.totalActions;
mLivenessDetectorConfig.maxFail = 0;
mLivenessDetectorConfig.timeoutMs = Integer.valueOf(sharedPrefs.getString("pref_liveness_detection_overtime_list", "10000"));
mLivenessDetectorConfig.fanapaiClsImageNumber = Integer.valueOf(sharedPrefs.getString("pref_fanpaicls_counts_list", "10000"));
mLivenessDetectorConfig.fixedActions = sharedPrefs.getBoolean("pref_fix_action", false);
mLivenessDetectorConfig.fixedActionList = Arrays.asList(actionOne, actionTwo, actionThree);
LogUtil.e(TAG, mLivenessDetectorConfig.fixedActionList.toString());
// 以下存图功能在不访问sdcard时无法使用
mLivenessDetectorConfig.saveRgb = sharedPrefs.getBoolean("pref_save_rgb", false);
mLivenessDetectorConfig.saveOriginImage = sharedPrefs.getBoolean("pref_save_origin_image", false);
mLivenessDetectorConfig.savePackage = sharedPrefs.getBoolean("pref_save_package", false);
mLivenessDetectorConfig.saveJPEG = sharedPrefs.getBoolean("pref_jpeg_image", false);
mLivenessDetectorConfig.saveFanpaiCls = sharedPrefs.getBoolean("pref_fanpaicls_image", false);
mLivenessDetectorConfig.newPackage = sharedPrefs.getBoolean("pref_new_package", true);
//此处默认值为0, 代表无昏暗检测
// mLivenessDetectorConfig.darkLevel = getDarkLevelFromDesc(sharedPrefs.getString
// ("pref_dark_detect_list", "0"));
// }
mLivenessDetectorConfig.fixedActions = true;
mLivenessDetectorConfig.fixedActionList = Arrays.asList(1, 3);
mLivenessDetectorConfig.darkLevel = getDarkLevelFromDesc(sharedPrefs.getString("pref_dark_detect_list", "0"));
mLivenessDetectorConfig.minPass = 2;
mLivenessDetectorConfig.maxFail = 1;
//视频录制相关配置。不访问sdcard时无法录制视频
mMediaRecordConfig.isEnable = sharedPrefs.getBoolean("pref_video", false);
//mMediaRecordConfig.videoPath = Environment.getExternalStorageDirectory().getPath() + "/video";
}
/** 注意,以上代码集成时请删除 **/
if (mLivenessDetectorConfig != null) {
......@@ -489,25 +482,28 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
* 请先调用setDetectionParameter()设置参数
*/
private void initControllers() {
// 改变默认的存储路径(默认为访问外存),需要在初始化算法前设置
ApplicationParameters.STORAGE_PATH = this.getApplicationContext().getApplicationContext().getFilesDir().getAbsolutePath();
try {
setDetectionParameter();
} catch (Exception e) {
LogUtil.e(TAG, "初始化参数失败", e);
}
//这里设置字段,用于防重放攻击
mLivenessDetectorConfig.setUserDefinedContent("user_defined_content");
//初始化算法模块
mVerificationController = VerificationControllerFactory.createVerificationController
(mVerificationControllerType, LivenessDetectionMainActivity.this,
mImageProcessParameter,
mLivenessDetectorConfig,
LivenessDetectionMainActivity.this,
new Handler(Looper.getMainLooper()));
mVerificationController = VerificationControllerFactory.createVerificationController(mVerificationControllerType, LivenessDetectionMainActivity.this,
mImageProcessParameter,
mLivenessDetectorConfig,
LivenessDetectionMainActivity.this,
new Handler(Looper.getMainLooper()));
//设置人脸框位置
mVerificationController.SetFaceLocation(mXPercent, mYPercent, mWidthPercent,
mHeightPercent);
mVerificationController.SetFaceLocation(mXPercent, mYPercent, mWidthPercent, mHeightPercent);
}
/**===========================算法相关函数==============================**/
/**===========================算法相关函数==============================**/
/**
* 调用此函数后活体检测即开始
......@@ -529,8 +525,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
* 请在里面调用mVerificationController.enterLivenessDetection()进入活体检测阶段
*/
@Override
public void onPrestartSuccess(LivenessDetectionFrames livenessDetectionFrames,
OliveappFaceInfo faceInfo) {
public void onPrestartSuccess(LivenessDetectionFrames livenessDetectionFrames, OliveappFaceInfo faceInfo) {
LogUtil.i(TAG, "[BEGIN] onPrestartSuccess");
mAnimationHanlder.removeCallbacks(mPreHintAnimation);
mIsPrestart = false;
......@@ -544,16 +539,13 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
/**
* 预检阶段每一帧的回调函数
*
* @param frame 每一帧
* @param frame 每一帧
* @param remainingTimeMillisecond 剩余时间
* @param faceInfo 人脸信息
* @param errorCodeOfInAction 动作不过关的可能原因,可以用来做提示语
* @param faceInfo 人脸信息
* @param errorCodeOfInAction 动作不过关的可能原因,可以用来做提示语
*/
@Override
public void onPrestartFrameDetected(PrestartDetectionFrame frame, int
remainingTimeMillisecond, OliveappFaceInfo faceInfo, ArrayList<Integer>
errorCodeOfInAction) {
public void onPrestartFrameDetected(PrestartDetectionFrame frame, int remainingTimeMillisecond, OliveappFaceInfo faceInfo, ArrayList<Integer> errorCodeOfInAction) {
mFrameRate += 1;
long currentTimestamp = System.currentTimeMillis();
if ((currentTimestamp - mLastTimestamp) > 1000) {
......@@ -562,7 +554,6 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
mFrameRate = 0;
}
}
/**
* 预检阶段失败,不可能进入此回调
*/
......@@ -570,23 +561,20 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
public void onPrestartFail(int result) {
LogUtil.wtf(TAG, "[END] onPrestartFail");
Intent intent = new Intent(LivenessDetectionMainActivity.this,
SampleUnusualResultActivity.class);
intent.putExtra(SampleUnusualResultActivity.keyToGetExtra, SampleUnusualResultActivity
.PRESTART_FAIL);
startActivity(intent);
// Intent intent = new Intent(LivenessDetectionMainActivity.this, SampleUnusualResultActivity.class);
// intent.putExtra(SampleUnusualResultActivity.keyToGetExtra, SampleUnusualResultActivity.PRESTART_FAIL);
// startActivity(intent);
}
/**
* 活体检测成功的回调
*
* 活体检测成功的回调
* @param livenessDetectionFrames 活体检测抓取的图片
* @param faceInfo 捕获到的人脸信息
* @param faceInfo 捕获到的人脸信息
*/
@Override
public void onLivenessSuccess(LivenessDetectionFrames livenessDetectionFrames,
OliveappFaceInfo faceInfo) {
public void onLivenessSuccess(LivenessDetectionFrames livenessDetectionFrames, OliveappFaceInfo faceInfo) {
releaseAudioAnimination();
mIsLivenessSuccess = true;
}
// 关闭音频&动画
......@@ -595,10 +583,10 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
mAnimationHanlder.removeCallbacksAndMessages(null);
mAnimationHanlder = null;
}
// if (mAudioModule != null) {
// mAudioModule.release();
// mAudioModule = null;
// }
if (mAudioModule != null) {
mAudioModule.release();
mAudioModule = null;
}
}
/**
......@@ -611,20 +599,17 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
/**
* 每一帧结果的回调方法
*
* @param currentActionType 当前是什么动作
* @param actionState 当前动作的检测结果
* @param sessionState 整个Session是否通过
* @param currentActionType 当前是什么动作
* @param actionState 当前动作的检测结果
* @param sessionState 整个Session是否通过
* @param remainingTimeoutMilliSecond 剩余时间,以毫秒为单位
* @param faceInfo 检测到的人脸信息,可以用来做动画
* @param errorCodeOfInAction 动作不过关的可能原因,可以用来做提示语
* @param faceInfo 检测到的人脸信息,可以用来做动画
* @param errorCodeOfInAction 动作不过关的可能原因,可以用来做提示语
*/
@Override
public void onFrameDetected(int currentActionType, int actionState, int sessionState, int
remainingTimeoutMilliSecond, OliveappFaceInfo faceInfo, ArrayList<Integer>
errorCodeOfInAction) {
LogUtil.i(TAG, "[BEGIN] onFrameDetected " + remainingTimeoutMilliSecond);
public void onFrameDetected(int currentActionType, int actionState, int sessionState, int remainingTimeoutMilliSecond, OliveappFaceInfo faceInfo, ArrayList<Integer> errorCodeOfInAction) {
LogUtil.i(TAG, "[BEGIN] onFrameDetected " + remainingTimeoutMilliSecond);
mCountDownTextView.setText("" + (remainingTimeoutMilliSecond / 1000 + 1));
mLocationArray = getFaceInfoLocation(mCurrentActionType, faceInfo);
mFrameRate += 1;
......@@ -639,15 +624,13 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
/**
* 切换到下一个动作时的回调方法
*
* @param lastActionType 上一个动作类型
* @param lastActionResult 上一个动作的检测结果
* @param newActionType 当前新生成的动作类型
* @param lastActionType 上一个动作类型
* @param lastActionResult 上一个动作的检测结果
* @param newActionType 当前新生成的动作类型
* @param currentActionIndex 当前是第几个动作
* @param faceInfo 人脸的信息
* @param faceInfo 人脸的信息
*/
public void onActionChanged(int lastActionType, int lastActionResult, int newActionType, int
currentActionIndex, OliveappFaceInfo faceInfo) {
public void onActionChanged(int lastActionType, int lastActionResult, int newActionType, int currentActionIndex, OliveappFaceInfo faceInfo) {
try {
// 更新提示文字
String hintText;
......@@ -670,7 +653,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
mAnimationHanlder.removeCallbacksAndMessages(null);
mAnimationHanlder.post(mActionAnimationTask);
} catch (Exception e) {
LogUtil.i(TAG, "changeToNextAction interrupt");
LogUtil.i(TAG,"changeToNextAction interrupt");
}
}
......@@ -679,14 +662,12 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
/**
* 拿到当前动作对应的脸部坐标,用于做动画
*
* @param actionType 动作类型
* @param faceInfo 对应的人脸信息
* @param faceInfo 对应的人脸信息
* @return 脸部坐标数组
*/
private ArrayList<Pair<Double, Double>> getFaceInfoLocation(int actionType, OliveappFaceInfo
faceInfo) {
ArrayList<Pair<Double, Double>> result = new ArrayList<Pair<Double, Double>>();
private ArrayList<Pair<Double, Double>> getFaceInfoLocation(int actionType, OliveappFaceInfo faceInfo) {
ArrayList<Pair<Double, Double>> result = new ArrayList<Pair<Double,Double>>();
switch (actionType) {
case FacialActionType.EYE_CLOSE: {
result.add(faceInfo.leftEye);
......@@ -707,6 +688,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
//========================根据设置决定本Activity要采用哪个layout=======================//
private int decideWhichLayout() {
int layout = R.layout.oliveapp_sample_liveness_detection_main_portrait_phone;
//选择布局文件
switch (SampleScreenDisplayHelper.getFixedOrientation(this)) {
......@@ -720,6 +702,15 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
case LANDSCAPE:
if (!SampleScreenDisplayHelper.ifThisIsPhone(this)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE);
/**
* 针对 Android8.1.0 上调用SetRequestedOrientation但摄像头角度不随着变化的bug作机型适配
* @param NEED_REGULATE true为图片角度需要校正,false为不需要
* @param REGULATE_DEGREE 要校正的角度(顺时针旋转)
*/
if(Build.MODEL.equals("Lenovo TB-X705M")) {
VerificationController.NEED_REGULATE = true;
VerificationController.REGULATE_DEGREE = 90;
}
layout = R.layout.oliveapp_sample_liveness_detection_main_landscape;
} else {
layout = R.layout.oliveapp_sample_liveness_detection_main_portrait_phone;
......@@ -751,12 +742,13 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
return 0;
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
if(hasFocus) {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
......@@ -777,8 +769,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
private void increaseClassObjectCount() {
// DEBUG: 检测是否有Activity泄漏
classObjectCount++;
LogUtil.i(TAG, "LivenessDetectionMainActivity classObjectCount onCreate: " +
classObjectCount);
LogUtil.i(TAG, "LivenessDetectionMainActivity classObjectCount onCreate: " + classObjectCount);
// 预期现象是classObjectCount会在1~2之间抖动,如果classObjectCount一直在增长,很可能有内存泄漏
if (classObjectCount == 10) {
......@@ -797,8 +788,7 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
}
// DEBUG: 检测是否有Activity泄漏。与increaseClassObjectCount对应
classObjectCount--;
LogUtil.i(TAG, "LivenessDetectionMainActivity classObjectCount finalize: " +
classObjectCount);
LogUtil.i(TAG, "LivenessDetectionMainActivity classObjectCount finalize: " + classObjectCount);
}
......@@ -808,9 +798,8 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
private Runnable mActionAnimationTask = new Runnable() {
@Override
public void run() {
if (/*mAudioModule != null && */mAnimController != null) {
// mAudioModule.playAudio(LivenessDetectionMainActivity.this, FacialActionType
// .getStringResourceName(mCurrentActionType));
if (mAudioModule != null && mAnimController != null) {
mAudioModule.playAudio(LivenessDetectionMainActivity.this, FacialActionType.getStringResourceName(mCurrentActionType));
mAnimController.playActionAnimation(mCurrentActionType, mLocationArray);
mAnimationHanlder.postDelayed(this, 2500);
}
......@@ -823,9 +812,8 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
private Runnable mPreHintAnimation = new Runnable() {
@Override
public void run() {
if (/*mAudioModule != null && */mAnimController != null) {
// mAudioModule.playAudio(LivenessDetectionMainActivity.this, FacialActionType
// .getStringResourceName(FacialActionType.CAPTURE));
if (mAudioModule != null && mAnimController != null) {
mAudioModule.playAudio(LivenessDetectionMainActivity.this, FacialActionType.getStringResourceName(FacialActionType.CAPTURE));
mAnimController.playAperture();
mAnimationHanlder.postDelayed(this, 2500);
}
......@@ -839,13 +827,27 @@ public abstract class LivenessDetectionMainActivity extends Activity implements
}
public void onInitializeFail(Throwable e) {
}
/**
* 获取大礼包
* @return 大礼包
*/
/*protected LivenessDetectionFrames getLivenessDetectionPackage() {
protected LivenessDetectionFrames getLivenessDetectionPackage() {
return mVerificationController.getLivenessDetectionPackage();
}*/
}
@Override
public void onMediaSaveSuccess(String s) {
LogUtil.d(TAG, "onMediaSaveSuccess path = " + s + ", IsLivenessSuccess " + mIsLivenessSuccess);
//活检失败将视频删除
if (!mIsLivenessSuccess) {
try{
CameraUtil.deleteMediaRecord(s);
} catch (Exception e) {
LogUtil.e(TAG, "视频删除失败", e);
}
}
}
}
package com.oliveapp.liveness.sample.register;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import com.oliveapp.liveness.sample.R;
public class SampleCameraResultActivity extends Activity{
public static final String TAG = SampleCameraResultActivity.class.getSimpleName();
public static final String EXTRA_IMAGE_CONTENT = "image_content";
public static final String EXTRA_FACE_EXISTS = "face_exists";
public static final String EXTRA_FACE_RECT = "face_rect";
private ImageView mImageView;
private Button mRetakeButton;
private Button mBackButton;
public static final int livenessMode = 4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_register_result);
mImageView = (ImageView) findViewById(R.id.captureImageImageView);
mRetakeButton = (Button) findViewById(R.id.retakeButton);
mBackButton = (Button) findViewById(R.id.confirmButton);
Bundle result = getIntent().getExtras();
final int mode = result.getInt(SampleImageCaptureActivity.EXTRA_CAPTURE_MODE);
byte[] imageContent = result.getByteArray(EXTRA_IMAGE_CONTENT);
boolean faceExists = result.getBoolean(EXTRA_FACE_EXISTS);
Bitmap capturedImage = BitmapFactory.decodeByteArray(imageContent, 0, imageContent.length);
if (faceExists) {
Bitmap imageWithRect = capturedImage.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(imageWithRect);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10);
String rectString = result.getString(EXTRA_FACE_RECT);
Rect rect = Rect.unflattenFromString(rectString);
canvas.drawRect(rect, paint);
mImageView.setImageBitmap(imageWithRect);
} else {
mImageView.setImageBitmap(capturedImage);
}
//
if (livenessMode == mode) {
mRetakeButton.setVisibility(View.INVISIBLE);
}
mRetakeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(SampleCameraResultActivity.this, SampleImageCaptureActivity.class);
i.putExtra(SampleImageCaptureActivity.EXTRA_CAPTURE_MODE, mode);
startActivity(i);
finish();
}
});
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
package com.oliveapp.liveness.sample.register;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.oliveapp.face.idcardcaptorsdk.captor.IDCardCaptor;
import com.oliveapp.libcommon.utility.LogUtil;
import com.oliveapp.libimagecapture.CaptureImageFragment;
import com.oliveapp.liveness.sample.R;
import com.oliveapp.liveness.sample.idcard_captor.SampleIdcardCaptorActivity;
public class SampleChooseCameraActivity extends Activity {
public static final String TAG = SampleChooseCameraActivity.class.getSimpleName();
private Button mIdCardButton;
private Button mSelfieButton;
private Button mIdcardFrontCaptureButton;
private Button mIdcardBackCaptureButton;
private IdcardCaptureListener mIdcardCaptureListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_register);
mIdCardButton = (Button) findViewById(R.id.IDcard);
mSelfieButton = (Button) findViewById(R.id.Selfie);
mIdcardFrontCaptureButton = (Button) findViewById(R.id.IdcardFrontCapture);
mIdcardBackCaptureButton = (Button) findViewById(R.id.IdcardBackCapture);
/**
* 拍摄身份证正面,反面请使用CaptureImageFragment.CAPTURE_MODE_IDCARD_BACK
*/
mIdCardButton.setOnClickListener(
new CaptureImageListener(CaptureImageFragment.CAPTURE_MODE_IDCARD_FRONT));
/**
* 拍摄类登记照
*/
mSelfieButton.setOnClickListener(
new CaptureImageListener(CaptureImageFragment.CAPTURE_MODE_SELFIE));
mIdcardCaptureListener = new IdcardCaptureListener();
mIdcardFrontCaptureButton.setOnClickListener(mIdcardCaptureListener);
mIdcardBackCaptureButton.setOnClickListener(mIdcardCaptureListener);
requestPermission();
}
private class CaptureImageListener implements View.OnClickListener {
private int mCaptureType;
public CaptureImageListener(int captureMode) {
mCaptureType = captureMode;
}
@Override
public void onClick(View v) {
if (requestPermission()) {
Intent i = new Intent(SampleChooseCameraActivity.this, SampleImageCaptureActivity.class);
i.putExtra(SampleImageCaptureActivity.EXTRA_CAPTURE_MODE, mCaptureType);
startActivity(i);
}
}
}
private class IdcardCaptureListener implements View.OnClickListener {
@Override
public void onClick(View v) {
Intent i = new Intent(SampleChooseCameraActivity.this, SampleIdcardCaptorActivity.class);
/**
* 设置身份证识别正面还是反面
*/
int i1 = v.getId();
if (i1 == R.id.IdcardFrontCapture) {
i.putExtra(SampleIdcardCaptorActivity.EXTRA_CARD_TYPE, IDCardCaptor.CARD_TYPE_FRONT);
} else if (i1 == R.id.IdcardBackCapture) {
i.putExtra(SampleIdcardCaptorActivity.EXTRA_CARD_TYPE, IDCardCaptor.CARD_TYPE_BACK);
}
/**
* 设置捕获模式,共有三种模式模式:
* 1.SampleIdcardCaptorActivity.CAPTURE_MODE_AUTO 自动捕获模式
* 2.SampleIdcardCaptorActivity.CAPTURE_MODE_MANUAL 手动拍摄模式
* 3.SampleIdcardCaptorActivity.CAPTURE_MODE_MIXED 混合模式,首先尝试自动捕获,指定时间后,采取手动拍摄
* 在本例中,使用混合捕获模式,需要设置自动捕获持续时间,单位为秒,默认10秒
*/
i.putExtra(SampleIdcardCaptorActivity.EXTRA_CAPTURE_MODE, SampleIdcardCaptorActivity.CAPTURE_MODE_MIXED);
i.putExtra(SampleIdcardCaptorActivity.EXTRA_DURATION_TIME, 10);
if (requestPermission()) {
startActivity(i);
}
}
}
/**==============================请求相机权限=========================**/
private static final int PERMISSION_READ_EXTERNAL_STORAGE = 101;
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 102;
private static final int PERMISSION_CAMERA = 103;
private boolean requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_WRITE_EXTERNAL_STORAGE);
return false;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_READ_EXTERNAL_STORAGE);
return false;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_CAMERA);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
try {
switch (requestCode) {
case PERMISSION_CAMERA: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(this, "没有摄像头权限我什么都做不了哦!", Toast.LENGTH_LONG).show();
}
break;
}
case PERMISSION_READ_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(this, "请打开存储读写权限,确保APP正常运行", Toast.LENGTH_LONG).show();
}
break;
}
case PERMISSION_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
Toast.makeText(this, "请打开存储读写权限,确保APP正常运行", Toast.LENGTH_LONG).show();
}
break;
}
}
} catch (Exception e) {
LogUtil.e(TAG, "Failed to request Permission", e);
}
}
}
package com.oliveapp.liveness.sample.register;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.oliveapp.libcommon.utility.PackageNameManager;
import com.oliveapp.libimagecapture.CaptureImageFragment;
import com.oliveapp.libimagecapture.OnImageCapturedEventListener;
import com.oliveapp.libimagecapture.datatype.DetectedRect;
import com.oliveapp.liveness.sample.R;
public class SampleImageCaptureActivity extends Activity implements OnImageCapturedEventListener {
public static final String TAG = SampleImageCaptureActivity.class.getSimpleName();
public static final String EXTRA_CAPTURE_MODE = "capture_mode";
private CaptureImageFragment mCaptureImageFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
if (!PackageNameManager.isPackageNameSet()) {
PackageNameManager.setPackageName(getPackageName());
}
PackageNameManager.setPackageName(PackageNameManager.getPackageName());
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_image_capture);
attachUserImageRegistractionFragment();
}
private void attachUserImageRegistractionFragment() {
FragmentManager mFragmentManager = getFragmentManager();
CaptureImageFragment userImageRegisterFragment = (CaptureImageFragment) mFragmentManager.findFragmentByTag(CaptureImageFragment.TAG);
if (userImageRegisterFragment == null) {
int captureType = getIntent().getExtras().getInt(EXTRA_CAPTURE_MODE, CaptureImageFragment.CAPTURE_MODE_IDCARD_FRONT);
userImageRegisterFragment = CaptureImageFragment.newInstance(captureType);
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.add(R.id.imageCaptureMainLayout, userImageRegisterFragment, CaptureImageFragment.TAG);
ft.commit();
} else {
if (userImageRegisterFragment.isAdded()) {
Log.i(TAG, "user image register fragment already attached");
}
}
userImageRegisterFragment.setArgs(this, this);
mCaptureImageFragment = userImageRegisterFragment;
}
@Override
public void OnImageCaptured(byte[] imageContent, DetectedRect faceRect) {
boolean faceExists = (faceRect != null);
Intent i = new Intent(this, SampleCameraResultActivity.class);
i.putExtra(EXTRA_CAPTURE_MODE, getIntent().getExtras().getInt(EXTRA_CAPTURE_MODE, CaptureImageFragment.CAPTURE_MODE_IDCARD_FRONT));
i.putExtra(SampleCameraResultActivity.EXTRA_IMAGE_CONTENT, imageContent);
i.putExtra(SampleCameraResultActivity.EXTRA_FACE_EXISTS, faceExists);
if (faceExists) {
i.putExtra(SampleCameraResultActivity.EXTRA_FACE_RECT, faceRect.rect.flattenToString());
}
startActivity(i);
finish();
}
}
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="#ff00427d"/>
</shape>
</item>
<item android:state_selected="true">
<shape>
<solid android:color="#ff005aaa"/>
</shape>
</item>
<item android:state_enabled="false">
<shape>
<solid android:color="#80005aaa"/>
</shape>
</item>
<item>
<shape>
<solid android:color="#ff005aaa"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:useLevel="true"
android:innerRadiusRatio="2.7"
android:thickness="4dp"
android:shape="ring">
<!--<stroke android:width="1dp" android:color="#07ADD0"/>-->
<solid android:color="#02ADCF"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
android:useLevel="false"
android:shape="oval">
<solid android:color="#5DC6E2" />
</shape>
</item>
<item>
<shape
android:useLevel="false"
android:innerRadiusRatio="2.7"
android:thickness="4dp"
android:shape="ring">
<!--<solid android:color="#02ADCF" />-->
<solid android:color="#ffffff" />
</shape>
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:useLevel="false"
android:innerRadiusRatio="2.7"
android:thickness="4dp"
android:shape="oval">
<stroke android:width="1dp" android:color="#5DC6E2"/>
<solid android:color="#FF4D4D4D"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="#ff00427d"/>
</shape>
</item>
<item android:state_selected="true">
<shape>
<solid android:color="#ff005aaa"/>
</shape>
</item>
<item android:state_enabled="false">
<shape>
<solid android:color="#80005aaa"/>
</shape>
</item>
<item>
<shape>
<solid android:color="#ff005aaa"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- 橙色人脸框,仅供debug用,非产品需求 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:color="@color/navy"
android:width="2dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/oliveapp_liveness_return" android:state_pressed="false"/>
<item android:drawable="@mipmap/oliveapp_liveness_return" android:state_pressed="true"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/oliveapp_liveness_return" android:state_pressed="false"/>
<item android:drawable="@mipmap/oliveapp_liveness_return" android:state_pressed="true"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@mipmap/oliveapp_liveness_return"/>
<item android:state_pressed="false" android:drawable="@mipmap/oliveapp_liveness_return"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/checkbox_unchecked"
android:state_checked="false"
android:state_enabled="true"/>
<item
android:drawable="@drawable/checkbox_checked"
android:state_checked="true"
android:state_enabled="true"/>
<item
android:drawable="@drawable/checkbox_disable_unchecked"
android:state_checked="false"
android:state_enabled="false"/>
<item
android:drawable="@drawable/checkbox_disable_checked"
android:state_checked="true"
android:state_enabled="false"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:drawable="@color/itemdisabled" />
<item android:state_enabled="false" android:drawable="@color/itemdisabled" />
<item android:state_enabled="true" android:state_pressed="true" android:drawable="@color/itemSelectColor" />
<item android:state_focused="true" android:state_enabled="true" android:drawable="@color/itemSelectColor" />
<item android:state_enabled="true" android:state_selected="true" android:drawable="@color/itemSelectColor" />
<item android:drawable="@color/itemBgColor" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.oliveapp.liveness.sample.idcard_captor.SampleIdcardActivity">
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ImageCaptureActivity"
android:id="@+id/imageCaptureMainLayout">
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/oliveapp_activity_vertical_margin"
android:paddingLeft="@dimen/oliveapp_activity_horizontal_margin"
android:paddingRight="@dimen/oliveapp_activity_horizontal_margin"
android:paddingTop="@dimen/oliveapp_activity_vertical_margin"
android:background="@color/colorDefaultBackground"
tools:context=".SampleLaunchActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/titleText"
android:id="@+id/titleTextView"
android:layout_alignParentTop="true"
android:layout_marginTop="70dp"
android:layout_centerHorizontal="true"
android:textSize="40sp"
android:textColor="@color/colorWhite"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/oliveapp_version"
android:textColor="@color/colorWhite"
android:textSize="20sp" />
<!--<TextView-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:textAppearance="?android:attr/textAppearanceLarge"-->
<!--android:text="@string/subtitleText"-->
<!--android:id="@+id/subtitleTextView"-->
<!--android:layout_below="@+id/titleTextView"-->
<!--android:layout_alignLeft="@+id/titleTextView"-->
<!--android:layout_alignStart="@+id/titleTextView" />-->
<Button
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:text="@string/hintCamera"
android:id="@+id/startButton"
android:layout_centerHorizontal="true"
android:layout_below="@+id/titleTextView"
android:layout_marginTop="100dp"
android:background="@drawable/oliveapp_button_background"
android:textColor="#ffffff"
android:textSize="20sp" />
<Button
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:text="@string/livenessButtonText"
android:id="@+id/livenessButton"
android:background="@drawable/oliveapp_button_background"
android:textColor="#ffffff"
android:textSize="20sp"
android:layout_below="@+id/startButton"
android:layout_marginTop="20dp"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:text="@string/settingButtonText"
android:id="@+id/settingButton"
android:background="@drawable/oliveapp_button_background"
android:textColor="#ffffff"
android:textSize="20sp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="60dp" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/oliveapp_activity_vertical_margin"
android:paddingLeft="@dimen/oliveapp_activity_horizontal_margin"
android:paddingRight="@dimen/oliveapp_activity_horizontal_margin"
android:paddingTop="@dimen/oliveapp_activity_vertical_margin"
android:background="@color/colorDefaultBackground"
tools:context=".register.SampleChooseCameraActivity">
<LinearLayout
android:id="@+id/chooseImageTypeLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_marginTop="50dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp">
<Button
android:id="@+id/IDcard"
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginBottom="30dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:text="@string/hintIDcard"
android:layout_gravity="center_horizontal"
android:textSize="16sp"
android:gravity="center_horizontal|center_vertical"
android:background="@drawable/oliveapp_button_background"
android:layout_marginTop="25dp"
android:textColor="#ffffff" />
<Button
android:id="@+id/Selfie"
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginBottom="30dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:text="@string/hintFrontCamera"
android:layout_gravity="center_horizontal"
android:textSize="16sp"
android:gravity="center_horizontal|center_vertical"
android:background="@drawable/oliveapp_button_background"
android:layout_marginTop="25dp"
android:textColor="#ffffff" />
<Button
android:id="@+id/IdcardFrontCapture"
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginBottom="30dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:text="@string/hintIdcardCapture"
android:layout_gravity="center_horizontal"
android:textSize="16sp"
android:gravity="center_horizontal|center_vertical"
android:background="@drawable/oliveapp_button_background"
android:layout_marginTop="25dp"
android:textColor="#ffffff" />
<Button
android:id="@+id/IdcardBackCapture"
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginBottom="30dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:text="@string/hintIdcardBackCapture"
android:layout_gravity="center_horizontal"
android:textSize="16sp"
android:gravity="center_horizontal|center_vertical"
android:background="@drawable/oliveapp_button_background"
android:layout_marginTop="25dp"
android:textColor="#ffffff" />
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/oliveapp_activity_vertical_margin"
android:paddingLeft="@dimen/oliveapp_activity_horizontal_margin"
android:paddingRight="@dimen/oliveapp_activity_horizontal_margin"
android:paddingTop="@dimen/oliveapp_activity_vertical_margin"
android:background="@color/colorDefaultBackground"
tools:context=".register.SampleCameraResultActivity">
<ImageView
android:layout_width="300dp"
android:layout_height="300dp"
android:id="@+id/captureImageImageView"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:text="重新拍摄"
android:textColor="@color/colorWhite"
android:id="@+id/retakeButton"
android:layout_marginBottom="20dp"
android:layout_centerHorizontal="true"
android:background="@drawable/oliveapp_button_background"
android:layout_above="@+id/confirmButton" />
<Button
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:text="返回"
android:textColor="@color/colorWhite"
android:id="@+id/confirmButton"
android:background="@drawable/oliveapp_button_background"
android:layout_alignParentBottom="true"
android:layout_marginBottom="60dp"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<?xml version="1.0" encoding="UTF-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/arrow"
android:clickable="false"
android:focusable="false" />
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- 这里放上系统的id -->
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:button="@drawable/selector_checkbox"
android:clickable="false"
android:focusable="false" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".idcard_captor.view_controller.SampleIdcardCaptorMainActivity">
<RelativeLayout
android:id="@+id/oliveapp_face_captureLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:visibility="visible">
<RelativeLayout
android:id="@+id/oliveapp_face_previewLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true">
<view
android:id="@+id/oliveapp_face_cameraPreviewView"
class="com.oliveapp.camerasdk.ui.CameraRootView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/oliveapp_face_captureIDCardHintLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible">
<ImageView
android:id="@+id/oliveapp_face_idcardSkeletonImageView"
android:layout_width="252dp"
android:layout_height="400dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/oliveapp_face_idcard_shade_skeleton_minimum3"
android:layout_centerInParent="true" />
<ImageView
android:id="@+id/oliveapp_face_scan_line"
android:layout_width="wrap_content"
android:layout_height="400dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/oliveapp_scan_line"/>
<ImageView
android:id="@+id/oliveapp_face_shadowLeftImageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/oliveapp_face_idcardSkeletonImageView"
android:layout_toStartOf="@+id/oliveapp_face_idcardSkeletonImageView"
android:scaleType="fitXY"
android:src="@drawable/oliveapp_face_black_shadow" />
<ImageView
android:id="@+id/oliveapp_face_shadowRightImageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="false"
android:layout_alignParentRight="true"
android:layout_toEndOf="@+id/oliveapp_face_idcardSkeletonImageView"
android:layout_toRightOf="@+id/oliveapp_face_idcardSkeletonImageView"
android:scaleType="fitXY"
android:src="@drawable/oliveapp_face_black_shadow" />
<ImageView
android:id="@+id/oliveapp_face_shadowTopImageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/oliveapp_face_shadowRightImageView"
android:layout_toRightOf="@+id/oliveapp_face_shadowLeftImageView"
android:adjustViewBounds="false"
android:baselineAlignBottom="false"
android:scaleType="fitXY"
android:src="@drawable/oliveapp_face_black_shadow"
android:layout_above="@+id/oliveapp_face_idcardSkeletonImageView" />
<ImageView
android:id="@+id/oliveapp_face_shadowBottomImageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/oliveapp_face_shadowRightImageView"
android:layout_toRightOf="@+id/oliveapp_face_shadowLeftImageView"
android:scaleType="fitXY"
android:src="@drawable/oliveapp_face_black_shadow"
android:layout_below="@+id/oliveapp_face_idcardSkeletonImageView" />
<com.oliveapp.libcommon.uicomponents.VerticalTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/oliveapp_face_hintTextView"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/oliveapp_face_database_image_hint_front"
android:textColor="#ffffff"
android:layout_marginLeft="5dp" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/oliveapp_frame_rate_text"
android:text="FPS: "/>
</RelativeLayout>
<!--<RelativeLayout-->
<!--android:id="@+id/oliveapp_face_takePictureButtonLayout"-->
<!--android:layout_width="fill_parent"-->
<!--android:layout_height="64dp"-->
<!--android:layout_alignParentBottom="true"-->
<!--android:layout_alignParentLeft="true"-->
<!--android:layout_alignParentRight="true"-->
<!--android:layout_alignParentStart="true"-->
<!--android:layout_centerHorizontal="true"-->
<!--android:background="@drawable/oliveapp_face_black_shadow">-->
<ImageButton
android:id="@+id/oliveapp_face_takePictureButton"
style="?android:attr/borderlessButtonStyle"
android:layout_height="64dp"
android:layout_width="wrap_content"
android:clickable="true"
android:src="@drawable/oliveapp_camera_alt_white_48dp"
android:scaleType="fitCenter"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:visibility="invisible"/>
<!--</RelativeLayout>-->
</RelativeLayout>
......@@ -83,7 +83,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hadapilah layar"
android:text="@string/oliveapp_step_hint_focus"
android:textColor="#FFFF00"
android:textSize="24sp" />
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_marginTopPercent="13.5%"
app:layout_widthPercent="36%"
app:layout_aspectRatio="462%"/>
<TextView
android:id="@+id/oliveappResultTextView"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
app:layout_widthPercent="80%"
app:layout_heightPercent="20%"
app:layout_marginTopPercent="41.6%"
android:textSize="40sp"
android:textColor="#FFFFFF"/>
<Button
android:id="@+id/oliveapp_liveness_result_retry"
android:layout_alignParentBottom="true"
app:layout_marginBottomPercent="10.8%"
app:layout_marginLeftPercent="15%"
app:layout_widthPercent="31%"
app:layout_aspectRatio="300%"/>
<Button
android:id="@+id/oliveapp_liveness_result_return"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:layout_marginBottomPercent="10.8%"
app:layout_marginRightPercent="15%"
app:layout_widthPercent="31%"
app:layout_aspectRatio="300%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingLeft="@dimen/oliveapp_activity_horizontal_margin"
android:paddingRight="@dimen/oliveapp_activity_horizontal_margin"
android:paddingTop="@dimen/oliveapp_activity_vertical_margin"
android:paddingBottom="@dimen/oliveapp_activity_vertical_margin"
tools:context="SampleUnusualResultActivity">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
app:layout_marginTopPercent="33.6%"
app:layout_widthPercent="49.1%"
app:layout_aspectRatio="462%"/>
<TextView
android:id="@+id/oliveappResultTextView"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
app:layout_widthPercent="80%"
app:layout_heightPercent="20%"
app:layout_marginTopPercent="41.6%"
android:textSize="30sp"
android:textColor="#FFFFFF"/>
<Button
android:id="@+id/oliveapp_liveness_result_retry"
android:layout_alignParentBottom="true"
android:background="@drawable/oliveapp_liveness_finish_retry"
app:layout_marginBottomPercent="8%"
app:layout_marginLeftPercent="6.1%"
app:layout_widthPercent="41.7%"
app:layout_aspectRatio="295%"/>
<Button
android:id="@+id/oliveapp_liveness_result_return"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="@drawable/oliveapp_liveness_finish_return_selector"
app:layout_marginBottomPercent="8%"
app:layout_marginRightPercent="6.1%"
app:layout_widthPercent="41.7%"
app:layout_aspectRatio="295%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_marginTopPercent="30%"
app:layout_widthPercent="49.1%"
app:layout_aspectRatio='462%'/>
<TextView
android:id="@+id/oliveappResultTextView"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
app:layout_widthPercent="80%"
app:layout_heightPercent="20%"
app:layout_marginTopPercent="41.6%"
android:textSize="40sp"
android:textColor="#FFFFFF"/>
<Button
android:id="@+id/oliveapp_liveness_result_retry"
android:layout_alignParentBottom="true"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_marginBottomPercent="10.8%"
app:layout_marginLeftPercent="10%"
app:layout_widthPercent="35%"
app:layout_aspectRatio="328%"/>
<Button
android:id="@+id/oliveapp_liveness_result_return"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_marginBottomPercent="10.8%"
app:layout_marginRightPercent="10%"
app:layout_widthPercent="35%"
app:layout_aspectRatio="328%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_marginRightPercent="25.5%"
app:layout_marginTopPercent="13.5%"
app:layout_widthPercent="36%"
app:layout_aspectRatio="462%"/>
<!--将下面列表使用listview表示-->
<ListView
android:id="@+id/oliveapp_liveness_saas_list"
android:layout_alignParentLeft="true"
app:layout_widthPercent="40%"
app:layout_heightPercent="40%"
app:layout_marginTopPercent="33.8%"
app:layout_marginLeftPercent="8.3%"
android:isScrollContainer="false"
android:divider="@android:color/transparent"
android:listSelector="@android:color/transparent"/>
<ImageView
android:layout_centerHorizontal="true"
app:layout_heightPercent="40%"
app:layout_widthPercent="2%"
app:layout_marginTopPercent="33%"
android:src="@mipmap/oliveapp_divider_tablet"/>
<android.support.percent.PercentRelativeLayout
app:layout_widthPercent="40%"
app:layout_heightPercent="40%"
app:layout_marginTopPercent="33%"
app:layout_marginRightPercent="8.2%"
android:layout_alignParentRight="true"
android:background="@mipmap/oliveapp_liveness_result_border">
<!--两张人脸-->
<!--第一张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_close"
app:layout_widthPercent="45%"
app:layout_heightPercent="90%"
app:layout_marginTopPercent="5%"
app:layout_marginLeftPercent="2.5%"/>
<ImageView
app:layout_widthPercent="40%"
app:layout_heightPercent="80%"
app:layout_marginTopPercent="10%"
app:layout_marginLeftPercent="5%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--第二张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_open"
app:layout_widthPercent="45%"
app:layout_heightPercent="90%"
app:layout_marginTopPercent="5%"
app:layout_marginRightPercent="2.5%"
android:layout_alignParentRight="true"/>
<ImageView
app:layout_widthPercent="40%"
app:layout_heightPercent="80%"
app:layout_marginTopPercent="10%"
app:layout_marginRightPercent="5%"
android:layout_alignParentRight="true"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
</android.support.percent.PercentRelativeLayout>
<Button
android:id="@+id/oliveapp_liveness_saas_result_retry"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:layout_marginBottomPercent="9%"
app:layout_marginRightPercent="28%"
app:layout_widthPercent="18%"
app:layout_aspectRatio="200%" />
<Button
android:id="@+id/oliveapp_liveness_saas_result_return"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:layout_marginBottomPercent="9%"
app:layout_marginRightPercent="8.3%"
app:layout_widthPercent="18%"
app:layout_aspectRatio="200%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_sample_saa_sresult"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.oliveapp.liveness.sample.SampleSaaSResultActivity">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
app:layout_marginRightPercent="25.5%"
app:layout_marginTopPercent="9.7%"
app:layout_widthPercent="49.1%"
app:layout_aspectRatio="462%"/>
<ImageView
app:layout_widthPercent="87.8%"
app:layout_heightPercent="24.6%"
app:layout_marginTopPercent="20.4%"
app:layout_marginRightPercent="5.1%"
android:layout_centerHorizontal="true"
android:background="@mipmap/oliveapp_liveness_result_border"/>
<!--两张人脸-->
<!--第一张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_close"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginLeftPercent="10.49%"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="13.5%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--第二张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_open"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginRightPercent="10.49%"
android:layout_alignParentRight="true"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="57.6%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--将下面列表使用listview表示-->
<ListView
android:id="@+id/oliveapp_liveness_saas_list"
android:layout_alignParentBottom="true"
app:layout_widthPercent="82.7%"
app:layout_heightPercent="25.4%"
app:layout_marginBottomPercent="25.3%"
app:layout_marginLeftPercent="8.6%"
android:isScrollContainer="false"
android:divider="@android:color/transparent"
android:listSelector="@android:color/transparent"/>
<Button
android:id="@+id/oliveapp_liveness_saas_result_retry"
android:layout_alignParentBottom="true"
android:background="@drawable/oliveapp_liveness_finish_retry"
app:layout_marginBottomPercent="8%"
app:layout_marginLeftPercent="6.1%"
app:layout_widthPercent="41.7%"
app:layout_aspectRatio="295%"/>
<Button
android:id="@+id/oliveapp_liveness_saas_result_return"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="@drawable/oliveapp_liveness_finish_return_selector"
app:layout_marginBottomPercent="8%"
app:layout_marginRightPercent="6.1%"
app:layout_widthPercent="41.7%"
app:layout_aspectRatio="295%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
app:layout_marginRightPercent="25.5%"
app:layout_marginTopPercent="9.7%"
app:layout_widthPercent="49.1%"
app:layout_heightPercent="7%"/>
<ImageView
app:layout_widthPercent="87.8%"
app:layout_heightPercent="24.6%"
app:layout_marginTopPercent="20.4%"
app:layout_marginRightPercent="5.1%"
android:layout_centerHorizontal="true"
android:background="@mipmap/oliveapp_liveness_result_border"/>
<!--两张人脸-->
<!--第一张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_close"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginLeftPercent="10.49%"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="13.5%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--第二张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_open"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginRightPercent="10.49%"
android:layout_alignParentRight="true"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="57.6%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--将下面列表使用listview表示-->
<ListView
android:id="@+id/oliveapp_liveness_saas_list"
android:layout_alignParentBottom="true"
app:layout_widthPercent="82.7%"
app:layout_heightPercent="25.4%"
app:layout_marginBottomPercent="25.3%"
app:layout_marginLeftPercent="8.6%"
android:isScrollContainer="false"
android:divider="@android:color/transparent"
android:listSelector="@android:color/transparent"/>
<Button
android:id="@+id/oliveapp_liveness_saas_result_retry"
android:layout_alignParentBottom="true"
app:layout_marginBottomPercent="8%"
app:layout_marginLeftPercent="6.1%"
app:layout_widthPercent="41.7%"
app:layout_aspectRatio="326%"/>
<Button
android:id="@+id/oliveapp_liveness_saas_result_return"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:layout_marginBottomPercent="8%"
app:layout_marginRightPercent="6.1%"
app:layout_widthPercent="41.7%"
app:layout_aspectRatio="326%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:id="@+id/oliveapp_liveness_result_list_layout"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/oliveapp_liveness_result_item"
android:gravity="center_vertical|left"
app:layout_widthPercent="70%"
app:layout_heightPercent="100%"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:textColor="#FFFFFF"
android:text="大礼包照片是否同一个人"/>
<ImageView
android:id="@+id/oliveapp_liveness_result_yesorno"
app:layout_widthPercent="10%"
app:layout_heightPercent="40%"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:src="@mipmap/oliveapp_liveness_result_right"/>
<TextView
android:id="@+id/oliveapp_liveness_result_detail"
app:layout_widthPercent="20%"
app:layout_heightPercent="50%"
app:layout_marginRightPercent="3%"
android:gravity="end"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/oliveapp_liveness_result_yesorno"
android:textColor="#6DE3E7"
android:text="0.0000000"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
android:src="#80000000"
android:layout_height="0dp"
android:layout_width="0dp"
app:layout_marginTopPercent="13.5%"
app:layout_widthPercent="36%"
app:layout_aspectRatio="462%"/>
<!--将下面列表使用listview表示-->
<ListView
android:id="@+id/oliveapp_liveness_saas_list"
android:layout_alignParentLeft="true"
app:layout_widthPercent="40%"
app:layout_heightPercent="40%"
app:layout_marginTopPercent="33.8%"
app:layout_marginLeftPercent="8.3%"
android:isScrollContainer="false"
android:divider="@android:color/transparent"
android:listSelector="@android:color/transparent"/>
<ImageView
android:layout_centerHorizontal="true"
app:layout_heightPercent="40%"
app:layout_widthPercent="2%"
app:layout_marginTopPercent="33%"
android:src="@mipmap/oliveapp_divider_tablet"/>
<android.support.percent.PercentRelativeLayout
app:layout_widthPercent="40%"
app:layout_heightPercent="40%"
app:layout_marginTopPercent="33%"
app:layout_marginRightPercent="8.2%"
android:layout_alignParentRight="true"
android:background="@mipmap/oliveapp_liveness_result_border">
<!--两张人脸-->
<!--第一张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_close"
app:layout_widthPercent="45%"
app:layout_heightPercent="90%"
app:layout_marginTopPercent="5%"
app:layout_marginLeftPercent="2.5%"/>
<ImageView
app:layout_widthPercent="40%"
app:layout_heightPercent="80%"
app:layout_marginTopPercent="10%"
app:layout_marginLeftPercent="5%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--第二张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_open"
app:layout_widthPercent="45%"
app:layout_heightPercent="90%"
app:layout_marginTopPercent="5%"
app:layout_marginRightPercent="2.5%"
android:layout_alignParentRight="true"/>
<ImageView
app:layout_widthPercent="40%"
app:layout_heightPercent="80%"
app:layout_marginTopPercent="10%"
app:layout_marginRightPercent="5%"
android:layout_alignParentRight="true"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
</android.support.percent.PercentRelativeLayout>
<Button
android:id="@+id/oliveapp_liveness_saas_result_finish"
android:layout_alignParentRight="true"
app:layout_marginTopPercent="82%"
app:layout_marginRightPercent="8.3%"
app:layout_widthPercent="18%"
app:layout_aspectRatio="200%"
/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_sample_saa_sresult"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.oliveapp.liveness.sample.liveness.SampleSaaSResultActivity">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
app:layout_marginTopPercent="9.7%"
app:layout_widthPercent="49.1%"
app:layout_aspectRatio="462%"/>
<ImageView
app:layout_widthPercent="87.8%"
app:layout_heightPercent="24.6%"
app:layout_marginTopPercent="20.4%"
app:layout_marginLeftPercent="6.1%"
android:layout_centerHorizontal="true"
android:background="@mipmap/oliveapp_liveness_result_border"/>
<!--两张人脸-->
<!--第一张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_close"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginLeftPercent="10.49%"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="13.5%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--第二张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_open"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginRightPercent="10.49%"
android:layout_alignParentRight="true"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="57.6%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--将下面列表使用listview表示-->
<ListView
android:id="@+id/oliveapp_liveness_saas_list"
android:layout_alignParentBottom="true"
app:layout_widthPercent="82.7%"
app:layout_heightPercent="25.4%"
app:layout_marginBottomPercent="25.3%"
app:layout_marginLeftPercent="8.6%"
android:isScrollContainer="false"
android:divider="@android:color/transparent"
android:listSelector="@android:color/transparent"/>
<Button
android:id="@+id/oliveapp_liveness_saas_result_finish"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/oliveapp_liveness_finish_button_selector"
app:layout_aspectRatio="618%"
app:layout_marginBottomPercent="8%"
app:layout_widthPercent="87.8%" />
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000">
<!--检测结果-->
<ImageView
android:id="@+id/oliveapp_liveness_result_image"
android:layout_centerHorizontal="true"
app:layout_marginRightPercent="25.5%"
app:layout_marginTopPercent="9.7%"
app:layout_widthPercent="50%"
app:layout_aspectRatio="462%"/>
<ImageView
app:layout_widthPercent="87.8%"
app:layout_heightPercent="24.6%"
app:layout_marginTopPercent="20.4%"
app:layout_marginLeftPercent="6.1%"
android:layout_centerHorizontal="true"
android:background="@mipmap/oliveapp_liveness_result_border"/>
<!--两张人脸-->
<!--第一张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_close"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginLeftPercent="10.49%"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="13.5%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--第二张-->
<ImageView
android:id="@+id/oliveapp_liveness_result_open"
app:layout_widthPercent="35.12%"
app:layout_heightPercent="19.68%"
app:layout_marginTopPercent="22.86%"
app:layout_marginRightPercent="10.49%"
android:layout_alignParentRight="true"/>
<ImageView
app:layout_widthPercent="28.9%"
app:layout_heightPercent="16.3%"
app:layout_marginTopPercent="24.6%"
app:layout_marginLeftPercent="57.6%"
android:src="@mipmap/oliveapp_liveness_result_face_border"/>
<!--将下面列表使用listview表示-->
<ListView
android:id="@+id/oliveapp_liveness_saas_list"
android:layout_alignParentBottom="true"
app:layout_widthPercent="82.7%"
app:layout_heightPercent="25.4%"
app:layout_marginBottomPercent="25.3%"
app:layout_marginLeftPercent="8.6%"
android:isScrollContainer="false"
android:divider="@android:color/transparent"
android:listSelector="@android:color/transparent"/>
<Button
android:id="@+id/oliveapp_liveness_saas_result_finish"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/oliveapp_liveness_finish_button_selector"
app:layout_marginBottomPercent="8%"
app:layout_widthPercent="87.8%"
app:layout_aspectRatio="618%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/oliveapp_start_button_layout">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000">
<!--关闭按钮-->
<ImageButton
android:id="@+id/oliveappCloseLivenessButton"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="@mipmap/oliveapp_close_icon"
app:layout_aspectRatio="100%"
app:layout_heightPercent="6%"
app:layout_marginRightPercent="6.3%"
app:layout_marginTopPercent="21%"/>
<Button
android:id="@+id/oliveappStartLivenessButton"
android:layout_alignParentRight="true"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_marginRightPercent="16%"
app:layout_marginTopPercent="60%"
app:layout_widthPercent="20%"
app:layout_aspectRatio="256%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/oliveapp_activity_vertical_margin"
android:paddingLeft="@dimen/oliveapp_activity_horizontal_margin"
android:paddingRight="@dimen/oliveapp_activity_horizontal_margin"
android:paddingTop="@dimen/oliveapp_activity_vertical_margin"
android:id="@+id/oliveapp_start_button_layout"
tools:context=".liveness.SampleStartActivity">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#80000000"
android:scaleType="centerCrop" />
<!--关闭按钮-->
<ImageButton
android:id="@+id/oliveappCloseLivenessButton"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="@mipmap/oliveapp_close_icon"
app:layout_marginRightPercent="6.6%"
app:layout_marginTopPercent="6.8%"
app:layout_widthPercent="7%"
app:layout_aspectRatio="100%"/>
<Button
android:id="@+id/oliveappStartLivenessButton"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
app:layout_marginBottomPercent="10%"
app:layout_widthPercent="73.5%"
app:layout_aspectRatio="513%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/oliveapp_start_button_layout"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#80000000"/>
<!--关闭按钮-->
<ImageButton
android:id="@+id/oliveappCloseLivenessButton"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="@mipmap/oliveapp_close_icon"
app:layout_heightPercent="4.1%"
app:layout_aspectRatio="100%"
app:layout_marginRightPercent="6.6%"
app:layout_marginTopPercent="6.8%"/>
<Button
android:id="@+id/oliveappStartLivenessButton"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_marginBottomPercent="8%"
app:layout_widthPercent="73%"
app:layout_aspectRatio="513%"/>
</android.support.percent.PercentRelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_item"
android:gravity="center_vertical"
android:minHeight="50dp"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="16dp" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp" >
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:singleLine="true"
android:text="title"
android:textColor="#4d4d4d"
android:textSize="18.0sp" />
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:layout_toLeftOf="@android:id/widget_frame"
android:maxLines="2"
android:text="summary"
android:textColor="#AAAAAA"
android:textSize="16sp" />
<FrameLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="4dp"
android:gravity="center_vertical" >
</FrameLayout>
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="@android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="20dp" />
<TextView
android:id="@+id/value"
android:paddingTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="value"
android:textSize="20sp"
android:textColor="#aaaaaa" />
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="basicConfigList" translatable="false">
<item>动作个数</item>
<item>活体超时时间</item>
<item>固定动作序列</item>
</string-array>
<string-array name="actionCountsList" translatable="false">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsCountsList" translatable="false">
<item>1</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsThreshold" translatable="false">
<item>low</item>
<item>high</item>
</string-array>
<string-array name="livenessDectionOvertimeList_key" translatable="false">
<item>5秒</item>
<item>10秒</item>
<item>15秒</item>
<item>20秒</item>
<item>永不超时</item>
</string-array>
<string-array name="livenessDectionOvertimeList_value" translatable="false">
<item>5000</item>
<item>10000</item>
<item>15000</item>
<item>20000</item>
<item>1000000</item>
</string-array>
<string-array name="choiceActionSequenceList" translatable="false">
<item>张嘴</item>
<item>抬头</item>
<item>闭眼</item>
</string-array>
<string-array name="choiceActionSequenceList_value" translatable="false">
<item>1</item>
<item>53</item>
<item>3</item>
</string-array>
<string-array name="darkDetectEntry" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
<string-array name="darkDetectValue" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
</resources>
<resources>
<string name="oliveapp_result_hint_text_pass">Congratuation!</string>
<string name="oliveapp_result_hint_text_fail">Please retry!</string>
<string name="oliveapp_ready_hint_start">Ayo mulai</string>
<string name="oliveapp_string_second">Kedua</string>
<string name="oliveapp_string_count_down">Hitung mundur</string>
<string name="oliveapp_face_hint_focus_here">Silakan hadapi layar ponsel</string>
<string name="oliveapp_face_database_image_hint_front">Silakan ambil foto bagian depan kartu ID untuk memastikan bahwa potret dan teks jelas</string>
<string name="oliveapp_face_database_image_hint_back">Silakan ambil bagian belakang kartu ID untuk memastikan teksnya jelas</string>
<string name="oliveapp_step_hint_focus">Silakan hadapi layar</string>
<string name="oliveapp_step_hint_mouthopen">Tolong buka mulutmu</string>
<string name="oliveapp_step_hint_eyeclose">Tolong berkedip</string>
<string name="oliveapp_step_hint_headup">Tolong angkat kepalamu</string>
</resources>
<resources>
<string name="oliveapp_detected_hint_none"></string>
<string name="oliveapp_detected_hint_face_not_found">Silakan hadapi layar</string>
<string name="oliveapp_detected_hint_face_too_small_face">Tolong dekat</string>
<string name="oliveapp_detected_hint_face_too_large_face">Harap menjauh</string>
<string name="oliveapp_detected_hint_light_too_bright">Cahayanya terlalu terang</string>
<string name="oliveapp_detected_hint_light_too_dark">Cahayanya terlalu gelap</string>
<string name="oliveapp_detected_hint_face_side_face">Tolong jangan hadapi</string>
<string name="oliveapp_detected_hint_face_up_face">Tolong sujud sedikit</string>
<string name="oliveapp_detected_hint_down_face">Tolong cari sedikit</string>
</resources>
<resources>
<string name="oliveapp_app_name">Sampel uji hidup</string>
<string name="titleText">Etu Technology</string>
<string name="oliveapp_version">1.10.e</string>
<string name="subtitleText">Kode Contoh Uji Langsung</string>
<string name="hintCamera">Memotret pendaftaran</string>
<string name="hintFrontCamera">Foto kelas (potret diri)</string>
<string name="hintIdcardCapture">Pengambilan otomatis kartu ID (depan)</string>
<string name="hintIdcardBackCapture">Pengambilan otomatis kartu ID (sebaliknya)</string>
<string name="hintIDcard">Salin foto</string>
<string name="livenessButtonText">Deteksi langsung</string>
<string name="settingButtonText">Tes khusus</string>
<string name="title_activity_example_start">Antarmuka startup</string>
<string name="title_activity_example_result">Antarmuka tampilan hasil</string>
<string name="title_activity_example_liveness">Antarmuka deteksi hidup</string>
<string name="oliveapp_liveness_detection_pass_hint">Selamat ya\nTes hidup yang sukses</string>
<string name="oliveapp_liveness_detection_fail_hint">Kegagalan deteksi\nHarap kembali untuk mencoba lagi</string>
<string name="oliveapp_liveness_detection_cancel_hint">Deteksi dibatalkan\nSilakan kembali untuk mencoba lagi</string>
</resources>
<resources>
<string name="title_activity_sample_idcard">SampleIdcardActivity</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="basicConfigList" translatable="false">
<item>动作个数</item>
<item>活体超时时间</item>
<item>固定动作序列</item>
</string-array>
<string-array name="actionCountsList" translatable="false">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsCountsList" translatable="false">
<item>1</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsThreshold" translatable="false">
<item>low</item>
<item>high</item>
</string-array>
<string-array name="livenessDectionOvertimeList_key" translatable="false">
<item>5秒</item>
<item>10秒</item>
<item>15秒</item>
<item>20秒</item>
<item>永不超时</item>
</string-array>
<string-array name="livenessDectionOvertimeList_value" translatable="false">
<item>5000</item>
<item>10000</item>
<item>15000</item>
<item>20000</item>
<item>1000000</item>
</string-array>
<string-array name="choiceActionSequenceList" translatable="false">
<item>张嘴</item>
<item>抬头</item>
<item>闭眼</item>
</string-array>
<string-array name="choiceActionSequenceList_value" translatable="false">
<item>1</item>
<item>53</item>
<item>3</item>
</string-array>
<string-array name="darkDetectEntry" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
<string-array name="darkDetectValue" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
</resources>
<resources>
<string name="oliveapp_result_hint_text_pass">Congratuation!</string>
<string name="oliveapp_result_hint_text_fail">Please retry!</string>
<string name="oliveapp_ready_hint_start">Ayo mulai</string>
<string name="oliveapp_string_second">Kedua</string>
<string name="oliveapp_string_count_down">Hitung mundur</string>
<string name="oliveapp_face_hint_focus_here">Silakan hadapi layar ponsel</string>
<string name="oliveapp_face_database_image_hint_front">Silakan ambil foto bagian depan kartu ID untuk memastikan bahwa potret dan teks jelas</string>
<string name="oliveapp_face_database_image_hint_back">Silakan ambil bagian belakang kartu ID untuk memastikan teksnya jelas</string>
<string name="oliveapp_step_hint_focus">Silakan hadapi layar</string>
<string name="oliveapp_step_hint_mouthopen">Tolong buka mulutmu</string>
<string name="oliveapp_step_hint_eyeclose">Tolong berkedip</string>
<string name="oliveapp_step_hint_headup">Tolong angkat kepalamu</string>
</resources>
<resources>
<string name="oliveapp_detected_hint_none"></string>
<string name="oliveapp_detected_hint_face_not_found">Silakan hadapi layar</string>
<string name="oliveapp_detected_hint_face_too_small_face">Tolong dekat</string>
<string name="oliveapp_detected_hint_face_too_large_face">Harap menjauh</string>
<string name="oliveapp_detected_hint_light_too_bright">Cahayanya terlalu terang</string>
<string name="oliveapp_detected_hint_light_too_dark">Cahayanya terlalu gelap</string>
<string name="oliveapp_detected_hint_face_side_face">Tolong jangan hadapi</string>
<string name="oliveapp_detected_hint_face_up_face">Tolong sujud sedikit</string>
<string name="oliveapp_detected_hint_down_face">Tolong cari sedikit</string>
</resources>
<resources>
<string name="oliveapp_app_name">Sampel uji hidup</string>
<string name="titleText">Etu Technology</string>
<string name="oliveapp_version">1.10.e</string>
<string name="subtitleText">Kode Contoh Uji Langsung</string>
<string name="hintCamera">Memotret pendaftaran</string>
<string name="hintFrontCamera">Foto kelas (potret diri)</string>
<string name="hintIdcardCapture">Pengambilan otomatis kartu ID (depan)</string>
<string name="hintIdcardBackCapture">Pengambilan otomatis kartu ID (sebaliknya)</string>
<string name="hintIDcard">Salin foto</string>
<string name="livenessButtonText">Deteksi langsung</string>
<string name="settingButtonText">Tes khusus</string>
<string name="title_activity_example_start">Antarmuka startup</string>
<string name="title_activity_example_result">Antarmuka tampilan hasil</string>
<string name="title_activity_example_liveness">Antarmuka deteksi hidup</string>
<string name="oliveapp_liveness_detection_pass_hint">Selamat ya\nTes hidup yang sukses</string>
<string name="oliveapp_liveness_detection_fail_hint">Kegagalan deteksi\nHarap kembali untuk mencoba lagi</string>
<string name="oliveapp_liveness_detection_cancel_hint">Deteksi dibatalkan\nSilakan kembali untuk mencoba lagi</string>
</resources>
<resources>
<string name="title_activity_sample_idcard">SampleIdcardActivity</string>
</resources>
......@@ -2,5 +2,4 @@
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="basicConfigList" translatable="false">
<item>动作个数</item>
<item>活体超时时间</item>
<item>固定动作序列</item>
</string-array>
<string-array name="actionCountsList" translatable="false">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsCountsList" translatable="false">
<item>1</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsThreshold" translatable="false">
<item>low</item>
<item>high</item>
</string-array>
<string-array name="livenessDectionOvertimeList_key" translatable="false">
<item>5秒</item>
<item>10秒</item>
<item>15秒</item>
<item>20秒</item>
<item>永不超时</item>
</string-array>
<string-array name="livenessDectionOvertimeList_value" translatable="false">
<item>5000</item>
<item>10000</item>
<item>15000</item>
<item>20000</item>
<item>1000000</item>
</string-array>
<string-array name="choiceActionSequenceList" translatable="false">
<item>张嘴</item>
<item>抬头</item>
<item>闭眼</item>
</string-array>
<string-array name="choiceActionSequenceList_value" translatable="false">
<item>1</item>
<item>53</item>
<item>3</item>
</string-array>
<string-array name="darkDetectEntry" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
<string-array name="darkDetectValue" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
</resources>
<resources>
<string name="oliveapp_result_hint_text_pass">Congratuation!</string>
<string name="oliveapp_result_hint_text_fail">Please retry!</string>
<string name="oliveapp_ready_hint_start">Ayo mulai</string>
<string name="oliveapp_string_second">Kedua</string>
<string name="oliveapp_string_count_down">Hitung mundur</string>
<string name="oliveapp_face_hint_focus_here">Silakan hadapi layar ponsel</string>
<string name="oliveapp_face_database_image_hint_front">Silakan ambil foto bagian depan kartu ID untuk memastikan bahwa potret dan teks jelas</string>
<string name="oliveapp_face_database_image_hint_back">Silakan ambil bagian belakang kartu ID untuk memastikan teksnya jelas</string>
<string name="oliveapp_step_hint_focus">Silakan hadapi layar</string>
<string name="oliveapp_step_hint_mouthopen">Tolong buka mulutmu</string>
<string name="oliveapp_step_hint_eyeclose">Tolong berkedip</string>
<string name="oliveapp_step_hint_headup">Tolong angkat kepalamu</string>
</resources>
<resources>
<string name="oliveapp_detected_hint_none"></string>
<string name="oliveapp_detected_hint_face_not_found">Silakan hadapi layar</string>
<string name="oliveapp_detected_hint_face_too_small_face">Tolong dekat</string>
<string name="oliveapp_detected_hint_face_too_large_face">Harap menjauh</string>
<string name="oliveapp_detected_hint_light_too_bright">Cahayanya terlalu terang</string>
<string name="oliveapp_detected_hint_light_too_dark">Cahayanya terlalu gelap</string>
<string name="oliveapp_detected_hint_face_side_face">Tolong jangan hadapi</string>
<string name="oliveapp_detected_hint_face_up_face">Tolong sujud sedikit</string>
<string name="oliveapp_detected_hint_down_face">Tolong cari sedikit</string>
</resources>
<resources>
<string name="oliveapp_app_name">Sampel uji hidup</string>
<string name="titleText">Etu Technology</string>
<string name="oliveapp_version">1.10.e</string>
<string name="subtitleText">Kode Contoh Uji Langsung</string>
<string name="hintCamera">Memotret pendaftaran</string>
<string name="hintFrontCamera">Foto kelas (potret diri)</string>
<string name="hintIdcardCapture">Pengambilan otomatis kartu ID (depan)</string>
<string name="hintIdcardBackCapture">Pengambilan otomatis kartu ID (sebaliknya)</string>
<string name="hintIDcard">Salin foto</string>
<string name="livenessButtonText">Deteksi langsung</string>
<string name="settingButtonText">Tes khusus</string>
<string name="title_activity_example_start">Antarmuka startup</string>
<string name="title_activity_example_result">Antarmuka tampilan hasil</string>
<string name="title_activity_example_liveness">Antarmuka deteksi hidup</string>
<string name="oliveapp_liveness_detection_pass_hint">Selamat ya\nTes hidup yang sukses</string>
<string name="oliveapp_liveness_detection_fail_hint">Kegagalan deteksi\nHarap kembali untuk mencoba lagi</string>
<string name="oliveapp_liveness_detection_cancel_hint">Deteksi dibatalkan\nSilakan kembali untuk mencoba lagi</string>
</resources>
<resources>
<string name="title_activity_sample_idcard">SampleIdcardActivity</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="basicConfigList" translatable="false">
<item>动作个数</item>
<item>活体超时时间</item>
<item>固定动作序列</item>
</string-array>
<string-array name="actionCountsList" translatable="false">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsCountsList" translatable="false">
<item>1</item>
<item>3</item>
</string-array>
<string-array name="fanpaiClsThreshold" translatable="false">
<item>low</item>
<item>high</item>
</string-array>
<string-array name="livenessDectionOvertimeList_key" translatable="false">
<item>5秒</item>
<item>10秒</item>
<item>15秒</item>
<item>20秒</item>
<item>永不超时</item>
</string-array>
<string-array name="livenessDectionOvertimeList_value" translatable="false">
<item>5000</item>
<item>10000</item>
<item>15000</item>
<item>20000</item>
<item>1000000</item>
</string-array>
<string-array name="choiceActionSequenceList" translatable="false">
<item>张嘴</item>
<item>抬头</item>
<item>闭眼</item>
</string-array>
<string-array name="choiceActionSequenceList_value" translatable="false">
<item>1</item>
<item>53</item>
<item>3</item>
</string-array>
<string-array name="darkDetectEntry" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
<string-array name="darkDetectValue" translatable="false">
<item></item>
<item></item>
<item></item>
<item></item>
</string-array>
</resources>
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="colorWhite">#FFFFFF</color>
<color name="navy">#FFFFFF</color>
<color name="colorDefaultBackground">#1A223E</color>
<color name="colorTabButtonSelectText">#FFFFFF</color>
<color name="colorTabButtonText">#000000</color>
<color name="itemBgColor">#fefefe</color>
<color name="itemSelectColor">#f0f0f0</color>
<color name="listLineColor">#e6e6e6</color>
<color name="itemdisabled">#f3f3f4</color>
</resources>
<resources>
<string name="oliveapp_result_hint_text_pass">Congratuation!</string>
<string name="oliveapp_result_hint_text_fail">Please retry!</string>
<string name="oliveapp_ready_hint_start">Ayo mulai</string>
<string name="oliveapp_string_second">Kedua</string>
<string name="oliveapp_string_count_down">Hitung mundur</string>
<string name="oliveapp_face_hint_focus_here">Silakan hadapi layar ponsel</string>
<string name="oliveapp_face_database_image_hint_front">Silakan ambil foto bagian depan kartu ID untuk memastikan bahwa potret dan teks jelas</string>
<string name="oliveapp_face_database_image_hint_back">Silakan ambil bagian belakang kartu ID untuk memastikan teksnya jelas</string>
......@@ -15,5 +7,4 @@
<string name="oliveapp_step_hint_mouthopen">Tolong buka mulutmu</string>
<string name="oliveapp_step_hint_eyeclose">Tolong berkedip</string>
<string name="oliveapp_step_hint_headup">Tolong angkat kepalamu</string>
</resources>
<resources>
<string name="oliveapp_detected_hint_none"></string>
<string name="oliveapp_detected_hint_face_not_found">Silakan hadapi layar</string>
<string name="oliveapp_detected_hint_face_too_small_face">Tolong dekat</string>
<string name="oliveapp_detected_hint_face_too_large_face">Harap menjauh</string>
<string name="oliveapp_detected_hint_light_too_bright">Cahayanya terlalu terang</string>
<string name="oliveapp_detected_hint_light_too_dark">Cahayanya terlalu gelap</string>
<string name="oliveapp_detected_hint_face_side_face">Tolong jangan hadapi</string>
<string name="oliveapp_detected_hint_face_up_face">Tolong sujud sedikit</string>
<string name="oliveapp_detected_hint_down_face">Tolong cari sedikit</string>
</resources>
<resources></resources>
<resources>
<string name="oliveapp_app_name">Sampel uji hidup</string>
<string name="titleText">Etu Technology</string>
<string name="oliveapp_version">1.10.e</string>
<string name="subtitleText">Kode Contoh Uji Langsung</string>
<string name="hintCamera">Memotret pendaftaran</string>
<string name="hintFrontCamera">Foto kelas (potret diri)</string>
<string name="hintIdcardCapture">Pengambilan otomatis kartu ID (depan)</string>
<string name="hintIdcardBackCapture">Pengambilan otomatis kartu ID (sebaliknya)</string>
<string name="hintIDcard">Salin foto</string>
<string name="livenessButtonText">Deteksi langsung</string>
<string name="settingButtonText">Tes khusus</string>
<string name="title_activity_example_start">Antarmuka startup</string>
<string name="title_activity_example_result">Antarmuka tampilan hasil</string>
<string name="title_activity_example_liveness">Antarmuka deteksi hidup</string>
<string name="oliveapp_liveness_detection_pass_hint">Selamat ya\nTes hidup yang sukses</string>
<string name="oliveapp_liveness_detection_fail_hint">Kegagalan deteksi\nHarap kembali untuk mencoba lagi</string>
<string name="oliveapp_liveness_detection_cancel_hint">Deteksi dibatalkan\nSilakan kembali untuk mencoba lagi</string>
<string name="oliveapp_app_name">活体检测sample</string>
</resources>
<resources>
<string name="title_activity_sample_idcard">SampleIdcardActivity</string>
</resources>
<resources></resources>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="pref_liveness_dection">
<PreferenceCategory android:title="模式">
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_debug_mode"
android:layout="@layout/prefs_list_s_item"
android:title="debug模式" />
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_with_prestart"
android:layout="@layout/prefs_list_s_item"
android:title="是否预检" />
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_pad_landscape"
android:layout="@layout/prefs_list_s_item"
android:title="Pad是否横屏" />
</PreferenceCategory>
<PreferenceCategory android:title="SaaS配置">
<EditTextPreference
android:key = "pref_saas_url"
android:title="SaaS地址"
android:defaultValue = "http://staging.yitutech.com"
android:layout="@layout/prefs_list_s_item"
/>
<EditTextPreference
android:key = "pref_test_id"
android:title="TestId"
android:defaultValue = "testid"
android:layout="@layout/prefs_list_s_item"
/>
</PreferenceCategory>
<PreferenceCategory android:title="基础配置">
<ListPreference
android:defaultValue="3"
android:entries="@array/actionCountsList"
android:entryValues="@array/actionCountsList"
android:key="pref_action_counts_list"
android:layout="@layout/prefs_list_s_item"
android:title="动作个数"
android:widgetLayout="@layout/arrow_widget" />
<ListPreference
android:defaultValue="10000"
android:entries="@array/livenessDectionOvertimeList_key"
android:entryValues="@array/livenessDectionOvertimeList_value"
android:key="pref_liveness_detection_overtime_list"
android:layout="@layout/prefs_list_s_item"
android:title="活体超时时间"
android:widgetLayout="@layout/arrow_widget" />
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_fix_action"
android:layout="@layout/prefs_list_s_item"
android:title="固定动作序列" />
</PreferenceCategory>
<PreferenceCategory
android:key="pref_action_sequence_category"
android:title="动作序列">
<ListPreference
android:defaultValue="3"
android:entries="@array/choiceActionSequenceList"
android:entryValues="@array/choiceActionSequenceList_value"
android:key="pref_action_one_list"
android:layout="@layout/prefs_list_s_item"
android:title="动作一"
android:widgetLayout="@layout/arrow_widget" />
<ListPreference
android:defaultValue="3"
android:entries="@array/choiceActionSequenceList"
android:entryValues="@array/choiceActionSequenceList_value"
android:key="pref_action_two_list"
android:layout="@layout/prefs_list_s_item"
android:title="动作二"
android:widgetLayout="@layout/arrow_widget" />
<ListPreference
android:defaultValue="3"
android:entries="@array/choiceActionSequenceList"
android:entryValues="@array/choiceActionSequenceList_value"
android:key="pref_action_three_list"
android:layout="@layout/prefs_list_s_item"
android:title="动作三"
android:widgetLayout="@layout/arrow_widget" />
</PreferenceCategory>
<PreferenceCategory android:title="防屏幕相关">
<ListPreference
android:defaultValue="1"
android:entries="@array/fanpaiClsCountsList"
android:entryValues="@array/fanpaiClsCountsList"
android:key="pref_fanpaicls_counts_list"
android:layout="@layout/prefs_list_s_item"
android:title="翻拍照数量"
android:widgetLayout="@layout/arrow_widget" />
<ListPreference
android:defaultValue="low"
android:entries="@array/fanpaiClsThreshold"
android:entryValues="@array/fanpaiClsThreshold"
android:key="pref_fanpaicls_threshold_list"
android:layout="@layout/prefs_list_s_item"
android:title="防屏幕翻拍阈值"
android:widgetLayout="@layout/arrow_widget" />
</PreferenceCategory>
<PreferenceCategory android:title="存储相关">
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_save_rgb"
android:layout="@layout/prefs_list_s_item"
android:title="存rgb图" />
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_save_origin_image"
android:layout="@layout/prefs_list_s_item"
android:title="存原图" />
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_save_package"
android:layout="@layout/prefs_list_s_item"
android:title="存大礼包" />
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_fanpaicls_image"
android:layout="@layout/prefs_list_s_item"
android:title="存翻拍照" />
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_jpeg_image"
android:layout="@layout/prefs_list_s_item"
android:title="存JPEG" />
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_new_package"
android:layout="@layout/prefs_list_s_item"
android:title="是否开启信息收集" />
</PreferenceCategory>
<PreferenceCategory android:title="昏暗检测相关">
<ListPreference
android:key="pref_dark_detect_list"
android:entries="@array/darkDetectEntry"
android:entryValues="@array/darkDetectValue"
android:layout="@layout/prefs_list_s_item"
android:widgetLayout="@layout/arrow_widget"
android:title="昏暗检测阈值"/>
</PreferenceCategory>
</PreferenceScreen>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment