Android接入advance活体检测

Android接入Advance.Ai活体检测 Api (安卓活体检测)

通过摄像头实时采集动态影像、识别人物面部表情,以此检测、验证用户的真实性与可靠性。
advance.ai 系统已针对印度尼西亚、印度、菲律宾、越南、泰国这五个国家市场的本地使用环境,定制开发了性能优化方案

活体检测前提:安卓系统相机授权可点击此链接学习

advance活体检测时序图UML 操作步骤梳理:

在这里插入图片描述
快速开发代码预览(本人亲测)

  1. Liveness Detection License Authorization
    (服务器端请求advance许可证)

    //其实也可以直接Android请求,但前提保证Android手机所有面相用户能访问的到advance(国内访问不了外网)

Request Url
https://api.advance.ai/openapi/liveness/v1/auth-license
POST (application/json)
Notes:
ADVANCE service is deployed overseas. If your test/official environment is in China, please request the service via VPN to avoid packet loss, service timeout and other problems

example

curl -X POST //请求方式
-H “X-ADVAI-KEY: {Your Access Key}” // 请求头header 加入 该参数 Advance Access Key
-H “Content-Type: application/json” //请求头header内容类型application/json
-d ‘{“licenseEffectiveSeconds”: 600}’ //applicationId如果加入会进行包名校验,默认不传
“https://api.advance.ai/openapi/liveness/v1/auth-license” // url

  1. 活体检测
//该方法以及参数等后面有详细说明
GuardianLivenessDetectionSDK.init(getApplication(), Market.Indonesia); //印尼市场
//license参数通过步骤1获取
String checkResult = GuardianLivenessDetectionSDK.setLicenseAndCheck(license);//步骤一获取license参数
if ("SUCCESS".equals(checkResult)) {
    // license 有效
    checkPermissions(); //该方法是检测相机权限以及调用活体检测在下面8有
} else {// license 不可用,过期或者格式错误
    Toast.makeText(MainActivity.this, checkResult, Toast.LENGTH_SHORT).show();
}
  1. 返回参数
LivenessResult.isSuccess();      //是否成功
LivenessResult.getLivenessId();  //可以api加入参数来查看分数
LivenessResult.getLivenessBitmap();  //获取活体检测图像
  1. LivenessId参数反馈查看

Request URL
https://api.advance.ai/openapi/liveness/v3/detection-result
POST (application/json)
Request Parameters:
livenessId
resultType

(详细说明如下:)


1.advance活体检测动作

在这里插入图片描述

//动作顺序  张嘴  眨眼  摇头...
// 第一个布尔值代表是否打乱传入的动作顺序,true 代表打乱顺序。 默认的动作顺序是 [眨眼]->[摇头]
GuardianLivenessDetectionSDK.setActionSequence(true,Detector.DetectionType.POS_YAW, Detector.DetectionType.MOUTH, Detector.DetectionType.BLINK);

2.advance官网

2.1 中文官网

https://www.advanceai.com.cn/cn/index/pageview/catid/122.html

2.2 印尼官网

https://in.advance.ai/

[ click (API Doc-> Liveness detection)
点击 (API文档->活体检测) ]

2.3 英文官网

https://www.advance.ai/liveness-detection

3. Android接入advance活体检测

Android接入AdvanceAI活体检测,通过摄像头实时采集检测详细说明如下:

3.0 Advance活性检测服务有三个步骤:

`
*步骤1:请求活动检测许可证授权以获得“许可证”
*步骤2:转到下载,下载Android或IOS SDK,将其集成到您的移动应用程序中,以进行活跃度检测,并将步骤1中获取的“许可证”作为请求参数
*步骤3:请求Liveness Detection,以步骤2返回的“livenessId”作为请求参数,获取Liveness分数及其对应的图像
`

官网参考:
活动检测许可证授权(步骤一)
Android or IOS(步骤二)
example Android sdk url address:SDK
(如果访问不了外网,可下载我上传csdn的SDK资源包AndroidX SDK)
个人免费csdn资源无需积分demo测试成功代码

当下载完SDK后,可进行如下操作:

3.1 集成 SDK 到您的工程中


3.1.1 打开SDK文件夹,得到如下文件。

