### SmAntiFraud.getDeviceId - Get Device Identifier Source: https://context7.com/ishumei/fp-android/llms.txt Retrieves the encrypted device identifier (boxId or boxData). This method should be called during critical user events like login or registration and the identifier should be sent to your backend server. ```APIDOC ## SmAntiFraud.getDeviceId - Get Device Identifier ### Description Retrieves the encrypted device identifier (boxId or boxData). `boxId` is a short identifier returned by the server, while `boxData` is the locally generated encrypted data. It is recommended to call this method during critical business events (e.g., login, registration) and report the device identifier to your business server. Note: The first call might block the current thread while waiting for data collection to complete. ### Method `SmAntiFraud.getDeviceId()` ### Parameters None ### Request Example ```java import com.ishumei.smantifraud.SmAntiFraud; // It's recommended to call this in a background thread to avoid blocking the UI thread new Thread(() -> { String deviceId = SmAntiFraud.getDeviceId(); Log.d("SMSDK", "Device ID: " + deviceId); Log.d("SMSDK", "ID Length: " + deviceId.length()); // Use the deviceId in your network requests // sendRequestWithDeviceId(deviceId); }).start(); ``` ### Response #### Success Response (String) - **deviceId**: The encrypted device identifier. This can be either `boxId` (shorter) or `boxData` (longer, ~4000+ characters). #### Response Example ``` // Example boxId: D/SMSDK: Device ID: Bm21V93t5QwTNdwyQxxxxxRYuSnOuwwylqZvz8Lixxxxx17lRMqcQ1jz9RwN6qW31/Z0YYmxN8KQnrya9xxxxxx== D/SMSDK: ID Length: 88 // Example boxData (length will be significantly longer): D/SMSDK: Device ID: [long encrypted string...] D/SMSDK: ID Length: 4000+ ``` ``` -------------------------------- ### 配置 SmOption 私有化部署 Source: https://context7.com/ishumei/fp-android/llms.txt 用于将数美 SDK 配置为私有化部署模式。需要设置组织标识、应用 ID、公钥,并将 `area` 设置为组织标识,同时配置私有化服务器的 URL。 ```java import com.ishumei.smantifraud.SmAntiFraud; public class PrivateDeployment { public static void initWithPrivateServer(Context context) { SmAntiFraud.SmOption option = new SmAntiFraud.SmOption(); // 基础配置 option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLIC_KEY"); // 私有化配置:area 设置为组织标识 option.setArea("YOUR_ORGANIZATION"); // 配置私有化服务器地址 // 将 private-host 替换为实际的私有化服务器域名 String host = "https://fp.your-company.com"; option.setUrl(host + "/deviceprofile/v4"); option.setConfUrl(host + "/v3/cloudconf"); // 初始化 SDK boolean isOk = SmAntiFraud.create(context, option); if (isOk) { Log.d("SMSDK", "私有化部署初始化成功"); } else { Log.e("SMSDK", "私有化部署初始化失败"); } } } // 注意:如果使用 http 协议,需要在 AndroidManifest.xml 中配置: // android:usesCleartextTraffic="true" ``` -------------------------------- ### SmAntiFraud.create - SDK Initialization Source: https://context7.com/ishumei/fp-android/llms.txt Initializes the SmAntiFraud SDK with organization, app, and public key. This method should be called after user consent to privacy policy and before any data collection. ```APIDOC ## SmAntiFraud.create - SDK Initialization ### Description Initializes the SmAntiFraud SDK with organization, app, and public key. This method should be called after user consent to privacy policy and before any data collection. The initialization process runs on a background thread and typically takes about 1 second. ### Method `SmAntiFraud.create(Context context, SmOption option)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body `SmOption` object containing: - **organization** (String) - Required - Your organization identifier provided by 数美. - **appId** (String) - Required - Your application identifier. Use "default" if no specific ID is available. - **publicKey** (String) - Required - The public key content from the `android_public_key` attachment. ### Request Example ```java import com.ishumei.smantifraud.SmAntiFraud; // Inside your Application class or an appropriate context SmAntiFraud.SmOption option = new SmAntiFraud.SmOption(); option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLIC_KEY"); // option.usingShortBoxData(true); // Optional: Use short boxData for HTTP Header compatibility boolean isOk = SmAntiFraud.create(getApplicationContext(), option); if (isOk) { Log.d("SMSDK", "SDK Initialization successful"); } else { Log.e("SMSDK", "SDK Initialization failed. Check parameters."); } ``` ### Response #### Success Response (boolean) - **true**: Initialization successful. - **false**: Initialization failed. #### Response Example ``` // Log output for success: D/SMSDK: SDK Initialization successful ``` #### Error Handling If initialization fails, check the `logcat` for `Smlog` messages for detailed error information. ``` -------------------------------- ### Initialize FP-Android SDK Source: https://github.com/ishumei/fp-android/blob/main/README.md Initialize the SDK with organization, app, and public key. Ensure this is called after user consent to privacy policy. The SDK checks parameters and returns a boolean indicating success. Logcat 'Smlog' can be used for self-diagnosis if initialization fails. ```java SmAntiFraud.SmOption option = new SmAntiFraud.SmOption(); option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLICK_KEY"); boolean isOk = SmAntiFraud.create(context, option); ``` -------------------------------- ### 配置 SmOption 代理接入 Source: https://context7.com/ishumei/fp-android/llms.txt 用于将数美 SDK 配置为代理接入模式。需要设置组织标识、应用 ID、公钥,并配置代理服务器的 URL。 ```java import com.ishumei.smantifraud.SmAntiFraud; public class ProxyDeployment { public static void initWithProxy(Context context) { SmAntiFraud.SmOption option = new SmAntiFraud.SmOption(); // 基础配置 option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLIC_KEY"); // 代理服务器配置 // 将 proxy-host 替换为实际的代理服务器域名 String proxyHost = "https://proxy.your-company.com"; option.setUrl(proxyHost + "/deviceprofile/v4"); option.setConfUrl(proxyHost + "/v3/cloudconf"); // 初始化 SDK boolean isOk = SmAntiFraud.create(context, option); if (isOk) { Log.d("SMSDK", "代理模式初始化成功"); } else { Log.e("SMSDK", "代理模式初始化失败"); } } } // 代理服务器需要将以下路径转发至数美服务器: // /deviceprofile/v4 -> 数美设备指纹采集接口 // /v3/cloudconf -> 数美云配置接口 ``` -------------------------------- ### proguard-rules.pro 混淆配置 Source: https://context7.com/ishumei/fp-android/llms.txt 在 proguard-rules.pro 文件中添加数美 SDK 的防混淆规则,防止 SDK 类和方法被混淆。 ```proguard # proguard-rules.pro # 数美 SDK 防混淆规则 -keep class com.ishumei.** {*;} # 如果使用了其他数美产品,可能需要额外规则 # -keep class com.shumei.** {*;} ``` -------------------------------- ### 初始化 SmAntiFraud SDK Source: https://context7.com/ishumei/fp-android/llms.txt 使用 `SmAntiFraud.create` 方法初始化 SDK。必须在用户同意隐私政策后调用。配置组织标识、应用标识和公钥。初始化在子线程进行,耗时约 1 秒。 ```java import com.ishumei.smantifraud.SmAntiFraud; public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); // 检查是否已同意隐私政策 if (hasAgreedPrivacyPolicy()) { initSmSdk(); } } private void initSmSdk() { // 创建初始化参数对象 SmAntiFraud.SmOption option = new SmAntiFraud.SmOption(); // 必填:组织标识(由数美提供) option.setOrganization("YOUR_ORGANIZATION"); // 必填:应用标识(在数美后台应用管理查看,无合适值可填 "default") option.setAppId("YOUR_APP_ID"); // 必填:加密 KEY(邮件中 android_public_key 附件内容) option.setPublicKey("YOUR_PUBLIC_KEY"); // 可选:使用短 boxData(解决 HTTP Header 4K 限制问题) // option.usingShortBoxData(true); // 执行初始化 boolean isOk = SmAntiFraud.create(getApplicationContext(), option); if (isOk) { Log.d("SMSDK", "SDK 初始化成功"); } else { // 初始化失败,查看 logcat 中的 Smlog 日志进行排查 Log.e("SMSDK", "SDK 初始化失败,请检查参数配置"); } } } ``` -------------------------------- ### Configure SDK for Proxy Deployment Source: https://github.com/ishumei/fp-android/blob/main/README.md Provide the proxy server host URL for device profile and cloud configuration. Developers are responsible for setting up their own proxy server. ```java String host = "https://proxy-host"; option.setUrl(host + "/deviceprofile/v4"); option.setConfUrl(host + "/v3/cloudconf"); ``` -------------------------------- ### 配置 build.gradle 文件 Source: https://github.com/ishumei/fp-android/blob/main/README.md 在 Android Studio 项目的 build.gradle 文件中添加 smsdk 的 aar 引用和 ndk 配置。确保 abiFilters 包含实际需要的 CPU 架构。 ```groovy android { …… defaultConfig { …… ndk { // 选择实际需要的 cpu 架构 abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } } dependencies { implementation fileTree(dir: "libs", include: ["smsdk*.aar"]) ... } ``` -------------------------------- ### 使用 SmAntiFraud.isHook 检测 Hook/Magisk 状态 Source: https://context7.com/ishumei/fp-android/llms.txt 调用 `isHook()` 方法检测设备是否安装了 Magisk 等 Hook 框架。该方法通过检查 `/proc/self/mounts` 文件来判断。检测结果可用于综合风险评估。 ```java import com.ishumei.smantifraud.SmAntiFraud; public class SecurityCheckActivity extends AppCompatActivity { private TextView mInfoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mInfoView = findViewById(R.id.detect_info); } /** * 执行完整的安全检测 */ public void performFullSecurityCheck(View view) { SmAntiFraud smAntiFraud = new SmAntiFraud(); // 检测 Root 状态 boolean isRooted = smAntiFraud.isRoot(); // 检测 Hook/Magisk 状态 boolean isHooked = smAntiFraud.isHook(); // 显示检测结果 String result = String.format(Locale.US, "ROOT 检测: %s\n\nHOOK/Magisk 检测: %s", isRooted ? "已 Root" : "未 Root", isHooked ? "已安装" : "未检测到"); mInfoView.setText(result); // 综合风险评估 if (isRooted || isHooked) { Log.w("Security", "设备存在安全风险"); // 可以将风险信息上报到服务器进行风控决策 reportSecurityRisk(isRooted, isHooked); } } private void reportSecurityRisk(boolean isRoot, boolean isHook) { JSONObject riskInfo = new JSONObject(); try { riskInfo.put("isRoot", isRoot); riskInfo.put("isHook", isHook); riskInfo.put("deviceId", SmAntiFraud.getDeviceId()); // 上报到业务服务器 } catch (JSONException e) { e.printStackTrace(); } } } // 预期输出(正常设备): // ROOT 检测: 未 Root // HOOK/Magisk 检测: 未检测到 // 预期输出(风险设备): // ROOT 检测: 已 Root // HOOK/Magisk 检测: 已安装 ``` -------------------------------- ### 添加 smsdk 防混淆规则 Source: https://github.com/ishumei/fp-android/blob/main/README.md 在 proguard-rules.pro 文件中添加 smsdk 的防混淆规则,以防止 SDK 类被错误地移除或混淆。 ```sh -keep class com.ishumei.** {*;} ``` -------------------------------- ### 使用 SmAntiFraud.isRoot 检测设备 Root 状态 Source: https://context7.com/ishumei/fp-android/llms.txt 调用 `isRoot()` 方法检测设备是否已被 Root。该方法检查常见的 su 文件路径和 Magisk 相关路径。如果检测到 Root,会打印警告日志并可选择性地执行后续操作。 ```java import com.ishumei.smantifraud.SmAntiFraud; public class SecurityCheckActivity extends AppCompatActivity { private void performSecurityCheck() { SmAntiFraud smAntiFraud = new SmAntiFraud(); // 检测设备是否被 Root boolean isRooted = smAntiFraud.isRoot(); if (isRooted) { Log.w("Security", "警告: 检测到设备已 Root"); // 可以根据业务需求决定是否限制功能 showRootWarningDialog(); } else { Log.d("Security", "设备未 Root"); } } private void showRootWarningDialog() { new AlertDialog.Builder(this) .setTitle("安全警告") .setMessage("检测到您的设备已 Root,部分功能可能受限") .setPositiveButton("我知道了", null) .show(); } } // 预期输出(Root 设备): // W/Security: 警告: 检测到设备已 Root // 预期输出(正常设备): // D/Security: 设备未 Root ``` -------------------------------- ### 声明 AndroidManifest.xml 权限 Source: https://github.com/ishumei/fp-android/blob/main/README.md 在 AndroidManifest.xml 文件中声明 SDK 所需的权限。必选权限包括 INTERNET 和 ACCESS_NETWORK_STATE,强烈建议添加其他权限以提升数据采集精度。 ```xml ``` -------------------------------- ### Configure SDK for Overseas Deployment (Frankfurt) Source: https://github.com/ishumei/fp-android/blob/main/README.md Set the area to 'flkf' for users in Europe. Provide the specific host URLs for device profile and cloud configuration targeting the Frankfurt data center. ```java option.setArea("flkf"); String host = "http://api-device-eur.fengkongcloud.com"; option.setUrl(host + "/deviceprofile/v4"); option.setConfUrl(host + "/v3/cloudconf"); ``` -------------------------------- ### network_security_config.xml 网络安全配置 Source: https://context7.com/ishumei/fp-android/llms.txt 配置 res/xml/network_security_config.xml 文件,允许 SDK 的域名(如 fengkongcloud.com)明文流量传输,适用于 targetSdkVersion 大于 27 的应用。 ```xml fengkongcloud.com ``` -------------------------------- ### Configure SDK for Private Deployment Source: https://github.com/ishumei/fp-android/blob/main/README.md Set the area to your organization identifier and provide the private host URL for device profile and cloud configuration. Ensure the app can send HTTP requests if using http. ```java option.setArea("YOUR-ORGANIZATION"); String host = "https://private-host"; option.setUrl(host + "/deviceprofile/v4"); option.setConfUrl(host + "/v3/cloudconf"); ``` -------------------------------- ### 获取设备标识 (boxId/boxData) Source: https://context7.com/ishumei/fp-android/llms.txt 使用 `SmAntiFraud.getDeviceId` 获取设备的加密标识。建议在关键业务事件时调用,并将标识上报至业务服务器。首次调用可能阻塞当前线程。 ```java import com.ishumei.smantifraud.SmAntiFraud; public class LoginActivity extends AppCompatActivity { private void performLogin(String username, String password) { // 在子线程中获取设备标识,避免阻塞 UI 线程 new Thread(() -> { // 获取设备标识 String deviceId = SmAntiFraud.getDeviceId(); // deviceId 可能是 boxId(短)或 boxData(长) // 示例 boxId: Bm21V93t5QwTNdwyQxxxxxRYuSnOuwwylqZvz8Lixxxxx17lRMqcQ1jz9RwN6qW31/Z0YYmxN8KQnrya9xxxxxx== Log.d("SMSDK", "设备标识: " + deviceId); Log.d("SMSDK", "标识长度: " + deviceId.length()); // 将设备标识添加到登录请求中 runOnUiThread(() -> { sendLoginRequest(username, password, deviceId); }); }).start(); } private void sendLoginRequest(String username, String password, String deviceId) { // 构建登录请求,包含设备标识 JSONObject requestBody = new JSONObject(); try { requestBody.put("username", username); requestBody.put("password", password); requestBody.put("deviceId", deviceId); // 设备指纹标识 } catch (JSONException e) { e.printStackTrace(); } // 发送请求到业务服务器 // 业务服务器可使用 deviceId 调用数美 API 进行风险查询 } } ``` -------------------------------- ### Configure SDK for Overseas Deployment (Singapore) Source: https://github.com/ishumei/fp-android/blob/main/README.md Set the area to Singapore for users in Southeast Asia. Enable acceleration for global users by setting the area and providing specific host URLs for device profile and cloud configuration. ```java option.setArea(SmAntiFraud.AREA_XJP) // For global users: // option.setArea(SmAntiFraud.AREA_XJP); // String host = "http://fp-sa-it-acc.fengkongcloud.com"; // option.setUrl(host + "/deviceprofile/v4"); // option.setConfUrl(host + "/v3/cloudconf"); ``` -------------------------------- ### Enable Short BoxData Source: https://github.com/ishumei/fp-android/blob/main/README.md Optionally enable `usingShortBoxData` to reduce the length of boxData. This can help avoid issues with header size limits but may decrease security. ```java option.usingShortBoxData(true); ``` -------------------------------- ### AndroidManifest.xml 权限配置 Source: https://context7.com/ishumei/fp-android/llms.txt 在 AndroidManifest.xml 中声明 SDK 所需的权限,包括网络通信和可选的设备信息获取权限。 ```xml ``` -------------------------------- ### Configure SDK for Overseas Deployment (Virginia) Source: https://github.com/ishumei/fp-android/blob/main/README.md Set the area to Virginia for users in Europe and America. Enable acceleration for global users by setting the area and providing specific host URLs for device profile and cloud configuration. ```java option.setArea(SmAntiFraud.AREA_FJNY); // For global users: // option.setArea(SmAntiFraud.AREA_FJNY); // String host = "http://fp-na-it-acc.fengkongcloud.com"; // option.setUrl(host + "/deviceprofile/v4"); // option.setConfUrl(host + "/v3/cloudconf"); ``` -------------------------------- ### 配置 AndroidManifest.xml http 设置 Source: https://github.com/ishumei/fp-android/blob/main/README.md 当 targetSdkVersion 大于 27 时,需要在 AndroidManifest.xml 中添加 android:usesCleartextTraffic="true" 以允许 HTTP 请求。如果配置了 networkSecurityConfig,则需在配置文件中添加 smsdk 域名。 ```xml …… ``` ```xml …… ``` -------------------------------- ### Configure Overseas Server Regions - SmOption.setArea Source: https://context7.com/ishumei/fp-android/llms.txt Configures the SDK's server region for overseas scenarios, supporting North America (Virginia/Frankfurt) and Southeast Asia (Singapore). Requires the overseas SDK package and appropriate region selection based on user distribution. ```java import com.ishumei.smantifraud.SmAntiFraud; public class SmSdkConfig { /** * 欧美地区配置(弗吉尼亚机房) * 适用于用户主要分布在欧美地区 */ public static void configForNorthAmerica(SmAntiFraud.SmOption option) { option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLIC_KEY"); // 设置弗吉尼亚机房 option.setArea(SmAntiFraud.AREA_FJNY); // 如果用户分布范围为全球,需要开启加速功能 // option.setArea(SmAntiFraud.AREA_FJNY); // String host = "http://fp-na-it-acc.fengkongcloud.com"; // option.setUrl(host + "/deviceprofile/v4"); // option.setConfUrl(host + "/v3/cloudconf"); } /** * 欧洲地区配置(法兰克福机房) * 适用于用户主要分布在欧洲地区 */ public static void configForEurope(SmAntiFraud.SmOption option) { option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLIC_KEY"); // 设置法兰克福机房 option.setArea("flkf"); String host = "http://api-device-eur.fengkongcloud.com"; option.setUrl(host + "/deviceprofile/v4"); option.setConfUrl(host + "/v3/cloudconf"); } /** * 东南亚地区配置(新加坡机房) * 适用于用户主要分布在东南亚地区 */ public static void configForSoutheastAsia(SmAntiFraud.SmOption option) { option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLIC_KEY"); // 设置新加坡机房 option.setArea(SmAntiFraud.AREA_XJP); // 如果用户分布范围为全球,需要开启加速功能 // option.setArea(SmAntiFraud.AREA_XJP); // String host = "http://fp-sa-it-acc.fengkongcloud.com"; // option.setUrl(host + "/deviceprofile/v4"); // option.setConfUrl(host + "/v3/cloudconf"); } } ``` -------------------------------- ### 配置 networkSecurityConfig.xml Source: https://github.com/ishumei/fp-android/blob/main/README.md 如果 AndroidManifest.xml 中设置了 android:networkSecurityConfig,则需要在 xml/network_security_config.xml 文件中添加 smsdk 域名配置,允许明文流量通过。 ```xml fengkongcloud.com ``` -------------------------------- ### Configure Overseas Server Regions Source: https://context7.com/ishumei/fp-android/llms.txt Configures the SDK to connect to specific server regions for overseas business scenarios. Supports North America (Virginia/Frankfurt) and Southeast Asia (Singapore) data centers. Requires using the overseas-specific SDK package and selecting the appropriate region based on user distribution. ```APIDOC ## SmOption.setArea - 配置海外机房 ### Description Configures the server region for the SDK. This is essential for overseas operations, allowing connection to specific data centers in North America or Southeast Asia. ### Method `option.setArea(String area)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **option** (SmAntiFraud.SmOption) - The options object to configure. - **organization** (string) - Required - Your organization identifier. - **appId** (string) - Required - Your application ID. - **publicKey** (string) - Required - Your public key. - **area** (string) - Required - The server region to connect to. Use constants like `SmAntiFraud.AREA_FJNY` (Virginia), `"flkf"` (Frankfurt), or `SmAntiFraud.AREA_XJP` (Singapore). - **url** (string) - Optional - Custom endpoint URL. - **confUrl** (string) - Optional - Custom configuration URL. ### Request Example ```java // Example for North America (Virginia) SmAntiFraud.SmOption option = new SmAntiFraud.SmOption(); option.setOrganization("YOUR_ORGANIZATION"); option.setAppId("YOUR_APP_ID"); option.setPublicKey("YOUR_PUBLIC_KEY"); option.setArea(SmAntiFraud.AREA_FJNY); // Virginia data center // Example for Europe (Frankfurt) // option.setArea("flkf"); // String host = "http://api-device-eur.fengkongcloud.com"; // option.setUrl(host + "/deviceprofile/v4"); // option.setConfUrl(host + "/v3/cloudconf"); // Example for Southeast Asia (Singapore) // option.setArea(SmAntiFraud.AREA_XJP); // Singapore data center ``` ### Response This method configures the SDK and does not return a direct response. Configuration is applied internally. #### Success Response N/A #### Response Example N/A ### Error Handling Ensure that the correct SDK package for overseas use is integrated and that the `organization`, `appId`, and `publicKey` are correctly set. Incorrect region codes or missing configurations may lead to connection errors. ``` -------------------------------- ### Register Device ID Callback - SmAntiFraud.registerServerIdCallback Source: https://context7.com/ishumei/fp-android/llms.txt Asynchronously listens for device ID (boxId) acquisition results to avoid blocking the thread. Must be called before `create`. The callback is triggered when the server-assigned boxId is obtained. ```java import com.ishumei.smantifraud.SmAntiFraud; public class MyApplication extends Application { private String cachedDeviceId = null; @Override public void onCreate() { super.onCreate(); if (hasAgreedPrivacyPolicy()) { // 必须在 create 之前注册回调 SmAntiFraud.registerServerIdCallback(new SmAntiFraud.IServerSmidCallback() { @Override public void onSuccess(String boxId) { // 服务器下发成功或缓存中有可用 boxId // 如果缓存中存在 boxId,此方法会触发 2 次 // 第 2 次会更新缓存中的 boxId cachedDeviceId = boxId; Log.d("SMSDK", "获取设备标识成功: " + boxId); // 可以在此处通知其他模块设备标识已就绪 notifyDeviceIdReady(boxId); } @Override public void onError(int errCode) { // 错误码说明: // -1: 无网络(设备无网络连接) // -2: 网络异常(HTTP 状态非 200 或连接异常) // -3: 业务异常(服务器未返回 deviceId,可能是参数错误或 QPS 超限) Log.e("SMSDK", "获取设备标识失败,错误码: " + errCode); switch (errCode) { case -1: Log.e("SMSDK", "原因: 设备无网络"); break; case -2: Log.e("SMSDK", "原因: 网络异常或服务器配置错误"); break; case -3: Log.e("SMSDK", "原因: 参数配置错误或 QPS 超限"); break; } } }); // 注册回调后再进行初始化 initSmSdk(); } } public String getCachedDeviceId() { return cachedDeviceId; } } // 预期输出(成功时): // D/SMSDK: 获取设备标识成功: Bm21V93t5QwTNdwyQxxxxxRYuSnOuwwylqZvz8Lixxxxx... // 预期输出(失败时): // E/SMSDK: 获取设备标识失败,错误码: -1 // E/SMSDK: 原因: 设备无网络 ``` -------------------------------- ### 声明 smsdk 隔离进程服务 Source: https://github.com/ishumei/fp-android/blob/main/README.md 在 AndroidManifest.xml 的 application 节点中声明 smsdk 的隔离进程服务。此服务用于检测 Magisk 工具,注意 smsdk 3.3.0 之前版本不需要此配置。 ```xml ``` -------------------------------- ### Register Server ID Callback Source: https://context7.com/ishumei/fp-android/llms.txt Asynchronously listen for device ID (boxId) acquisition results to avoid blocking the thread during the initial call to getDeviceId. This method must be called before create, otherwise the callback might not be triggered. The callback is invoked when the server-assigned boxId is obtained. ```APIDOC ## SmAntiFraud.registerServerIdCallback - 注册设备标识回调 ### Description Registers a callback to asynchronously receive the device identifier (boxId). This is crucial for preventing thread blocking when `getDeviceId` is called for the first time. The callback must be registered before calling `create`. ### Method `SmAntiFraud.registerServerIdCallback(SmAntiFraud.IServerSmidCallback callback)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java SmAntiFraud.registerServerIdCallback(new SmAntiFraud.IServerSmidCallback() { @Override public void onSuccess(String boxId) { // Handle successful retrieval of boxId Log.d("SMSDK", "获取设备标识成功: " + boxId); } @Override public void onError(int errCode) { // Handle errors during boxId retrieval Log.e("SMSDK", "获取设备标识失败,错误码: " + errCode); } }); ``` ### Response #### Success Response - **boxId** (string) - The successfully obtained device identifier. #### Response Example ``` // Log output on success: D/SMSDK: 获取设备标识成功: Bm21V93t5QwTNdwyQxxxxxRYuSnOuwwylqZvz8Lixxxxx... ``` #### Error Response - **errCode** (int) - An error code indicating the reason for failure. - -1: No network connection. - -2: Network anomaly (non-200 HTTP status or connection error). - -3: Business anomaly (server did not return deviceId, possibly due to incorrect parameters or QPS limit). #### Response Example ``` // Log output on error: E/SMSDK: 获取设备标识失败,错误码: -1 E/SMSDK: 原因: 设备无网络 ``` ``` -------------------------------- ### Register Server ID Callback Source: https://github.com/ishumei/fp-android/blob/main/README.md Register a callback to receive the server-assigned device ID (boxId) or error codes. This method must be called before `create`. It handles scenarios where boxId is available in cache or needs to be fetched from the server. ```java SmAntiFraud.registerServerIdCallback(new SmAntiFraud.IServerSmidCallback() { @Override public void onSuccess(String boxId) { // Server assigned or cached boxId available } @Override public void onError(int errCode) { // Handle errors: -1 (No network), -2 (Network anomaly), -3 (Business error) } }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.