SafetyNet Verify Apps API

SafetyNet Verify Apps API 可让您的应用以编程方式与设备上的验证应用功能进行互动,从而保护设备免受可能有害应用的危害。

如果您的应用会处理财务信息等敏感用户数据,您应确认当前设备是否得到妥善保护,不会遭到恶意应用的攻击,并且不存在假冒应用或执行其他恶意操作的应用。如果设备的安全性不符合最低安全状态,您可以在自己的应用中停用某些功能,降低用户面临的危险。

Google 一直致力于确保 Android 生态系统尽可能安全,因此,Google 会监控并分析 Android 应用的行为。如果验证应用功能检测到可能危险的应用,则会通知所有安装该应用的用户,并建议他们立即卸载该应用。此过程可保护这些用户的安全和隐私。

通过 SafetyNet Verify Apps API,您可以利用此功能来保护应用的数据。通过使用此 API,您可以确定用户的设备是否受到验证应用功能的保护,建议尚未使用该功能的用户选择启用该保护功能,并确定设备上是否安装了任何已知的可能有害应用。

注意:虽然 SafetyNet 会提醒用户存在可能有害的应用,但一些用户选择不卸载这些应用,或者没有看到警告通知。因此,即使启用了验证应用功能,设备也可能安装有可能有害的应用。

附加服务条款

访问或使用 SafetyNet API 即表示您同意 Google API 服务条款及这些附加条款。请先阅读并了解所有适用的条款及政策,然后再使用这些 API。

Verify Apps API 服务条款

对识别可能有害应用的分析可能会出现误报和漏报情况。我们会尽我们所知呈现此 API 套件返回的结果(或可能缺少结果)。您承认并理解,无法保证此 SafetyNet API 套件返回的结果始终准确无误。

启用应用验证

SafetyNet Verify Apps API 提供了两种方法来启用验证应用功能。您可以使用 isVerifyAppsEnabled() 确定是否已启用应用验证,也可以使用 enableVerifyApps() 请求启用应用验证。

这两种方法的不同之处在于:isVerifyAppsEnabled() 报告验证应用功能的当前状态,而 enableVerifyApps() 明确要求用户同意使用该功能。如果您希望自己的应用仅了解该功能的状态以做出以安全性为考量因素的决策,您的应用应该调用 isVerifyAppsEnabled()。不过,如果您希望确保自己的应用能够列出已安装的可能有害应用,则应改为调用 enableVerifyApps()

确定是否已启用应用验证

通过异步 isVerifyAppsEnabled() 方法,您的应用可以确定用户是否已启用验证应用功能。此方法会返回一个 VerifyAppsUserResult 对象,该对象包含用户采取的与验证应用功能相关的所有操作,包括他们是否已启用该功能。

以下代码段展示了如何创建与此方法关联的回调:

Kotlin

    SafetyNet.getClient(this)
            .isVerifyAppsEnabled
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    if (task.result.isVerifyAppsEnabled) {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is enabled.")
                    } else {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is disabled.")
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.")
                }
            }
    

Java

    SafetyNet.getClient(this)
        .isVerifyAppsEnabled()
        .addOnCompleteListener(new OnCompleteListener<VerifyAppsUserResponse>() {
            @Override
            public void onComplete(Task<VerifyAppsUserResponse> task) {
                if (task.isSuccessful()) {
                    VerifyAppsUserResponse result = task.getResult();
                    if (result.isVerifyAppsEnabled()) {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is enabled.");
                    } else {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is disabled.");
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.");
                }
            }
        });
    

请求启用应用验证

通过异步 enableVerifyApps() 方法,您的应用可以调用一个请求用户启用验证应用功能的对话框。此方法会返回一个 VerifyAppsUserResult 对象,该对象包含用户采取的与验证应用功能相关的所有操作,包括他们是否已同意启用该功能。

以下代码段展示了如何创建与此方法关联的回调:

Kotlin

    SafetyNet.getClient(this)
            .enableVerifyApps()
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    if (task.result.isVerifyAppsEnabled) {
                        Log.d("MY_APP_TAG", "The user gave consent to enable the Verify Apps feature.")
                    } else {
                        Log.d(
                                "MY_APP_TAG",
                                "The user didn't give consent to enable the Verify Apps feature."
                        )
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.")
                }
            }
    

