一、前提条件
·创建并获取云 API 密钥信息 SecretId 和 SecretKey,密钥信息获取请前往 API 密钥管理。
·已在 CLS 控制台获取移动端接入 Token,详见 获取密钥。
二、步骤1:引入依赖
在 build.gradle 中同时引入核心 SDK 和网络探测插件:
implementation(group: 'com.tencentcloudapi.cls', name: 'tencentcloud-cls-sdk-android', version: '3.0.1')implementation(group: 'com.tencentcloudapi.cls', name: 'cls-network-diagnosis-reporter-android', version: '3.0.1')
依赖包说明:
| 依赖包 | 说明 |
| tencentcloud-cls-sdk-android | 核心 SDK,负责将探测结果上报到 CLS |
| cls-network-diagnosis-reporter-android | 网络探测插件,提供 HTTP Ping、DNS、Ping、MTR、TCP Ping 等能力 |
三、步骤2:权限配置
在 AndroidManifest.xml 中添加:
<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" />
四、步骤3:网络安全配置(Android 9.0+)
Android 9.0(API 28)及以上默认禁止明文 HTTP 流量,需配置网络安全策略。
1. 在 res/xml/ 目录下创建 network_security_config.xml。
<?xml version="1.0" encoding="utf-8"?><network-security-config> <domain-config cleartextTrafficPermitted="true"> <!– 按需替换为实际的 CLS 域名 –> <domain includeSubdomains="true">ap-guangzhou.cls.tencentcs.com</domain> </domain-config></network-security-config>
2. 在 AndroidManifest.xml 的 <application> 标签中引用。
完整 AndroidManifest.xml 示例:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tencentcloudapi.cls"> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:networkSecurityConfig="@xml/network_security_config"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
五、步骤4:初始化与插件接入
在 Application.onCreate 或 Activity.onCreate 中完成初始化。
private void initCls(Context context) { // 1. 初始化核心 SDK ClsConfigOptions clsConfigOptions = new ClsConfigOptions( "https://ap-guangzhou-open.cls.tencentcs.com", "[日志主题 ID]", new Credential("[secret_id]", "[secret_key]")); clsConfigOptions.enableLog(true); clsConfigOptions.addTag("cls_android", "3.0.1"); ClsDataAPI.startWithConfigOptions(context, clsConfigOptions); // 2. 创建并配置网络探测插件 INetworkDiagnosisPlugin clsNetDiagnosisPlugin = new NetworkDiagnosisPlugin(); clsNetDiagnosisPlugin.addCustomField("env", "production"); // 可选:添加自定义字段 clsNetDiagnosisPlugin.setAppCredentialToken("[移动端接入 Token]"); // 从 CLS 控制台获取 // 3. 注册并启动插件 ClsDataAPI.sharedInstance(context) .addPlugin(clsNetDiagnosisPlugin) .startPlugin(context);}
INetworkDiagnosisPlugin 接口说明:
| 方法 | 说明 |
| addCustomField(String key, String value) | 添加自定义字段,随探测结果一起上报 |
| setAppCredentialToken(String token) | 设置移动端接入 Token |
六、步骤5:混淆配置
如果项目启用了 ProGuard 或 R8 混淆,在 proguard-rules.pro 中添加。
-keep class net.jpountz.lz4.** { *; }
七、网络探测 API
所有探测方法均通过 CLSNetworkDiagnosis.getInstance() 调用,探测结果会自动上报到 CLS。
八、HTTP Ping
检测目标 URL 的 HTTP 连通性、响应时间、证书等信息。
public void clsHttpPing(Context context) throws NoSuchAlgorithmException { INetworkDiagnosis.HttpRequest request = new INetworkDiagnosis.HttpRequest(); request.domain = "https://ap-guangzhou.cls.tencentcs.com"; // 必填:目标 URL request.ip = "1.2.3.4"; // 可选:指定目标 IP(绕过 DNS) request.headerOnly = true; // 可选:仅获取响应头(默认 false) request.downloadBytesLimit = 1024; // 可选:限制下载字节数(默认 64KB) request.timeout = 30 * 1000; // 可选:超时时间,单位毫秒(默认 30000ms) request.maxTimes = 3; // 可选:探测次数(默认 10) request.multiplePortsDetect = false; // 可选:是否多端口探测(默认 true) // 可选:SSL 证书校验配置 request.credential = new INetworkDiagnosis.HttpCredential(getSSLContext(context), null); // 可选:自定义扩展字段 request.extension = new HashMap<String, String>() {{ put("custom_field", "httpPing"); }}; // 不带回调 CLSNetworkDiagnosis.getInstance().http(request); // 带回调 CLSNetworkDiagnosis.getInstance().http(request, new INetworkDiagnosis.Callback() { @Override public void onComplete(INetworkDiagnosis.Response response) { CLSLog.i("HTTP", response.content); } });}
HttpRequest 参数说明:
HttpRequest 继承自 PingRequest,包含以下所有字段:
| 字段 | 类型 | 默认值 | 是否必填 | 说明 |
| domain | String | – | 必填 | 目标 URL,需包含协议头(http:// 或 https://) |
| ip | String | null | 可选 | 指定目标 IP,设置后跳过 DNS 解析直接连接 |
| headerOnly | boolean | false | 可选 | 是否只请求响应头 |
| downloadBytesLimit | int | 65536(64KB) | 可选 | 限制下载字节数,0表示不限制 |
| credential | HttpCredential | null | 可选 | SSL 证书校验配置,含 SSLContext 和 X509TrustManager |
| timeout | int | 30000(30秒) | 可选 | 请求超时时间,单位毫秒 |
| maxTimes | int | 10 | 可选 | 探测次数 |
| size | int(byte) | 64 | 可选 | 探测包大小 |
| multiplePortsDetect | boolean | true | 可选 | 是否启用多端口探测 |
| extension | Map<String, String> | null | 可选 | 自定义扩展字段,随结果一起上报 |
九、DNS 解析
检测目标域名的 DNS 解析耗时和结果。
public void clsDNSPing() { INetworkDiagnosis.DnsRequest request = new INetworkDiagnosis.DnsRequest(); request.domain = "ap-guangzhou-open.cls.tencentcs.com"; // 必填:目标域名 request.type = INetworkDiagnosis.DNS_TYPE_IPv4; // 可选:DNS 类型,"A"(IPv4)或 "AAAA"(IPv6),默认 "A" request.nameServer = "8.8.8.8"; // 可选:指定 DNS 服务器地址 request.timeout = 2000; // 可选:超时时间,单位毫秒(默认 2000ms) request.extension = new HashMap<String, String>() {{ put("custom_field", "dns"); }}; // 不带回调 CLSNetworkDiagnosis.getInstance().dns(request); // 带回调 CLSNetworkDiagnosis.getInstance().dns(request, new INetworkDiagnosis.Callback() { @Override public void onComplete(INetworkDiagnosis.Response response) { CLSLog.i("DNS", response.content); } });}
DnsRequest 参数说明:
DnsRequest 继承自 PingRequest,包含以下所有字段:
| 字段 | 类型 | 默认值 | 是否必填 | 说明 |
| domain | String | – | 必填 | 目标域名 |
| type | String | "A" | 可选 | DNS 查询类型:"A"(IPv4)或 "AAAA"(IPv6) |
| nameServer | String | null | 可选 | 指定 DNS 服务器地址,为空则使用系统默认 DNS |
| timeout | int | 2000 | 可选 | 查询超时时间,单位毫秒 |
| size | int(byte) | 64 | 可选 | 探测包大小 |
| multiplePortsDetect | boolean | true | 可选 | 是否启用多端口探测 |
| extension | Map<String, String> | null | 可选 | 自定义扩展字段 |
十、Ping(ICMP)
检测目标域名的 ICMP 连通性和延迟。
public void clsPing() { INetworkDiagnosis.PingRequest request = new INetworkDiagnosis.PingRequest(); request.domain = "ap-guangzhou-open.cls.tencentcs.com"; // 必填:目标域名 request.size = 64; // 可选:探测包大小,单位 byte(默认 64) request.maxTimes = 10; // 可选:探测次数(默认 10) request.timeout = 2000; // 可选:超时时间,单位毫秒(默认 2000ms) request.multiplePortsDetect = true; // 可选:是否多端口探测(默认 true) request.extension = new HashMap<String, String>() {{ put("custom_field", "ping"); }}; // 不带回调 CLSNetworkDiagnosis.getInstance().ping(request); // 带回调 CLSNetworkDiagnosis.getInstance().ping(request, new INetworkDiagnosis.Callback() { @Override public void onComplete(INetworkDiagnosis.Response response) { CLSLog.i("Ping", response.content); } });}
PingRequest 参数说明:
| 字段 | 类型 | 默认值 | 是否必填 | 说明 |
| domain | String | – | 必填 | 目标域名或 IP |
| size | int(byte) | 64 | 可选 | ICMP 探测包大小 |
| maxTimes | int | 10 | 可选 | 探测次数 |
| timeout | int | 2000 | 可选 | 单次探测超时时间,单位毫秒 |
| multiplePortsDetect | boolean | true | 可选 | 是否启用多端口探测 |
| extension | Map<String, String> | null | 可选 | 自定义扩展字段 |
十一、MTR(路由追踪)
追踪到目标域名的完整网络路径,支持 ICMP 和 UDP 协议。
public void clsMTR() { INetworkDiagnosis.MtrRequest request = new INetworkDiagnosis.MtrRequest(); request.domain = "ap-guangzhou-open.cls.tencentcs.com"; // 必填:目标域名 request.protocol = INetworkDiagnosis.MtrRequest.Protocol.ICMP; // 可选:探测协议(默认 ALL) request.maxTTL = 30; // 可选:最大跳数(默认 30) request.maxPaths = 1; // 可选:最大路径数(默认 1) request.maxTimes = 10; // 可选:每跳探测次数(默认 10) request.timeout = 2000; // 可选:超时时间,单位毫秒(默认 2000ms) request.multiplePortsDetect = true; // 可选:是否多端口探测(默认 true) request.extension = new HashMap<String, String>() {{ put("custom_field", "mtr"); }}; // 不带回调 CLSNetworkDiagnosis.getInstance().mtr(request); // 带回调 CLSNetworkDiagnosis.getInstance().mtr(request, new INetworkDiagnosis.Callback() { @Override public void onComplete(INetworkDiagnosis.Response response) { CLSLog.i("MTR", response.content); } });}
MtrRequest 参数说明:
MtrRequest 继承自 PingRequest,包含以下所有字段:
| 字段 | 类型 | 默认值 | 是否必填 | 说明 |
| domain | String | – | 必填 | 目标域名或 IP |
| protocol | Protocol | Protocol.ALL | 可选 | 探测协议:ALL(全部)、ICMP、UDP |
| maxTTL | int | 30 | 可选 | 最大路由跳数(TTL) |
| maxPaths | int | 1 | 可选 | 最大探测路径数 |
| maxTimes | int | 10 | 可选 | 每跳探测次数 |
| timeout | int | 2000 | 可选 | 单次探测超时时间,单位毫秒 |
| size | int(byte) | 64 | 可选 | 探测包大小 |
| multiplePortsDetect | boolean | true | 可选 | 是否启用多端口探测 |
| extension | Map<String, String> | null | 可选 | 自定义扩展字段 |
十二、TCP Ping
检测目标域名指定端口的 TCP 连通性和延迟。
public void clsTcpPing() { INetworkDiagnosis.TcpPingRequest request = new INetworkDiagnosis.TcpPingRequest(); request.domain = "ap-guangzhou-open.cls.tencentcs.com"; // 必填:目标域名 request.port = 80; // 必填:目标端口 request.payload = "hello"; // 可选:发送的探测数据 request.maxTimes = 10; // 可选:探测次数(默认 10) request.timeout = 2000; // 可选:超时时间,单位毫秒(默认 2000ms) request.size = 64; // 可选:探测包大小,单位 byte(默认 64) request.multiplePortsDetect = true; // 可选:是否多端口探测(默认 true) request.extension = new HashMap<String, String>() {{ put("custom_field", "tcpPing"); }}; // 不带回调 CLSNetworkDiagnosis.getInstance().tcpPing(request); // 带回调 CLSNetworkDiagnosis.getInstance().tcpPing(request, new INetworkDiagnosis.Callback() { @Override public void onComplete(INetworkDiagnosis.Response response) { CLSLog.i("TcpPing", response.content); } });}
TcpPingRequest 参数说明:
TcpPingRequest 继承自 PingRequest,包含以下所有字段:
| 字段 | 类型 | 默认值 | 是否必填 | 说明 |
| domain | String | – | 必填 | 目标域名或 IP |
| port | int | -1 | 必填 | 目标端口号 |
| payload | String | null | 可选 | 探测时发送的数据内容 |
| maxTimes | int | 10 | 可选 | 探测次数 |
| timeout | int | 2000 | 可选 | 单次探测超时时间,单位毫秒 |
| size | int(byte) | 64 | 可选 | 探测包大小 |
| multiplePortsDetect | boolean | true | 可选 | 是否启用多端口探测 |
| extension | Map<String, String> | null | 可选 | 自定义扩展字段 |