您的当前位置:首页正文

腾讯云Android 人脸识别,快速接入代码

2024-11-25 来源:个人技术集锦

之前直接照着自己的理解罗列了下腾讯云的文档,然后被喷了,那么直接提供代码把。

调用方法

    var userBean = UserBean()
            userBean.name = ""//验证姓名
            userBean.idNo = ""// 身份证号
            userBean.userId = "123456"        
FaceVerifySuper.setListener(mContext, userBean, object : FaceVerifySuper.OnTencentRequestListener {
                override fun faceVerifySuccess() {

                }

                override fun faild() {

                }

            })

        }

 具体实现

APP_ID,SECRT, keyLicence,这3个参数要自己填写



import android.annotation.SuppressLint
import android.content.Context
import android.content.Context.WIFI_SERVICE
import android.net.wifi.WifiManager
import android.nfc.Tag
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import com.google.common.hash.Hashing
import com.hjq.toast.ToastUtils
import com.webank.facelight.contants.WbCloudFaceContant
import com.webank.facelight.contants.WbFaceError
import com.webank.facelight.listerners.WbCloudFaceVeirfyLoginListner
import com.webank.facelight.tools.WbCloudFaceVerifySdk
import okio.HashingSink
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.math.log


@SuppressLint("StaticFieldLeak")
object FaceVerifySuper {

    var TAG = "FaceVerify"
    val APP_ID = ""
    val SECRT = ""
    val GRANT_TYPE = "client_credential"
    val VERSION = "1.0.0"
    val TENCENT_BASE_URL = "https://idasc.webank.com/api/"

    var onTencentRequestListener: OnTencentRequestListener? = null
    var userBean: UserBean? = null
    var mContext: Context? = null

    fun setListener(mContext: Context, userBean: UserBean, onTencentRequestListener: OnTencentRequestListener) {
        this.mContext = mContext
        this.userBean = userBean
        Log.e("Tag", "userBean====${userBean}")
        this.onTencentRequestListener = onTencentRequestListener
        doFaceVerify()
    }

