android使用可信科技的人脸识别活体认证遇到的问题

由于项目需要实现身份的人脸识别活体认证功能,所以这里采用可信科技中的人脸识别功能,当然这是人家的劳动成果,认证的过程是需要钱的。实现监面android端并不难,很多东西人家的sdk中都已经封装好了,监面人脸识别的整体流程有:


1、android客户端需要下载相应的sdk,在官网上面有例子,官网的链接是:http://www.kexin.net/,下载android的studio例子或者eclipse的例子的时候,里面的所有资源文件一定要拷贝进去,否则就会报错。


2、android端拷贝完所有的资源后,只需要在需要使用的activity中继承 ActivityBase,填写用户名、密码、姓名、身份证以及后台服务器的地址,一般申请了监面开发者账号的,可信公司将提供请求接口时使用的账号(akey)和密码(skey),就是上诉所说的用户名和密码。 CameraActivity1类就是启动监面进行活体认证拍照的类,在需要调用活体认证处,添加如下代码:


sp = getSharedPreferences("mrsoft", MODE_PRIVATE);
        editor = sp.edit();
        editor.putString("ip", ip);
        editor.putString("editUid", username);
        editor.putString("editPwd", pwd);
        editor.putString("name", name);
        editor.putString("number", number);
        editor.commit();
        Intent it = getIntent();
        Bundle b = new Bundle();
        b.putString("ip", ip);
        b.putString("username", username);
        b.putString("password", pwd);
        b.putString("name", name);
        b.putString("number", number);
        it.putExtras(b);
        it.setClass(TourismLoanActivity.this, CameraActivity1.class);
        startActivityForResult(it, ResultCode);



上诉的代码,是将身份证、姓名、用户名、密码、ip传至

