Android

集成要求

合规说明

请注意,在贵司的App中集成同盾提供的SDK产品时:

1.1 根据《网络安全法》《电信条例》《电信和互联网用户个人信息保护规定》等相关法律法规要求及监管实践中的标准,在贵司的最终用户首次启动App并在贵司开始采集信息之前,贵司应以交互界面或设计(如隐私政策弹窗等)向最终用户完整告知收集、使用、与第三方共享最终用户个人信息的目的、方式和范围,并征得最终用户的明示同意。

1.2 为向贵司提供业务安全和风控服务,同盾SDK将采集、处理、使用用户的手机终端唯一标志信息(IMEI/IDFA)、Android ID、OAID、IMSI、MEID、MAC 地址、SIM 卡序列号、设备序列号、设备类型、设备型号、系统类型、地理位置、登录 IP 地址等设备信息。为确保贵司使用相关服务的合规性,前述隐私政策应涵盖对同盾SDK提供服务并采集、处理、使用相关信息的授权,以下条款内容供贵司参考,具体表述可由贵司根据贵司隐私协议的整体框架和内容自行确定:

同盾SDK:为了业务安全和风控,我司使用了同盾 SDK,该 SDK 需要获取您的手机终端唯一标志信息(IMEI/IDFA)、Android ID、OAID、IMSI、MEID、MAC 地址、SIM卡序列号、设备序列号、设备类型、设备型号、系统类型、地理位置、登录 IP 地址、应用程序列表、运行中进程信息、传感器(光传感器、重力传感器、磁场传感器、加速度传感器、陀螺仪传感器、心率传感器)相关设备信息,用于设备欺诈风险识别。

同盾隐私协议:https://www.trustdecision.com/legal/privacy-policy

环境要求

条目说明
兼容版本支持主流机型,Android 5.0及以上系统
支持架构armeabi-v7a, arm64-v8a

集成步骤

集成SDK

添加仓库

首先, 请在项目根目录的 build.gradle加入maven库的配置

allprojects {
    repositories {
        ...
        mavenCentral()
    }
}

如果您的 Gradle 版本是 7 或更高版本,请将这些行添加到您的 settings.gradle

repositories {
        ...
        mavenCentral()
}

添加依赖

在项目的 app/build.gradle 中加上依赖,如图:

dependencies {
    // 设备安全组件
    implementation 'com.trustdecision.android:mobrisk:4.3.2.8'
    // 活体检测
    implementation 'com.trustdecision.android:liveness:2.2.3'
 }

如果遇到合规性问题,我们也可以在依赖阶段排除相关模块的采集,如下:

dependencies {
    // 设备安全组件
    implementation('com.trustdecision.android:mobrisk:4.3.2.8'){		
      	// 移除后sdk不获取安装包列表
        exclude group: 'com.trustdecision.android', module: 'packagelist'
        // 移除后sdk不会收集READ_PHONE_STATE相关信息
        exclude group: 'com.trustdecision.android', module: 'readphone'
        // 移除后sdk不会收集地理位置相关信息
        exclude group: 'com.trustdecision.android', module: 'location'
       	// 移除后sdk不会收集传感器相关信息
        exclude group: 'com.trustdecision.android', module: 'sensor'
      	// 移除后sdk不会收集wifi相关信息
        exclude group: 'com.trustdecision.android', module: 'wifiinfo'
    }
 }

ABI类型

SDK目前支持 armeabi-v7a、arm64-v8a 两种ABI类型,建议接入方在 app/build.gradle文件内添加 abiFilters配置选择所需要的架构类型,示例

defaultConfig {
    ........
    ndk {
        abiFilters 'armeabi-v7a', 'arm64-v8a'
    }
}

具体架构,请以您自己需要支持的架构为准!

配置AndroidManifest.xml

在应⽤module下的 AndroidManifest.xml ⽂件中声明以下权限

<manifest>
   <!--必选权限-->
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  <!--如果您的应用是面向海外市场,在google play 上发布,请添加此项-->
  <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

   <!--以下权限是可选权限,不声明此部分权限将放弃部分设备信息的采集,对风险识别有一定影响-->
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
   <uses-permission android:name="android.permission.READ_PHONE_STATE" />
   <!-- Android11及以上获取安装包列表需要该权限,采集安装包列表涉及到⻛险合规,是否需要该权限业务⽅⾃⾏选
