SafetyNet Verify Apps API

SafetyNet Verification Apps API 是採用 Google Play 服務的程式庫,可讓應用程式以程式輔助方式與裝置上的驗證應用程式功能互動,保護裝置不受可能有害的應用程式侵擾。

如果您的應用程式會處理使用者的私密資料 (例如財務資訊),請務必確認使用者的裝置不受惡意應用程式侵擾,且裝置上沒有應用程式會冒用您的應用程式,或執行其他惡意動作。如果裝置的安全性未符合最低安全防護機制,您可以停用自家應用程式內的某些功能,降低使用者受到的風險。

Google 一直致力於盡可能維護 Android 生態系統的安全,因此會監控及剖析 Android 應用程式的行為。如果「驗證應用程式」功能偵測到可能有害的應用程式,系統會通知所有已安裝該應用程式的使用者,並建議所有人立即解除安裝。這項程序可以保護這些使用者的安全和隱私權。

SafetyNet Verification Apps API 可讓您利用這項功能保護應用程式資料。這個 API 可讓您判斷使用者的裝置是否受到「驗證應用程式」功能保護、鼓勵尚未使用此功能的使用者採用這項防護機制,還能找出裝置上已知的可能有害應用程式。

注意:雖然 SafetyNet 會請使用者留意可能有害的應用程式,但有些人可能不會看到警告通知,而有些人可能會選擇不解除安裝這類應用程式。因此,即使已啟用「驗證應用程式」功能,裝置仍可能會安裝可能有害的應用程式。

附加服務條款

存取或使用 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 Verification 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.");
            }
        }
    });