    fun transferFaceSdk(verifyBean: TencentFaceVerifyBean) {
        verifyBean?.wifiIp = "IP=" + getIpAddress(mContext!!)
        var faceVerifyResult: FaceVerifyResult = FaceVerifyResult()
        //腾讯云线下对接分配的 Licence
        var keyLicence = ""
        var verifyMsgBean = VerifyMsgBean()
        verifyMsgBean.userId = verifyBean.userId
        verifyMsgBean.wifiIp = verifyBean?.wifiIp
//        verifyMsgBean.roleName = verifyBean.userBean?.roleName

        Log.e("tag", " verifyBean.orderNo=======${verifyBean.orderNo}")
        //传入数据
        var data = Bundle();
        var inputData = WbCloudFaceVerifySdk.InputData(
                verifyBean.faceId,
                verifyBean.orderNo,
                verifyBean.wifiIp,
                verifyBean.gps,
                APP_ID,
                VERSION,
                verifyBean.noceStr,
                verifyBean.userId,
                verifyBean.sign,
                verifyBean.verifyMode,
                keyLicence);


        data.putSerializable(WbCloudFaceContant.INPUT_DATA, inputData);

        //个性化参数设置,可以不设置,不设置则为默认选项。
        //是否显示成功结果页,默认显示,此处设置为不显示
        data.putBoolean(WbCloudFaceContant.SHOW_SUCCESS_PAGE, false);
        //是否展示刷脸失败页面,默认展示,此处设置为不显示
        data.putBoolean(WbCloudFaceContant.SHOW_FAIL_PAGE, false);
        //sdk样式设置,默认为黑色
        //此处设置为白色
        data.putString(WbCloudFaceContant.COLOR_MODE, WbCloudFaceContant.WHITE);

        //设置选择的比对类型  默认为权威库网纹图片比对
        //权威数据源比对 WbCloudFaceContant.ID_CRAD
        //自带比对源比对  WbCloudFaceContant.SRC_IMG
        //仅活体检测  WbCloudFaceContant.NONE
        //此处设置权威数据源对比
        // data.putString(WbCloudFaceContant.COMPARE_TYPE, WbCloudFaceContant.ID_CRAD);
        //是否需要录制上传视频 默认需要,此处设置为需要
        data.putBoolean(WbCloudFaceContant.VIDEO_UPLOAD, false);
        //是否对录制视频进行检查,默认不检查,此处设置为不检查
        data.putBoolean(WbCloudFaceContant.VIDEO_CHECK, false);
        //设置是否打开闭眼检测,默认不检测,此处设置为检测
        data.putBoolean(WbCloudFaceContant.ENABLE_CLOSE_EYES, true);
    Log.e("FVPresenter", "\n========>>>>" + inputData + "\n")

        //初始化 SDK,得到是否登录 SDK 成功的结果
        WbCloudFaceVerifySdk.getInstance().initSdk(mContext, data, object : WbCloudFaceVeirfyLoginListner {
            override fun onLoginSuccess() {

                WbCloudFaceVerifySdk.getInstance().startWbFaceVeirifySdk(mContext) { result ->
                    if (result != null) {

                        verifyMsgBean.isSuccess = result.isSuccess
                        verifyMsgBean.sign = result.sign
                        verifyMsgBean.liveRate = result.liveRate
                        verifyMsgBean.similarity = result.similarity
                        verifyMsgBean.orderNo = result.orderNo 

                        if (result.isSuccess) {
                            faceVerifyResult?.isSuccess = true

                            Log.d(TAG, "刷脸成功! Sign=" + result.sign + "; liveRate=" + result.liveRate +
                                    "; similarity=" + result.similarity + "userImageString=" + result.userImageString)
                            Toast.makeText(mContext, "身份识别成功", Toast.LENGTH_SHORT).show()
                            onTencentRequestListener?.faceVerifySuccess()
                        } else {
                            val error = result.error
                            verifyMsgBean.verror = VerifyMsgBean.VError()
                            verifyMsgBean.verror?.domain = error.domain
                            verifyMsgBean.verror?.code = error.code
                            verifyMsgBean.verror?.desc = error.desc
                            verifyMsgBean.verror?.reason = error.reason
                            verifyMsgBean.error = verifyMsgBean.verror.toString()
                            if (error != null) {
                                Log.d(TAG, "刷脸失败!domain=" + error.domain + " ;code= " + error.code
                                        + " ;desc=" + error.desc + ";reason=" + error.reason)
                                if (error.domain == WbFaceError.WBFaceErrorDomainCompareServer) {
                                    Log.d(TAG, "对比失败,liveRate=" + result.liveRate +
                                            "; similarity=" + result.similarity)
                                }
                                onTencentRequestListener?.faild()
                                Toast.makeText(mContext, "刷脸失败!" + error.desc,
                                        Toast.LENGTH_LONG).show()
                            } else {
                                Log.e(TAG, "sdk返回error为空!")
                            }
                        }
//                        listener.success(verifyBean, result)
                    } else {
                        verifyMsgBean.sdkNull = true
                        Log.e(TAG, "sdk返回结果为空!")
                    }
                    sumbitVerifyMsg(verifyMsgBean!!)
                }
            }

            override fun onLoginFailed(error: WbFaceError?) {
                Log.i(TAG, "onLoginFailed!")
                // 通知页面失败
//                listener.faild(verifyBean, error!!)
                onTencentRequestListener?.faild()
                if (error != null) {
                    verifyMsgBean.verror = VerifyMsgBean.VError()
                    verifyMsgBean.verror?.domain = error.domain
                    verifyMsgBean.verror?.code = error.code
                    verifyMsgBean.verror?.desc = error.desc
                    verifyMsgBean.verror?.reason = error.reason
                    verifyMsgBean.error = verifyMsgBean.verror.toString()

                    Log.e(TAG, "登录失败!domain=" + error.domain + " ;code= " + error.code
                            + " ;desc=" + error.desc + ";reason=" + error.reason)
                    if (error.domain == WbFaceError.WBFaceErrorDomainParams) {
                        ToastUtils.show("传入参数有误!" + error.reason)
                    } else {
                        ToastUtils.show("登录刷脸sdk失败!" + error.desc)
//                        Toast.makeText(mContext, "登录刷脸sdk失败!" + error.desc, Toast.LENGTH_SHORT).show()
                    }
                } else {
                    verifyMsgBean.sdkNull = true
                    Log.e(TAG, "sdk返回error为空!")
                }
                sumbitVerifyMsg(verifyMsgBean)
            }
        })

    }