择 -->
   <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
        tools:ignore="QueryAllPackagesPermission" />
</manifest>

权限说明

权限说明
INTERNET(必选)允许程序访问网络连接,发送请求与服务器进行通信
ACCESS_NETWORK_STATE(必选)获取网络连接状态信息
ACCESS_WIFI_STATE(必选)获取当前WiFi接入的状态以及WLAN热点的信息
AD_ID(海外必选)获取google 广告ID
ACCESS_COARSE_LOCATION获取粗略位置信息,精度大概误差在30~1500米
ACCESS_FINE_LOCATION获取精确位置信息,定位精度达10米以内
READ_PHONE_STATE读取SIM卡相关信息
QUERY_ALL_PACKAGES获取应用程序列表

SDK 的使用方法

注意事项

确保在用户同意隐私协议后,再进行SDK初始化,避免出现用户未同意隐私协议就进行SDK初始化采集,引发合规风险。

SDK配置

TD的sdk使用TDRisk.Builder方法对sdk初始参数进行配置设置,并将设置结果作为初始化参数提供给sdk初始化方法initWithOptions()使用。

TDRisk.Builder必须参数配置如下

配置 key定义说明示例代码
partnerCode合作方编码同盾的合作方编码,请联系同盾运营获取builder.partnerCode("partner")
partnerKey合作方Key同盾的合作方Key,请联系同盾运营获取builder.partnerKey("partnerKey")
appKey应用标识应用标识,参考如何申请appKeybuilder.appKey("appKey")
country国家地区TDRisk.COUNTRY_US 北美
TDRisk.COUNTRY_FRA 欧洲
TDRisk.COUNTRY_SG 新加坡
TDRisk.COUNTRY_IDNA 印尼
builder.country(TDRisk.COUNTRY_SG)

initWithOptions方法选传参数,详情见附表(初始化配置可选参数列表)

最佳实践

  1. 在应用入口Application的onCreate方法中调用初始化并异步获取blackBox
// 应用入口APPlication的onCreate
TDRisk.Builder builder = new TDRisk.Builder()
/*************************** 必传 ***************************/
.partnerCode("demo")        // 同盾的合作⽅编码,请填写⾃身的合作⽅编码
.partnerKey("key")          // 同盾平台注册的合作方Key
.appKey("appKey")           // 同盾平台注册的应用标识		 
.country(TDRisk.COUNTRY_CN); // 国家地区参数,列表可以参考下文全部配置说明
/*************************** 必传 ***************************/
if(⽤户同意隐私协议){
  TDRisk.initWithOptions(getApplicationContext(), builder);
  TDRisk.getBlackBox(new TDRiskCallback() {
  	@Override
  	public void onEvent(String blackbox) {
    	// 此处回调在新开辟的子线程
    	// ⽹络正常的情况下,会在1-2s内返回结果;⽹络异常的情况下,会在超时时间(默认最长15s)后返回
    	Log.i("TD", "init & get success");
  }
});
}
  1. 在实际业务节点同步获取blackBox
// 比如注册的时候
public void register() {
  ...
  String blackBox = TDRisk.getBlackBox();
  ...
}

状态检查

  1. 执行initWithOptions初始化成功会在 logcat中打印以下log:
TD_JAVA: Tongdun sdk load success
TD_JAVA: Tongdun sdk init success
  1. SDK上报数据成功,getBlackBox()返回的结果长度为26位字符串。如: rGPGX1678775227I9NCwcuVJCb。
  2. 异常情况下,getBlackBox()返回的结果长度可能达到5000字符,详情可查看正常blackBox和降级blackBox的差异

获取SDK版本号

示例代码

// 获取SDK版本号
TDRisk.getSDKVersion();

其他说明

混淆打包 如果开发者需要使用 proguard 进行混淆打包,请在 proguard 配置文件添加如下代码:

#trustdecision
-keep class com.trustdecision.**{*;}
-keep class cn.tongdun.**{*;}

活体检测功能模块

初始化配置可选参数列表

