Face payment and password box input payment
Show results
Face payment effect video
Password box input payment effect video
Because the system security keyboard will be activated when the password is paid, and the automatic protection function will be turned on to prevent leakage, which will lead to a black screen recording when entering the password, so use another mobile phone to shoot.
Function realization
face payment
API initialization
ftEngine = new FaceEngine();
ftInitCode = ftEngine.init(this, DetectMode.ASF_DETECT_MODE_VIDEO, ConfigUtil.getFtOrient(this),
16, MAX_DETECT_NUM, FaceEngine.ASF_FACE_DETECT);
frEngine = new FaceEngine();
frInitCode = frEngine.init(this, DetectMode.ASF_DETECT_MODE_IMAGE, DetectFaceOrientPriority.ASF_OP_0_ONLY,
16, MAX_DETECT_NUM, FaceEngine.ASF_FACE_RECOGNITION);
flEngine = new FaceEngine();
flInitCode = flEngine.init(this, DetectMode.ASF_DETECT_MODE_IMAGE, DetectFaceOrientPriority.ASF_OP_0_ONLY,
16, MAX_DETECT_NUM, FaceEngine.ASF_LIVENESS);
facial feature extraction
private void searchFace(final FaceFeature frFace, final Integer requestId) {
Observable.create(new ObservableOnSubscribe<CompareResult>() {
@Override
public void subscribe(ObservableEmitter<CompareResult> emitter) {
CompareResult compareResult = FaceServer.getInstance().getTopOfFaceLib(frFace);
emitter.onNext(compareResult);
}
})
.subscribeOn( Schedulers.computation())
.observeOn( AndroidSchedulers.mainThread())
.subscribe(new Observer<CompareResult>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(CompareResult compareResult) {
if (compareResult == null || compareResult.getUserName() == null) {
requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);
faceHelper.setName(requestId, "VISITOR " + requestId);
return;
}
if (compareResult.getSimilar() > SIMILAR_THRESHOLD) {
boolean isAdded = false;
if (compareResultList == null) {
requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);
faceHelper.setName(requestId, "VISITOR " + requestId);
return;
}
for (CompareResult compareResult1 : compareResultList) {
if (compareResult1.getTrackId() == requestId) {
isAdded = true;
break;
}
}
if (!isAdded) {
//对于多人脸搜索,假如最大显示数量为 MAX_DETECT_NUM 且有新的人脸进入,则以队列的形式移除
if (compareResultList.size() >= MAX_DETECT_NUM) {
compareResultList.remove(0);
adapter.notifyItemRemoved(0);
}
//添加显示人员时,保存其trackId
compareResult.setTrackId(requestId);
compareResultList.add(compareResult);
adapter.notifyItemInserted(compareResultList.size() - 1);
}
requestFeatureStatusMap.put(requestId, RequestFeatureStatus.SUCCEED);
faceHelper.setName(requestId, getString(R.string.recognize_success_notice, compareResult.getUserName()));
} else {
faceHelper.setName(requestId, getString(R.string.recognize_failed_notice, "NOT_REGISTERED"));
retryRecognizeDelayed(requestId);
}
}
Return payment result
Determine the recognition result according to the trackid obtained when the face is registered
Integer recognizeStatus = requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId());
Modify the color of the recognition box according to the return code, and modify the value of the jump state
if (recognizeStatus != null) {
handler.sendEmptyMessageDelayed( 1,1000 );
if (recognizeStatus == RequestFeatureStatus.FAILED) {
color = RecognizeColor.COLOR_FAILED;
returnFlag = false;
}
if (recognizeStatus == RequestFeatureStatus.SUCCEED) {
color = RecognizeColor.COLOR_SUCCESS;
returnFlag = true;
}
}
Delayed Jump with Asynchronous Communication
Handler handler = new Handler( ){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage( msg );
if (msg.what == 1){
CountDown();
handler.sendEmptyMessageDelayed( 1,1000 );
}
}
};
Password box input payment
Custom password input box control
public class PayPwdEditText extends RelativeLayout {
private EditText editText; //文本编辑框
private Context context;
private LinearLayout linearLayout; //文本密码的文本
private TextView[] textViews; //文本数组
private int pwdlength = 6; //密码长度, 默认6
private OnTextFinishListener onTextFinishListener;
public PayPwdEditText(Context context) {
this(context, null);
}
public PayPwdEditText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PayPwdEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
}
/**
* @param bgdrawable 背景drawable
* @param pwdlength 密码长度
* @param splilinewidth 分割线宽度
* @param splilinecolor 分割线颜色
* @param pwdcolor 密码字体颜色
* @param pwdsize 密码字体大小
*/
public void initStyle(int bgdrawable, int pwdlength, float splilinewidth, int splilinecolor, int pwdcolor, int pwdsize)
{
this.pwdlength = pwdlength;
initEdit(bgdrawable);
initShowInput(bgdrawable, pwdlength, splilinewidth, splilinecolor, pwdcolor, pwdsize);
}
/**
* 初始化编辑框
* @param bgcolor
*/
private void initEdit(int bgcolor)
{
editText = new EditText(context);
editText.setBackgroundResource(bgcolor);
editText.setCursorVisible(false);
editText.setTextSize(0);
//设置为密文输入模式和数字
editText.setInputType( InputType.TYPE_NUMBER_VARIATION_PASSWORD | InputType.TYPE_CLASS_NUMBER);
//设置输入长度为6
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(pwdlength)});
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Editable etext = editText.getText();
Selection.setSelection(etext, etext.length());
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
initDatas(s);
if(s.length() == pwdlength)
{
if(onTextFinishListener != null)
{
onTextFinishListener.onFinish(s.toString().trim());
}
}
}
});
LayoutParams lp = new LayoutParams( LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
lp.addRule( RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
addView(editText, lp);
}
/**
* @param bgcolor 背景drawable
* @param pwdlength 密码长度
* @param slpilinewidth 分割线宽度
* @param splilinecolor 分割线颜色
* @param pwdcolor 密码字体颜色
* @param pwdsize 密码字体大小
*/
public void initShowInput(int bgcolor, int pwdlength, float slpilinewidth, int splilinecolor, int pwdcolor, int pwdsize)
{
//添加密码框父布局
linearLayout = new LinearLayout(context);
linearLayout.setBackgroundResource(bgcolor);
LayoutParams layoutParams = new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
linearLayout.setLayoutParams(layoutParams);
linearLayout.setOrientation( LinearLayout.HORIZONTAL);
addView(linearLayout);
//添加密码框
textViews = new TextView[pwdlength];
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT);
params.weight = 1;
params.gravity = Gravity.CENTER;
LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(dip2px(context, slpilinewidth), LayoutParams.MATCH_PARENT);
for(int i = 0; i < textViews.length; i++)
{
final int index = i;
TextView textView = new TextView(context);
textView.setGravity( Gravity.CENTER);
textViews[i] = textView;
textViews[i].setTextSize(pwdsize);
textViews[i].setTextColor(context.getResources().getColor(pwdcolor));
textViews[i].setInputType( InputType.TYPE_NUMBER_VARIATION_PASSWORD | InputType.TYPE_CLASS_NUMBER);
linearLayout.addView(textView, params);
if(i < textViews.length - 1)
{
View view = new View(context);
view.setBackgroundColor(context.getResources().getColor(splilinecolor));
linearLayout.addView(view, params2);
}
}
}
/**
* 是否显示明文
* @param showPwd
*/
public void setShowPwd(boolean showPwd) {
int length = textViews.length;
for(int i = 0; i < length; i++) {
if (showPwd) {
textViews[i].setTransformationMethod( PasswordTransformationMethod.getInstance());
} else {
textViews[i].setTransformationMethod( HideReturnsTransformationMethod.getInstance());
}
}
}
/**
* 设置显示类型
* @param type
*/
public void setInputType(int type)
{
int length = textViews.length;
for(int i = 0; i < length; i++) {
textViews[i].setInputType(type);
}
}
/**
* 清除文本框
*/
public void clearText()
{
editText.setText("");
for(int i = 0; i < pwdlength; i++)
{
textViews[i].setText("");
}
}
public void setOnTextFinishListener(OnTextFinishListener onTextFinishListener) {
this.onTextFinishListener = onTextFinishListener;
}
/**
* 根据输入字符,显示密码个数
* @param s
*/
public void initDatas(Editable s)
{
if(s.length() > 0)
{
int length = s.length();
for(int i = 0; i < pwdlength; i++)
{
if(i < length)
{
for(int j = 0; j < length; j++)
{
char ch = s.charAt(j);
textViews[j].setText( String.valueOf(ch));
}
}
else
{
textViews[i].setText("");
}
}
}
else
{
for(int i = 0; i < pwdlength; i++)
{
textViews[i].setText("");
}
}
}
public String getPwdText()
{
if(editText != null)
return editText.getText().toString().trim();
return "";
}
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public interface OnTextFinishListener
{
void onFinish(String str);
}
public void setFocus()
{
editText.requestFocus();
editText.setFocusable(true);
showKeyBord(editText);
}
/**
* 显示键盘
* @param view
*/
public void showKeyBord(View view)
{
InputMethodManager imm = (InputMethodManager) context.getSystemService( Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
}
}
Initialize the control
Corresponding to password box background, password digits, dividing line width, dividing line color, font color, font size
mPayPwdEditText.initStyle( R.drawable.bg_paypassword_style,6,0.8f,R.color.colorWhite,R.color.colorWhite,35);
In-layout usage
<com.example.PayPackage.PayPwdEditText
android:id="@+id/payPassWordEditText"
android:layout_width="match_parent"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_height="35dp"/>
password match
Monitor the input event of the control, use the test password case: 123456, and match the data carried by the callback interface.
mPayPwdEditText.setOnTextFinishListener( new PayPwdEditText.OnTextFinishListener() {
@Override
public void onFinish(String str) {
if (str.equals( "123456" ))
{
startActivity( new Intent( OrderInterface.this,PaySuccess.class ) );
}else {
if (PassWordError == null) {
PassWordError = new Toast( OrderInterface.this );
View view = LayoutInflater.from( OrderInterface.this ).inflate( R.layout.passworderror,null,false );
ErrorTips = view.findViewById( R.id.ErrorTips );
PassWordError.setView( view );
//PassWordError.setGravity( Gravity.CENTER,0, ResHelper.dipToPx(OrderInterface.this, -100) );
}
PassWordError.show();
mPayPwdEditText.clearText();
}
}
} );
Its internal is to monitor the input event of the EditText control. Then compare the length of the input string with the length of the password, and then return the input string
@Override
public void afterTextChanged(Editable s) {
initDatas(s);
if(s.length() == pwdlength)
{
if(onTextFinishListener != null)
{
onTextFinishListener.onFinish(s.toString().trim());
}
}
}
end words
This face recognition API uses ArcSoft