    /**
     * 人脸识别请求
     */
    fun doFaceVerify() {

        // 判断传入数据是否合法
        if (onTencentRequestListener == null || userBean == null || Constants.isEmptyS(userBean!!.name, userBean!!.idNo, userBean!!.userId)) {
            Log.e(TAG, "onTencentRequestListener${onTencentRequestListener}")
            Log.e(TAG, "userBean!!.name${userBean!!.name}")
            Log.e(TAG, "userBean!!.name${userBean!!.idNo}")
            Log.e(TAG, "userBean!!.name${userBean!!.userId}")
            ToastUtils.show("非法数据")
        } else {
            getAccessToken()
        }

    }


    fun getFaceId(sgin: String, noceStr: String) {

        var verifyBean = TencentFaceVerifyBean()
        verifyBean.webankAppId = APP_ID
        verifyBean.orderNo = Constants.getRandomNumber()
        verifyBean.name = userBean?.name
        verifyBean.idNo = userBean?.idNo
        verifyBean.userId = userBean?.userId
        verifyBean.sign = sgin
        verifyBean.noceStr = noceStr

        getRetroClientByTencentUrl().requestFaceId(Constants.Obj2RequestBody(verifyBean)).enqueue(object : Callback<TencentResponseBean> {

            override fun onResponse(call: Call<TencentResponseBean>, response: Response<TencentResponseBean>) {
                // 成功获取信息
                if (OnRequestUtils.isTXResponseSuccess(response) && response.body()?.result?.faceId != null) {
                    verifyBean.faceId = response.body()?.result?.faceId
                    transferFaceSdk(verifyBean)
                } else {
                    if (response.body()?.msg != null)
//                        doFaildOperational(response,-1)
                        ToastUtils.show("错误信息:" + response.body()?.msg)
                    onTencentRequestListener?.faild()
                }

            }

            override fun onFailure(call: Call<TencentResponseBean>, t: Throwable) {

                onTencentRequestListener?.faild()
            }


        })

    }


    //    https://idasc.webank.com/api/oauth2/api_ticket
    /**
     * 获取NoceTicket
     */
    fun getNonceTicket(t: TencentResponseBean) {
        val requestMap = HashMap<String, String>()
        requestMap.put("app_id", APP_ID);
        requestMap.put("access_token", t.access_token!!);
        requestMap.put("type", "NONCE");
        requestMap.put("version", VERSION);
        requestMap.put("user_id", userBean!!.userId!!);
        getRetroClientByTencentUrl().requestNonceTicket(requestMap).enqueue(object : Callback<TencentResponseBean> {
            override fun onResponse(call: Call<TencentResponseBean>, response: Response<TencentResponseBean>) {
                if (OnRequestUtils.isTXResponseSuccess(response)
                        && response.body()?.tickets?.size!! > 0
                        && response.body()?.tickets?.get(0)!!.value != null
                ) {
                    var noceStr: String = Constants.getRandomNumber()
                    var values = ArrayList<String>()
                    values.add(APP_ID)
                    values.add(userBean!!.userId!!) //合作方自行分配(与 SDK 里定义的 userId 保持一致)
                    values.add(VERSION)
                    values.add(noceStr)// 合作方自行生成(与 SDK 里定义的随机数保持一致)
                    var sign = signGenerate(values, response.body()!!.tickets!!.get(0)!!.value!!) // 获取签名
                    //  执行获取 faceId 方法
                    getFaceId(sign, noceStr)
                } else {
                    doFaildOperational(response, 1)
                    onTencentRequestListener?.faild()
                }
            }

            override fun onFailure(call: Call<TencentResponseBean>, t: Throwable) {
                onTencentRequestListener?.faild()
            }
        })

    }