文件/文件夹名称解释
liveness集成活体检测功能的模块
  • liveness module 是集成了活体检测功能的UI模块,可直接引用到您的主工程中,根据实际需求进行个性化修改。
  • 考虑到架构之间存在兼容性,以及每种架构的机型占比,如果对包大小有要求,建议选择如下方案:
android{
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters "armeabi","arm64-v8a","x86"
        }   
    }
}

3.1.2 导入 liveness 模块到您的工程

导入模块时注意点说明:

①.liveness模块与app同级目录
在这里插入图片描述
②.livenness模块内的build.gradle下的vision版本记得更改
compileSdkVersion、targetSdkVersion等
在这里插入图片描述
③.app目录内的build.gradle下的dependencies依赖以及flatDir
加入:

repositories {
    flatDir {
        dirs project(':liveness').file('libs')
    }
}
dependencies {
	implementation project(":liveness")
}

在这里插入图片描述
④. 修改android目录下的setting.gradle文件,添加项目模块的引用

include ":liveness"

在这里插入图片描述

3.2 详细接入SDK说明


  1. 初始化 SDK。
  • 在自定义的 application 中增加如下初始化代码:
// 初始化方法不耗时,非必须在 application 中初始化,但要确保进入 LivenessActivity 之前完成调用
GuardianLivenessDetectionSDK.init(this,your market);  // (Market的选择在下方可参考)
Market
Indonesia
India
Philippines
Vietnam
Thailand
Malaysia
Mexico
Singapore
Aksata
Pakistan
Nigeria
CentralData

最后一个参数 Market 是一个枚举类型,必须和您的账号所属国家的类别一致,否则无法通过授权。

  1. 设置 license (由您的服务端调用openAPI获取license)
String checkResult = GuardianLivenessDetectionSDK.setLicenseAndCheck(license);
if ("SUCCESS".equals(checkResult)) {
    // license 有效
   startLivenessActivity();
} else {
    // license 不可用,过期/格式错误/appId未备案
}
  1. 启动活体检测与获取检测结果。

SDK 默认不检查相机权限,如果您希望权限的申请交由 SDK 处理,可在 SDK 初始化方法调用后,调用如下方法,则 LivenessActivity 中会执行权限申请的操作:

GuardianLivenessDetectionSDK.letSDKHandleCameraPermission();

每次进行活体检测成功后,会返回唯一的 livenessId 和本次检测的 300*300 像素的清晰正面照片。

  • 您需要将 livenessId 传给您的服务端,由服务端调用 openAPI 获取本次检测的分值。
  • 您可以通过 SDK 提供的方法直接获取图片,也可以由服务端调用 openAPI 获取。
/**
 * 请求状态码
 */
public static final int REQUEST_CODE_LIVENESS = xxxx;

/**
 * 启动活体检测
 */
private void startLivenessActivity() {
    Intent intent = new Intent(this, LivenessActivity.class);
    startActivityForResult(intent, REQUEST_CODE_LIVENESS);
}

