SafetyNet Verify Apps API

SafetyNet Verify Apps API 是一个由 Google Play 服务提供支持的库,可让您的应用以编程方式与设备上的验证应用功能进行交互,从而保护设备免受潜在有害应用的危害。

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

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

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

附加服务条款

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

Verify Apps API 服务条款

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

添加 SafetyNet API 依赖项

在使用 Verify Apps API 之前,请先将 SafetyNet API 添加到您的项目。如果您使用的是 Android Studio,请将此依赖项添加到您的应用级 Gradle 文件。如需了解详情,请参阅 SafetyNet API 设置

启用应用验证功能

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

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

确定是否已启用应用验证功能

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

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

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() 方法,您的应用可以调用一个请求用户启用“验证应用”功能的对话框。此方法会返回一个 VerifyAppsUserResponse 对象,该对象包含有关用户所执行与“验证应用”功能相关的所有操作的信息,包括他们是否已同意启用该功能。

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

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.");
            }
        }
    });