Java

    SafetyNet.getClient(this)
        .enableVerifyApps()
        .addOnCompleteListener(new OnCompleteListener<VerifyAppsUserResponse>() {
            @Override
            public void onComplete(Task<VerifyAppsUserResponse> task) {
                if (task.isSuccessful()) {
                    VerifyAppsUserResponse result = task.getResult();
                    if (result.isVerifyAppsEnabled()) {
                        Log.d("MY_APP_TAG", "The user gave consent " +
                              "to enable the Verify Apps feature.");
                    } else {
                        Log.d("MY_APP_TAG", "The user didn't give consent " +
                              "to enable the Verify Apps feature.");
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.");
                }
            }
        });
    

在使用此方法时,您的应用可能会遇到一些临界情况:

  • 如果验证应用功能已启用,则系统不会显示该对话框,且 API 的行为就如同用户已同意启用该功能。
  • 如果用户转到该对话框以外的其他位置,则该对话框会被销毁,且 API 会假定用户未同意启用该功能。
  • 如果您的应用和其他应用同时调用此方法,系统将仅显示一个对话框,并且所有应用都会从此方法收到相同的返回值。

列出已安装的可能有害应用

通过异步 listHarmfulApps() 方法,您可以获取用户在其设备上安装的所有已知可能有害的应用列表。此列表包含已识别的可能有害应用的类别,以便您的应用能够采取适当措施。

以下代码段展示了如何创建与此方法关联的回调:

Kotlin

    SafetyNet.getClient(this)
            .listHarmfulApps()
            .addOnCompleteListener { task ->
                Log.d(TAG, "Received listHarmfulApps() result")

                if (task.isSuccessful) {
                    val result = task.result
                    val scanTimeMs = result.lastScanTimeMs

                    val appList = result.harmfulAppsList
                    if (appList?.isNotEmpty() == true) {
                        Log.e("MY_APP_TAG", "Potentially harmful apps are installed!")

                        for (harmfulApp in appList) {
                            Log.e("MY_APP_TAG", "Information about a harmful app:")
                            Log.e("MY_APP_TAG", "  APK: ${harmfulApp.apkPackageName}")
                            Log.e("MY_APP_TAG", "  SHA-256: ${harmfulApp.apkSha256}")

                            // Categories are defined in VerifyAppsConstants.
                            Log.e("MY_APP_TAG", "  Category: ${harmfulApp.apkCategory}")
                        }
                    } else {
                        Log.d("MY_APP_TAG", "There are no known potentially harmful apps installed.")
                    }
                } else {
                    Log.d(
                            "MY_APP_TAG",
                            "An error occurred. Call isVerifyAppsEnabled() to ensure that the user "
                                    + "has consented."
                    )
                }
            }
    

Java

    SafetyNet.getClient(this)
        .listHarmfulApps()
        .addOnCompleteListener(new OnCompleteListener<HarmfulAppsResponse>() {
            @Override
            public void onComplete(Task<HarmfulAppsResponse> task) {
                Log.d(TAG, "Received listHarmfulApps() result");

                if (task.isSuccessful()) {
                    HarmfulAppsResponse result = task.getResult();
                    long scanTimeMs = result.getLastScanTimeMs();

                    List<HarmfulAppsData> appList = result.getHarmfulAppsList();
                    if (appList.isEmpty()) {
                        Log.d("MY_APP_TAG", "There are no known " +
                              "potentially harmful apps installed.");
                    } else {
                        Log.e("MY_APP_TAG",
                              "Potentially harmful apps are installed!");

                        for (HarmfulAppsData harmfulApp : appList) {
                            Log.e("MY_APP_TAG", "Information about a harmful app:");
                            Log.e("MY_APP_TAG",
                                  "  APK: " + harmfulApp.apkPackageName);
                            Log.e("MY_APP_TAG",
                                  "  SHA-256: " + harmfulApp.apkSha256);

                            // Categories are defined in VerifyAppsConstants.
                            Log.e("MY_APP_TAG",
                                  "  Category: " + harmfulApp.apkCategory);
                        }
                    }
                } else {
                    Log.d("MY_APP_TAG", "An error occurred. " +
                          "Call isVerifyAppsEnabled() to ensure " +
                          "that the user has consented.");
                }
            }
        });