/**
 1. 获取检测结果
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_LIVENESS) {
        if (LivenessResult.isSuccess()) {// 活体检测成功
            String livenessId = LivenessResult.getLivenessId();// 本次活体id
            Bitmap livenessBitmap = LivenessResult.getLivenessBitmap();// 本次活体图片
        } else {// 活体检测失败
            String errorCode = LivenessResult.getErrorCode();// 失败错误码
            String errorMsg = LivenessResult.getErrorMsg();// 失败原因
            ...
        }
    }
}
  1. 动作顺序说明

默认的动作顺序是 [眨眼]->[摇头],如需自定义动作顺序请参考如下代码:

在启动LivenessActivity页面前调用如下方法:

// 第一个布尔值代表是否打乱传入的动作顺序,true 代表打乱顺序。
GuardianLivenessDetectionSDK.setActionSequence(true,Detector.DetectionType.POS_YAW, Detector.DetectionType.MOUTH, Detector.DetectionType.BLINK);
  1. 用户绑定(强烈建议)。

您可以通过该方法将自己的用户唯一标识传给我们,我们会根据该标识建立映射关系。当遇到问题时,方便同我们进行日志追踪。

GuardianLivenessDetectionSDK.bindUser(String userId)
  1. 开启遮挡检测

遮挡检测默认是关闭状态,如需开启遮挡检测,请在初始化SDK之后调用如下方法设置

GuardianLivenessDetectionSDK.isDetectOcclusion(true)
  1. liveness 模块的代码可以自行修改来满足定制化需求。

目前 SDK 支持中文,英文,印尼文,越南语,泰国语,印地语,西班牙语 七种语言/语音。根据手机当前语言自动切换,无需代码设置,如您仅支持一种语言,可自行删除其余国家的资源文件。

错误码解释
FACE_MISSING检测过程中人脸丢失
ACTION_TIMEOUT动作超时
MULTIPLE_FACE检测过程中出现多张人脸
MUCH_MOTION检测过程中动作幅度过大
AUTH_BAD_NETWORK授权请求网络失败
CHECKING_BAD_NETWORK动作结束后图像上传网络请求失败
DEVICE_NOT_SUPPORT该设备不支持活体检测
USER_GIVE_UP用户中途放弃检测
UNDEFINED未定义的其他错误类型
AUTH_PARAMETER_ERROR授权请求参数错误
AUTH_IAM_FAILED包名未备案

8.官方demo

package ai.advance.integration.demo;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.blankj.utilcode.constant.PermissionConstants;
import com.blankj.utilcode.util.PermissionUtils;

import ai.advance.liveness.lib.GuardianLivenessDetectionSDK;
import ai.advance.liveness.lib.LivenessResult;
import ai.advance.liveness.lib.Market;
import ai.advance.liveness.sdk.activity.LivenessActivity;

public class MainActivity extends AppCompatActivity {
    static final int REQUEST_CODE_LIVENESS = 1000;
    private static final int PERMISSIONS_REQUEST_CODE = 1;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initKeyTypeButton();
        initTicketButton();
        initLicenseButton();

        //相机权限授权
        findViewById(R.id.key_type_button_camera).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "相机授权", Toast.LENGTH_SHORT).show();

                //申请系统相机权限
                startPreviewWithPermission();
            }
        });
    }
    private void startPreviewWithPermission() {
        //权限申请
        //PermissionUtils工具包权限类型:CAMERA相机
        //callback回调监听授权或拒绝 onGranted 授权事件  onDenied否绝事件
        PermissionUtils.permission(PermissionConstants.CAMERA)
                .callback(new PermissionUtils.SimpleCallback() {
                    @Override
                    public void onGranted() {
                        try {
                            Toast.makeText(MainActivity.this, "相机授权申请成功", Toast.LENGTH_SHORT).show();
                            //申请成功后,可以调用相机拍摄/视频等操作
                        } catch (Exception ignored) {
                            Toast.makeText(MainActivity.this, "相机授权申请报错", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onDenied() {
                        //可以在此函数中调用 AlertDialog 提示用户相应操作等
                        Toast.makeText(MainActivity.this, "相机授权申请否决", Toast.LENGTH_SHORT).show();
                    }
                }).request();
    }

    private void initLicenseButton() {
        findViewById(R.id.license_type_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO 将此处的 license 修改
                String license = null;
                if (license == null) {
                    new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 license 赋值").setPositiveButton("确定", null).create().show();
                } else {
                    boolean packageNamePass = checkPackageName();
                    if (packageNamePass) {
                        GuardianLivenessDetectionSDK.init(getApplication(), Market.Indonesia);
                        String checkResult = GuardianLivenessDetectionSDK.setLicenseAndCheck(license);
                        if ("SUCCESS".equals(checkResult)) {
                            // license 有效
                            checkPermissions();
                        } else {// license 不可用,过期或者格式错误
                            Toast.makeText(MainActivity.this, checkResult, Toast.LENGTH_SHORT).show();
                        }
                    }

                }
            }
        });
    }

    private void initKeyTypeButton() {
        findViewById(R.id.key_type_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO 将此处的 key 修改为您的
                String accessKey = "你的accessKey";
                String secretKey = "你的secretKey";
                
                Market market = Market.Indonesia;
                if (accessKey == null || secretKey == null || market == null) {
                    new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 Key 赋值").setPositiveButton("确定", null).create().show();
                } else {
                    boolean packageNamePass = checkPackageName();
                    if (packageNamePass) {
                        GuardianLivenessDetectionSDK.init(getApplication(), accessKey, secretKey, market);
                        checkPermissions();
                    }
                }

            }
        });
    }

    private void initTicketButton() {
        findViewById(R.id.ticket_type_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO 将此处的 ticket 修改
                String ticket = null;
                String queryId = null;
                if (ticket == null) {
                    new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 ticket 赋值").setPositiveButton("确定", null).create().show();
                } else {
                        GuardianLivenessDetectionSDK.init(getApplication(), Market.Indonesia);
                        GuardianLivenessDetectionSDK.setTicket(ticket);
                        GuardianLivenessDetectionSDK.setQueryId(queryId);
                        checkPermissions();
                }

            }
        });

    }

    private boolean checkPackageName() {
        if ("your.app.id".equals(getPackageName())) {
            new AlertDialog.Builder(MainActivity.this).setMessage("请将 build.gradle 中的包名修改为您已备案的").setPositiveButton("确定", null).create().show();
            return false;
        }
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE_LIVENESS:
//                    Call the following methods to get results
//                    String livenessId = LivenessResult.getLivenessId();
//                    Bitmap livenessBitmap = LivenessResult.getLivenessBitmap();
//                    String transactionId = LivenessResult.getTransactionId();
//                    boolean success = LivenessResult.isSuccess();
//                    String errorMsg = LivenessResult.getErrorMsg();
                if (LivenessResult.isSuccess()) {
                    Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, LivenessResult.getErrorCode(), Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    private boolean allPermissionsGranted() {
        for (String permission : getRequiredPermissions()) {
            if (ContextCompat.checkSelfPermission(this, permission)
                    != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
     * Detect camera authorization
     */
    public void checkPermissions() {
        if (allPermissionsGranted()) {
            onPermissionGranted();
        } else {
            ActivityCompat.requestPermissions(this, getRequiredPermissions(), PERMISSIONS_REQUEST_CODE);
        }
    }

    public String[] getRequiredPermissions() {
        return new String[]{Manifest.permission.CAMERA};
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSIONS_REQUEST_CODE) {
            //已授权
            if (allGranted(grantResults)) {
                onPermissionGranted();
            } else {
                onPermissionRefused();
            }
        }
    }

    /**
     * Denied camera permissions
     */
    public void onPermissionRefused() {
        new AlertDialog.Builder(this).setMessage(getString(R.string.liveness_no_camera_permission)).setPositiveButton(getString(R.string.liveness_perform), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        }).create().show();
    }

    private boolean allGranted(int[] grantResults) {
        boolean hasPermission = true;
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                hasPermission = false;
            }
        }
        return hasPermission;
    }

    /**
     * Got camera permissions
     */
    public void onPermissionGranted() {
        Intent intent = new Intent(this, LivenessActivity.class);
        //活体检测后回调至onActivityResult()
        startActivityForResult(intent, REQUEST_CODE_LIVENESS);
    }
}