CameraActivity1中,交由其该类进行活体认证后,将图片上传至ip地址的服务器后台中,再通过回调,返回服务器那边接收到的认证结果,注意,这里的服务器指的是自己公司的服务器,而不是监面那边的服务器,监面是不提供直接客户端与监面服务器的直接的对接的,都是由客户端上传图片至自己公司的服务器上,再由公司的服务器上传至监面的服务器进行验证后将结果返回至公司服务器,再由公司服务器返回结果到客户端回调处,所以,在回调的地方的去处理相应的结果:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
    //活体认证回调返回
    if(requestCode==ResultCode&&resultCode==ResultCode)
    {
        // 刷新数据++++++++++++++++++++++++++++++++
        Bundle bundle = data.getExtras();
        String result = bundle.getString("result");
        try {
            JSONObject jsonObject = new JSONObject(result);
           int state =  jsonObject.getInt("state");
            if(state==0){//识别成功
                showCustomToast("采样成功");
            }else{
                showCustomToast("采样失败,请重新采样!");
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }


另外,在android4.4系统上,有可能会出现点击第一次活体认证是没有问题的,当重复再点击的时候程序就会崩溃,出现文件的路径为空的现象,这是由于以下代码导致的,只需要将其屏蔽掉即可:


File kexinface=	new File(FileUtil.getWaterPhotoPath());
			for (File file : kexinface.listFiles()) {
	            if (file.isFile())
	                file.delete(); // 删除所有文件
			}
			kexinface.delete();// 删除目录本身

其实究其原因,应该是由于android4.4中访问文件的路径的方式与其他android其他的不一样导致文件路径找不着,使用爆空指针的bug。



有的时候使用人脸识别可能不是直接一个按钮就启动的,还需要在webView中进行操作,甚至于webView中不仅仅只有人脸识别需要调用摄像机拍照,还可能需要另外拍证件照,那么此时就会有两个功能,一个是在webView中调用相机来进行证件照的拍摄,一个是需要调用人脸识别来进行图片的活体拍摄,那么在webView中是怎么实现的呢?首先通常布局文件中就是一个webView控件,


<?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">
    <WebView
        android:id="@+id/id_webView"
        android:layout_below="@id/id_rl_top"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></WebView>
</RelativeLayout>


在activity中,则需要初始化webView控件,以及设置相应的属性


/*

     * 初始化WebView

     */

    private void initWebView() {

        //从布局文件中扩展webView

        this.webView = (WebView) this.findViewById(R.id.id_webView);

        // 得到设置属性的对象
        WebSettings webSettings = webView.getSettings();

        // 使能JavaScript
        webSettings.setJavaScriptEnabled(true);


//        webView.addJavascriptInterface(this, "test");//对应js中的test.xxx

        //设置可以访问文件
        webSettings.setAllowFileAccess(true);
        //设置支持缩放
        webSettings.setBuiltInZoomControls(true);

        webView.addJavascriptInterface(this, "test");//对应js中的test.xxx
        webView.addJavascriptInterface(this, "takePhoto");//对应js中的test.xxx
//        this.webView.setWebChromeClient(new chromeClient());

        this.webView.loadUrl("链接地址");
        //设置Web视图
        webView.setWebViewClient(new webViewClient (){
            @Override
            public void onPageFinished(WebView view, String url)
            {
                super.onPageFinished(view, url);
                progressDialog.dismiss();//加载网页完成时,关闭提示
            }
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon)
            {
                super.onPageStarted(view, url, favicon);
                progressDialog.show();<span style="font-family: 宋体;">//加载网页时,显示滚动条</span>

            }
        });


    }



在android中,上诉的js的调用的android中的方法:


/**
     * js调用android的活体验证身份的方法
     * @param username
     * @param ic_card
     */
    @JavascriptInterface
    public void startPeopleIdentify(String username, String ic_card) {//对应js中xxx.hello("")
//        Log.e("zqy", "startPeopleIdentify::::" + username + "," + ic_card);
        name = username;
        number = ic_card;
        start();


    }

    /**
     * js调用android的拍照方法
     * @param str
     */
    @JavascriptInterface
    public void takePhoto(String str) {//对应js中xxx.hello("")
        //调用摄像头
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        param = str;
        startActivityForResult(intent, ResultCodePhoto);
    }



在js中,js调用android的方法:


function <span style="font-family: 宋体;">startPeopleIdentify</span><span style="font-family: 宋体;">() {</span>
<span >	</span>window.<span style="font-family: 宋体;">test</span><span style="font-family: 宋体;">.</span><span style="font-family: 宋体;">startPeopleIdentify</span><span style="font-family: 宋体;">();//js调用android中的活体认证方法</span>
}



function <span style="font-family: 宋体;">takePhoto</span>() {
	window.<span style="font-family: 宋体;">takePhoto</span>.<span style="font-family: 宋体;">takePhoto</span><span style="font-family: 宋体;">();//js调用android中的拍照方法</span>
}

在activity中的回调:


//拍照回调返回
        if(requestCode==ResultCodePhoto&&resultCode == RESULT_OK) {
            String sdStatus = Environment.getExternalStorageState();
            if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
                Log.i("TestFile",
                        "SD card is not avaiable/writeable right now.");
                return;
            }
            String name = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
            Bundle bundle = data.getExtras();
            Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式
            if (bitmap != null) {
                final String result = bitmaptoString(bitmap);
                webView.post(new Runnable() {//此处是将拍照返回的bitmap转成字符串,传递给js,显示拍照后的图片
                    @Override
                    public void run() {
                        webView.loadUrl("javascript:callJS('" + param + "','" + result + "')");
                    }
                });
            } else {
                Toast.makeText(this, "拍照不成功,请重新拍照..", Toast.LENGTH_SHORT).show();
            }
        }
    //活体认证回调返回
    if(requestCode==ResultCode&&resultCode==ResultCode)
    {
        // 刷新数据++++++++++++++++++++++++++++++++
        Bundle bundle = data.getExtras();
        String result = bundle.getString("result");
        try {
            JSONObject jsonObject = new JSONObject(result);
           int state =  jsonObject.getInt("state");
            if(state==0){//识别成功
                showCustomToast("采样成功");
            }else{
                showCustomToast("采样失败,请重新采样!");
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

以下是拍照后将bitmap转成字符串的方法:


/**
     * 将Bitmap转换成字符串
     * @param bitmap
     * @return
     */
    public String bitmaptoString(Bitmap bitmap) {
        String string = null;
        ByteArrayOutputStream bStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, bStream);
        byte[] bytes = bStream.toByteArray();
        string = Base64.encodeToString(bytes, Base64.DEFAULT);
        return string;
    }

大致上的问题就到这里了,下面附赠活体认证的例子的链接,有需要的可以去下载