软件编程
位置:首页>> 软件编程>> Android编程>> Android实现人脸支付的示例代码

Android实现人脸支付的示例代码

作者:FranzLiszt1847  发布时间:2023-07-30 14:23:52 

标签:Android,人脸支付

效果展示

人脸支付效果视频

Android实现人脸支付的示例代码

密码框输入支付效果视频

因为密码支付时会调起系统安全键盘,开启自动保护功能,防止泄露,会导致输入密码时录屏黑屏,故使用另一台手机拍摄。

Android实现人脸支付的示例代码

功能实现

人脸支付

API初始化

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);

人脸特征提取

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);
                       }
                   }

返回支付结果

根据匹配人脸注册时所获取的trackid,判断识别结果

Integer recognizeStatus = requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId());

根据返回码修改识别框颜色,并修改跳转状态的值

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;
               }
           }

利用异步通信进行延迟跳转

Handler handler = new Handler(  ){
       @Override
       public void handleMessage(@NonNull Message msg) {
           super.handleMessage( msg );
           if (msg.what == 1){
               CountDown();
               handler.sendEmptyMessageDelayed( 1,1000 );
           }
       }
   };

密码框输入支付

自定义密码输入框控件

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);
   }

}

初始化控件

分别对应密码框背景、密码位数、分割线宽度、分割线颜色、字体颜色、字体大小

mPayPwdEditText.initStyle( R.drawable.bg_paypassword_style,6,0.8f,R.color.colorWhite,R.color.colorWhite,35);

布局内用法

<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"/>

密码匹配

对控件进行输入事件监听,采用测试密码用例:123456,与回调接口所携带的数据进行匹配。

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();
               }
           }
       } );

其内部是对EditText控件进行输入事件监听。然后通过比对输入字符串长度与密码长度,然后返回其输入的字符串

@Override
           public void afterTextChanged(Editable s) {
               initDatas(s);
               if(s.length() == pwdlength)
               {
                   if(onTextFinishListener != null)
                   {
                       onTextFinishListener.onFinish(s.toString().trim());
                   }
               }
           }

尾言

此人脸识别API采用虹软ArcSoft

来源:https://blog.csdn.net/News53231323/article/details/122991431

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com