9.个人亲自调试全部代码(成功)
个人免费无需积分资源demo代码下载全(https://download.csdn.net/download/mingketao/86503595)
在这里插入图片描述
注意advance密钥是要改为你自己的

package ai.advance.integration.demo;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;

import ai.advance.liveness.lib.Detector;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.constant.PermissionConstants;
import com.blankj.utilcode.util.PermissionUtils;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import ai.advance.liveness.lib.GuardianLivenessDetectionSDK;
import ai.advance.liveness.lib.LivenessResult;
import ai.advance.liveness.lib.Market;
import ai.advance.liveness.sdk.activity.LivenessActivity;
import okhttp3.Call;

public class MainActivity extends AppCompatActivity {
    static final int REQUEST_CODE_LIVENESS = 1000;
    private static final int PERMISSIONS_REQUEST_CODE = 1;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initKeyTypeButton();
        initTicketButton();
        initLicenseButton();

        //相机权限授权
        findViewById(R.id.key_type_button_camera).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "相机授权", Toast.LENGTH_SHORT).show();

                //申请系统相机权限
                startPreviewWithPermission();
            }
        });
    }
    private void startPreviewWithPermission() {
        //权限申请
        //PermissionUtils工具包权限类型:CAMERA相机
        //callback回调监听授权或拒绝 onGranted 授权事件  onDenied否绝事件
        PermissionUtils.permission(PermissionConstants.CAMERA)
                .callback(new PermissionUtils.SimpleCallback() {
                    @Override
                    public void onGranted() {
                        try {
                            Toast.makeText(MainActivity.this, "相机授权申请成功", Toast.LENGTH_SHORT).show();
                            //申请成功后,可以调用相机拍摄/视频等操作
                        } catch (Exception ignored) {
                            Toast.makeText(MainActivity.this, "相机授权申请报错", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onDenied() {
                        //可以在此函数中调用 AlertDialog 提示用户相应操作等
                        Toast.makeText(MainActivity.this, "相机授权申请否决", Toast.LENGTH_SHORT).show();
                    }
                }).request();
    }

    private void initLicenseButton() {
        findViewById(R.id.license_type_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO 将此处的 license 修改
                String license = "";
                if (license == null) {
                    new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 license 赋值").setPositiveButton("确定", null).create().show();
                } else {
                    boolean packageNamePass = checkPackageName();
                    if (packageNamePass) {
                        GuardianLivenessDetectionSDK.init(getApplication(), Market.Indonesia);
                        String checkResult = GuardianLivenessDetectionSDK.setLicenseAndCheck(license);
                        if ("SUCCESS".equals(checkResult)) {
                            // license 有效
                            checkPermissions();
                        } else {// license 不可用,过期或者格式错误
                            Toast.makeText(MainActivity.this, checkResult, Toast.LENGTH_SHORT).show();
                        }
                    }

                }
            }
        });
    }

    private void initKeyTypeButton() {
        findViewById(R.id.key_type_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO 将此处的 key 修改为您的
                String accessKey = "你的accessKey";
                String secretKey = "你的secretKey";
                
                Market market = Market.Indonesia;
                if (accessKey == null || secretKey == null || market == null) {
                    new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 Key 赋值").setPositiveButton("确定", null).create().show();
                } else {
                    boolean packageNamePass = checkPackageName();
                    if (packageNamePass) {
                        GuardianLivenessDetectionSDK.init(getApplication(), accessKey, secretKey, market);
                        checkPermissions();
                    }
                }

            }
        });
    }

    private void initTicketButton() {
        findViewById(R.id.ticket_type_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Map<String, String> params = new HashMap<>();
                params.put("licenseEffectiveSeconds", "600");

                String path = "https://api.advance.ai/openapi/liveness/v1/auth-license";
                String json = "{\"licenseEffectiveSeconds\":\"600\"}";

                Handler handler = new Handler() {};

                http(handler, path, json, new HttpCallBack() {
                    @Override
                    public void onFinishi(String json) {
                        JSONObject jsonObject = JSONObject.parseObject(json);
                        String license = jsonObject.getJSONObject("data").get("license").toString();

                        if (license == null) {
                            new AlertDialog.Builder(MainActivity.this).setMessage(" Foto tidak dapat terdeteksi, silahkan ulangi").create().show();
                        } else {
                            GuardianLivenessDetectionSDK.init(getApplication(), Market.Indonesia);
                            //动作顺序  张嘴  眨眼  摇头...
                            // 第一个布尔值代表是否打乱传入的动作顺序,true 代表打乱顺序。 默认的动作顺序是 [眨眼]->[摇头]
                            GuardianLivenessDetectionSDK.setActionSequence(true, Detector.DetectionType.POS_YAW, Detector.DetectionType.MOUTH, Detector.DetectionType.BLINK);
                            String checkResult = GuardianLivenessDetectionSDK.setLicenseAndCheck(license);
                            if ("SUCCESS".equals(checkResult)) {
                                // license 有效
                                Intent intent = new Intent(MainActivity.this, LivenessActivity.class);
                                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                startActivityForResult(intent, REQUEST_CODE_LIVENESS);
                            } else {// license 不可用,过期或者格式错误
                                //Toast.makeText(AdvanceFaceActivity.this, checkResult, Toast.LENGTH_SHORT).show();
                                new AlertDialog.Builder(MainActivity.this).setMessage(" Foto tidak dapat terdeteksi, silahkan ulangi").create().show();
                            }
                        }
                    }
                });
            }
        });

    }

    public static void http(final Handler handler, final String path, final String json, final HttpCallBack call){
        new Thread(){
            @Override
            public void run() {
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestProperty("Content-type","application/json");
                    //TODO 添加X-ADVAI-KEY
                    conn.setRequestProperty("X-ADVAI-KEY","需要添加你的key");
                    conn.setRequestMethod("POST");
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.setUseCaches(false);
                    PrintWriter writer = new PrintWriter(conn.getOutputStream(),true);
                    writer.println(json);
                    writer.close();
                    BufferedReader br =new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
                    final StringBuilder sb = new StringBuilder();
                    String l = "";
                    while( (l=br.readLine())!=null){
                        sb.append(l);
                    };
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            call.onFinishi(sb.toString());
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }


    private boolean checkPackageName() {
        if ("com.ecreditpal.cashloan.indo".equals(getPackageName())) {
            new AlertDialog.Builder(MainActivity.this).setMessage("请将 build.gradle 中的包名修改为您已备案的").setPositiveButton("确定", null).create().show();
            return false;
        }
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE_LIVENESS:
//                    Call the following methods to get results
//                    String livenessId = LivenessResult.getLivenessId();
//                    Bitmap livenessBitmap = LivenessResult.getLivenessBitmap();
//                    String transactionId = LivenessResult.getTransactionId();
//                    boolean success = LivenessResult.isSuccess();
//                    String errorMsg = LivenessResult.getErrorMsg();
                if (LivenessResult.isSuccess()) {

                    Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, LivenessResult.getErrorCode(), Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    private boolean allPermissionsGranted() {
        for (String permission : getRequiredPermissions()) {
            if (ContextCompat.checkSelfPermission(this, permission)
                    != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
     * Detect camera authorization
     */
    public void checkPermissions() {
        if (allPermissionsGranted()) {
            onPermissionGranted();
        } else {
            ActivityCompat.requestPermissions(this, getRequiredPermissions(), PERMISSIONS_REQUEST_CODE);
        }
    }

    public String[] getRequiredPermissions() {
        return new String[]{Manifest.permission.CAMERA};
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSIONS_REQUEST_CODE) {
            //已授权
            if (allGranted(grantResults)) {
                onPermissionGranted();
            } else {
                onPermissionRefused();
            }
        }
    }

    /**
     * Denied camera permissions
     */
    public void onPermissionRefused() {
        new AlertDialog.Builder(this).setMessage(getString(R.string.liveness_no_camera_permission)).setPositiveButton(getString(R.string.liveness_perform), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        }).create().show();
    }

    private boolean allGranted(int[] grantResults) {
        boolean hasPermission = true;
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                hasPermission = false;
            }
        }
        return hasPermission;
    }

    /**
     * Got camera permissions
     */
    public void onPermissionGranted() {
        Intent intent = new Intent(this, LivenessActivity.class);
        //活体检测后回调至onActivityResult()
        startActivityForResult(intent, REQUEST_CODE_LIVENESS);
    }
}

10.问题解决
“no variants found for app”->解决方案下载android sdk28, 如下
下载sdk28

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
NR PRACh(Physical Random Access Channel)是5G新无线标准中引入的一种信道,用于实现设备对基站的随机接入过程。NR PRACh的流程经过了一些改进和更新,现在我们来简析NR PRACh的流程v2.0版本。 NR PRACh的随机接入过程主要分为两个阶段:PREAMBLE和数据传输。 在PREAMBLE阶段,设备首先选择一个RA-RNTI(Random Access-Radio Network Temporary Identifier),然后根据系统配置的PREAMBLE格式,生成一个随机接入前导码(Preamble)。设备使用随机接入前导码发送信号至基站。基站会对接收到的信号进行解码,并通过测量指示器(Timing Advance Command)告知设备在物理层的传输时延。 在数据传输阶段,设备收到测量指示器后,会根据所获取的时延信息,将数据发送至基站。为了提高传输效率和容量,5G引入了一种新的方式称为CPRACH(Contetion-based Physical Random Access Channel)。通过CPRACH,设备可以发送多个半持续信号。 在CPRACH过程中,设备首先进行功率等级控制,然后根据随机接入指示器(Random Access Indication)选择合适的重传间隔。设备会在相应的时间和频率资源上发送CPRACH,并等待基站的响应。 基站在收到CPRACH后,会进行接收处理,并使用随机接入响应(Random Access Response)回复设备。随机接入响应中包含了一个时间对齐命令(Timing Alignment Command),设备根据该命令进行时间对齐,并开始与基站正式通信。 以上就是NR PRACh信道和随机接入流程v2.0的简析。NR PRACh通过PREAMBLE和数据传输两个阶段实现设备对基站的随机接入,提高了传输效率和容量。该过程为5G网络的正常连接提供了基础。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值