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

到此这篇关于Android实现人脸支付的文章就介绍到这了,更多相关Android 人脸支付内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android实现微信支付功能

    开发Android APP微信支付功能,需要完成三个步骤:第一步生成预支付订单.第二步生成微信支付参数.第三步调起微信APP支付.除了需要审核通过的APP应用外,还需要获得微信支付接口权限,然后获取对应的商户号.API密钥,这两者缺一不可,并且在APP微信支付中使用 获得商户号.API密钥 在微信开放平台中查看审核通过的APP应用,是否申请支付功能,若已申请,登录微信支付|商户平台:http://pay.weixin.qq.com 查看对应的商户号.API密钥 >申请微信支付接口 >登录商户平

  • Android支付宝和微信支付集成

    场景 随着移动支付的兴起,在我们的app'中,会经常有集成支付的需求.这时候一般都会采用微信和支付宝的sdk 来集成 (一)支付宝支付 在使用支付宝支付的过程中,我们是在服务器端生成订单,客户端访问接口,并得到订单信息,调用接口支付,支付成功后支付宝会分别 异步调用服务器端,并向客户端返回支付结果. 开发步骤: ①注册支付宝账号--进行实名认证--提交审核资料--审核通过 支付宝无线快捷支付接口: b.alipay.com/order/productDetail.htm?productId=20

  • Android接入支付宝实现支付功能实例

    我本来是想直接讲Android支付这一块的,包括支付宝,微信,其他第三方整合支付等,但是微信开放平台他对我的账号做了限制,所有我今天就先把重心放在支付宝的支付上,也算是写得尽可能详细些吧,毕竟是第三方的SDK,只要我们耐心的阅读文档和开发引导,这个其实不是很难的,我也是没有用过支付宝的支付,但是我相信,你看完这篇博客,也会对他了如指掌的,好的,我们正文开始 一.准备步骤 1.登录官网 他的官网就是蚂蚁金服的开放平台了,我们可以访问 蚂蚁金服开放平台 ,并且注册账号进行登录 创建应用 如果你是现有

  • Android app第三方支付宝支付接入教程

    支付宝的接入相对比较简单,看看支付宝官网的文档基本都能搞定,但是切记一点让你们的后台也要搞清楚支付宝的流程,重中之重. 1.注意事项 开发前一定要阅读支付宝官方文档 强烈建议签名等处理在后台处理,我这个是测试是在自己本地写的,不要吐槽 想获取支付宝合作商户ID,及支付宝公钥请点击支付宝链接,生成密钥及PKCS8转码工具在文档中 添加Android.permission.INTERNET权限和android.permission.ACCESS_NETWORK_STATE权限 要导入支付宝的包 2.

  • 微信支付仅能成功调用一次问题的解决方法(Android)

    本人使用Android开发有一段时间了,但是本身没有系统学,而且多年专注服务端开发,总觉得因为项目需要接触Android移动端开发只是暂时的,所以没有太上心,结果碰到一个大难题折腾了一天,最后被有经验的小伙伴提示了一下才迎刃而解,感觉无地自容的同时,又非常窃喜,毕竟跨过一个一个的坎,就成长了,在这里丢人等换个地方就成牛了也未可知,哈哈.闲言就絮叨到这里,赶紧分享: 微信支付调用接口整体的流程有必要简述一下(目前网上的资料大部分都是适配微信支付旧版的代码,最新的微信支付官方文档中并没有服务端的De

  • Android仿支付宝支付从底部弹窗效果

    我们再用支付宝支付的时候,会从底部弹上来一个对话框,让我们选择支付方式等等,今天我们就来慢慢实现这个功能 效果图 实现 主界面很简单,就是一个按钮,点击后跳到支付详情的Fragment中 package com.example.hfs.alipayuidemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.wi

  • Android仿支付宝的头部伸缩动画效果

    Android5.0推出的MaterialDesign库包含了处理头部工具栏的多个控件,不但允许自定义顶部导航栏,而且导航栏高度是可以伸缩的.如此一来,一方面导航栏能够放得下更多控件,另一方面在用户想看具体内容时也能腾出更多的屏幕空间. 这么说可能比较抽象,那就先来看看两张导航栏的效果图,第一张是导航栏完全展开时的界面,此时页面头部的导航栏占据了较大部分的高度: 第二张是导航栏完全收缩时的界面,此时头部导航栏只剩矮矮的一个长条. 看起来很眼熟是不是,上面的截图正是仿支付宝首页的头部效果.如果你熟

  • Android微信支付获取二次签名Sign的方法

    本文实例为大家分享了Android微信支付获取二次签名Sign的方法,供大家参考,具体内容如下 /** * 获取sign签名 * * @return */ private String genPayReq() { // 获取参数的值 PayReq request = new PayReq(); request.appId = ConstantsMember.APP_ID; request.partnerId = ConstantsMember.MCHID; request.prepayId =

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

    目录 效果展示 功能实现 人脸支付 密码框输入支付 尾言 效果展示 人脸支付效果视频 密码框输入支付效果视频 因为密码支付时会调起系统安全键盘,开启自动保护功能,防止泄露,会导致输入密码时录屏黑屏,故使用另一台手机拍摄. 功能实现 人脸支付 API初始化 ftEngine = new FaceEngine(); ftInitCode = ftEngine.init(this, DetectMode.ASF_DETECT_MODE_VIDEO, ConfigUtil.getFtOrient(thi

  • ImageView 实现Android colorPikcer 选择器的示例代码

    本文介绍了ImageView 实现Android colorPikcer 选择器的示例代码,分享给大家,具体如下: Android colorPikcer 选择器 环形的ColorPicker,主要思路是: Color 选在放在ImageView 的background上面,根据点击的位置判断选择的颜色. 重写onTouch,在onTouch 里面判断点击点的颜色. 根据当前选择的颜色设置图片的src. 获取Bitmap 在 ColorPickerView 构造函数中初始化 Bitmap.因为g

  • Android 曲线图的绘制示例代码

    本文介绍了Android 曲线图的绘制示例代码,分享给大家,具体如下: 效果展示 效果展示.gif 使用方式 // 初始化数据表格相关 with(mTableView) { // 配置坐标系 setupCoordinator("日", "人", /*这里是横坐标的值*/0f, 5f, 10f, 15f, 20f, 25f, 30f) // 添加曲线, 确保纵坐标的数值位数相等 addWave(ContextCompat.getColor(this@MainActiv

  • Android进程间通信实践的示例代码

    本文介绍了Android进程间通信实践的示例代码,分享给大家,具体如下: 因为线程间的内存是共享的,所以它们之间的通信简单,比如可以通过共享变量等方式实现.而进程间想要通信就要麻烦许多了.要想实现进程间通信,我们需要在不同进程之间定义一套它们可以共同理解的接口描述语言,也即 IDL.比较常用的 IDL 有 JSON.Protocol Buffers 等.而 Android 不同进程之间的通信也有个特别的语言,叫 AIDL(Android Interface Definition Language

  • Android 滚动时间选择的示例代码

    效果图 复制代码直接用!!!! 1.导入依赖 implementation 'com.bigkoo:pickerview:2.1.0' 2.三个bean类 PickerViewData public class PickerViewData implements IPickerViewData { private String content; public PickerViewData(String content) { this.content = content; } public voi

  • Android解析json数据示例代码(三种方式)

    Json数据 复制代码 代码如下: [{"code":"110000","sheng":"11","di":"00","xian":"00","name":"北京市","level":1},{"code":"659004","sheng&q

  • Android支付宝支付的示例代码

    上一篇,我们已经详细讲解了Android微信支付,今天接着为大家带来支付宝支付,支付宝支付相对微信支付要简单一些,吐槽一下,而且支付宝文档确实比微信的文档好了不少,下面开始讲解支付流程. 1.首先给出官方文档的地址 Android集成支付宝流程 2.在开始集成和开发前,首先了解一下常用的接入方式和架构建议: 支付流程.png 在开始下一步之前,给大家看看网上的很多操作. 网上的代码.png 这一大堆代码,后面还有,百来行吧,而且支付宝Demo貌似也是这么干的,估计一些新司机就有点懵逼了,至于吗?

  • Android实现图片压缩示例代码

    核心思想是通过BitmapFactory.Options来缩放图片,主要是用到了它的inSampleSize参数(采样率) 当inSampleSize为1的时候,采样后的图片大小为图片的原始大小: 当inSampleSize为2的时候,采样后的图片的宽和高是原来的1/2,也就是说,它的像素点是原来的1/4,占的内存自然就是原来的1/4了.以此类推. 当inSampleSize小于1的时候,效果和等于1的时候是一样的. 压缩流程如下: 1.BitmapFactory.Options 的inJust

  • Android 国际货币格式化的示例代码

    简评:今天介绍下 Android 中国际货币格式化的一个小小知识点. 目前为止,货币格式化最简单的方式是调用 NumberFormat.getCurrencyInstance() 获得 NumberFormat 实例来把数字格式化为货币格式的字符串(当然也可以把字符串转换成数字).可以根据当前设备的位置来获取 java.util.Currency 实例再以此进行货币的格式化. 但如果我们的应用只接受特定的几种货币,那这种随着用户设备位置而修改货币格式就不是一个好的做法. 你可能会说「这简单啊,那

  • android异步生成图片的示例代码

    下面来说说在Android上如果异步生成图片,通过xml布局用View排版好图片样式,在子线程生成一张图片,以满足生成用来分享的图片等需求(生成图片前设置可变元素,如用户的头像,昵称等). 效果 点击按钮生成图片: 特性 通过布局和View的方式设计图片样式. 在子线程中生成和保存图片. 封装好工具类,直接使用即可. 核心代码 private Bitmap createBitmap(View view) { int widthSpec = View.MeasureSpec.makeMeasure

随机推荐