    /**
     * 获取Access Token
     */
    @Throws()
    fun getAccessToken() {
        val requestMap = HashMap<String, String>()
        requestMap.put("app_id", APP_ID);
        requestMap.put("secret", SECRT);
        requestMap.put("grant_type", GRANT_TYPE);
        requestMap.put("version", VERSION);

        getRetroClientByTencentUrl().requestAccessToken(requestMap).enqueue(object : Callback<TencentResponseBean> {

            override fun onResponse(call: Call<TencentResponseBean>, response: Response<TencentResponseBean>) {
                // 判断返回是否成功
                if (OnRequestUtils.isTXResponseSuccess(response) && response.body()?.access_token != null) {
                    getNonceTicket(response.body()!!)
                } else {
                    doFaildOperational(response, 0)
                    onTencentRequestListener?.faild()
                }
            }

            override fun onFailure(call: Call<TencentResponseBean>, t: Throwable) {
                onTencentRequestListener?.faild()
            }

        })

    }

    /**
     * 签名算法
     * @param values
     * @param ticket
     * @return
     */
    fun signGenerate(values: ArrayList<String>, ticket: String): String {
//        values.removeAll(Collections.singleton(null))// remove null
        values.add(ticket)
        Collections.sort(values)
        val sb = StringBuilder()
        for (s in values) {
            sb.append(s)
        }
        return Hashing.sha1().hashString(sb, Charsets.UTF_8).toString().toUpperCase()
    }

    /**
     * 腾讯云请求配置
     */
    fun getRetroClientByTencentUrl(): RequsetDataInterface {
        return RetroClient.getApiService(TENCENT_BASE_URL)
    }

    /**
     * 腾讯云正常响应,返回不通过处理
     */
    fun doFaildOperational(response: Response<TencentResponseBean>, type: Int) {
        var failMsg: StringBuffer = StringBuffer("Faild code :")
                .append(response.body()?.code)
                .append(" msg :")
                .append(response.body()?.msg)
        if (type == 0 && response.body()?.access_token == null) {
            failMsg.append("Bad Response ACCESS_TOKEN = NULL")
        } else if (type == 1 && response.body()?.tickets == null) {
            failMsg.append("Bad Response NONCE_TICKET = NULL")
        }
        ToastUtils.show(failMsg)
    }


    /**
     * 提交此次验证信息结果至己方平台
     */
    fun sumbitVerifyMsg(v: VerifyMsgBean) {
    }

    /**
     * 获取当前设备wifi IP
     */
    private fun getIpAddress(mContext: Context): String {
        val wm = mContext.getApplicationContext().getSystemService(WIFI_SERVICE) as WifiManager
        val ipAddressInt = wm.connectionInfo.ipAddress
        val ipAddress = String.format(Locale.getDefault(), "%d.%d.%d.%d", ipAddressInt and 0xff, ipAddressInt shr 8 and 0xff, ipAddressInt shr 16 and 0xff, ipAddressInt shr 24 and 0xff)
        return ipAddress
    }

    /**
     * 回调响应
     */
    interface OnTencentRequestListener {
        fun faceVerifySuccess()
        fun faild()

    }
}

 

显示全文