配置 key定义说明示例代码
livenessHttpTimeOutSDK网络超时时间配置(单位:毫秒)默认为10 * 1000msbuilder.livenessHttpTimeOut(10000)
language语言类型默认为手机系统语言
Options:
en 英语
zh-Hans 简体中文
zh-Hant 繁體中文
es 西班牙语
id 印尼语
ar 阿拉伯语
fil 菲律宾语
ko 韩语
pt 葡萄牙语
ru 俄语
th 泰语
tr 土耳其语
vi 越南语
builder.language("en")
playAudio是否播报语音默认为 false,不播报语音builder.playAudio(true)
showReadyPage启动人脸时,会弹出检测准备页面是否显示准备页面, 默认为 true, 即显示builder.showReadyPage(true)
faceMissingInterval没有检测到人脸时的超时时间无人脸超时时间, 单位ms 默认为 1000msbuilder.faceMissingInterval(1000)
prepareStageTimeout准备阶段超时时间准备阶段超时时间, 单位秒 默认为 0S, 即永远不超时builder.prepareStageTimeout(0)
actionStageTimeout动作阶段超时时间动作阶段超时时间, 单位秒 默认为 8Sbuilder.actionStageTimeout(8)

弹出活体检测

showLiveness方法

通过TDRisk.showLiveness 唤起 活体检测

TDShowLivenessCallback 是活体检测的回调接口,您需要自行实现以下接口:

示例代码

...
public void loginClick() {
  TDRisk.showLiveness(new TDRiskLivenessCallback() {
      @Override
      public void onSuccess(String result) {
        Log.d("TD","验证完成: " + result);
      }

      @Override
      public void onError(String errorCode, String errorMsg,String sequenceId) {
        Log.d("TD","验证失败!, 错误码:"+ errorCode + ", 错误内容:" + errorMsg + ", seqid" +sequenceId);
      }
  });
}

Result响应参数

字段类型含义备注
codeIntegerAPI状态码见下方状态码列表
messageString状态信息提示在 API 异常状态下会输出具体的异常原因
sequence_idString响应唯一码用于跟踪每次请求记录的唯一标识
imageString活体检测人脸图片活体检测过程中抓拍到的最佳人脸图片,base64格式
scoreDouble活体检测置信分预留字段,目前仅需要根据code字段结果判断是否通过活体检测(code=200代表真人通过)

Result示例

{
  "code": "200",
  "message": "success",
  "sequence_id": "1679299854228726325924",
  "image": "\/9j\/4AAQSkZJRgABAQAAAQABAAD\/2wBDAAMCA",
  "score": 0.98958
}

状态码

代码提示是否计费
200success 成功(真人通过)
20700No face detected 没有检测到人脸
20702Person change detected 检测到换人
20703Detection timeout 检测超时
20705Screen lock or background exit during detection 检测过程中锁屏或退出后台
20710No camera permission 没有相机权限
20711User actively cancels detection on the preparation page 准备页面用户主动取消检测
20712User actively cancels detection on the detection page 检测页面用户主动取消检测
20749Inconsistent action, tilt head down 动作不一致做出低头动作
60001Network issue, failed to retrieve session 网络问题,无法获取session
60002Network issue, failed to call anti-hack 网络问题,无法调用anti-hack
12202Identified as a blink attack 判断为抠眼攻击
12203Identified as a mouth movement attack 判断为抠嘴攻击
12204Identified as a partial face attack 判断为半张脸攻击
12205Identified as a video replay attack 判断为视频回放攻击
12206Identified as a black and white image 判断为黑白图片
12207Identified as a paper-based attack 判断为纸面攻击
12208Identified as a frame (including paper or phone frame) 判断为边框(包括纸面、手机等边框)
12209Identified as a moire pattern attack 判断为摩尔纹攻击
12210Identified as a face superiority attack 判断为脸优攻击
12211Identified as a paper-based attack (optical flow) 判断为纸面攻击(光流)
12212Identified as a mask attack 判断为面具攻击
12213Identified as an ID card attack 判断为证卡攻击
12214Identified as a 3D mask attack 判断为3D面具攻击
12215Identified as a synthetic image attack 判断为合成图像攻击
12216Identified as a black-market software attack 判断为黑产软件攻击
12217Identified as a T-type mask attack 判断为T型面具攻击
12218Identified as a blurry image 判断为模糊图片
12219Suspected deepfake image attack 疑似深伪图像攻击
12220Suspected high-resolution screen attack 疑似高清屏幕攻击
12222Injection attack 注入攻击
12250Verification error 其他活体攻击
11350Internal error 内部错误