Integritätsergebnisse

Auf dieser Seite wird beschrieben, wie Sie das zurückgegebene Integritätsergebnis interpretieren und damit arbeiten. Unabhängig davon, ob Sie eine Standard- oder klassische API-Anfrage stellen, wird das Integritätsergebnis im selben Format mit ähnlichem Inhalt zurückgegeben. Das Integritätsergebnis kommuniziert Informationen über die Gültigkeit von Geräten, Apps und Konten. Der Server Ihrer App kann die resultierende Nutzlast in einem entschlüsselten, bestätigten Ergebnis verwenden, um zu bestimmen, wie am besten mit einer bestimmten Aktion oder Anfrage in Ihrer App fortgefahren wird.

Format des zurückgegebenen Integritätsergebnisses

Die Nutzlast ist eine JSON-Datei im Nur-Text-Format und enthält neben den vom Entwickler bereitgestellten Informationen Integritätssignale.

Die allgemeine Nutzlaststruktur sieht so aus:

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: { ... }
}

Sie müssen zuerst prüfen, ob die Werte im Feld requestDetails mit denen der ursprünglichen Anfrage übereinstimmen, bevor Sie jedes Integritätsergebnis prüfen. In den folgenden Abschnitten werden die einzelnen Felder genauer beschrieben.

Feld mit Anfragedetails

Das Feld requestDetails enthält Informationen zur Anfrage, darunter vom Entwickler bereitgestellte Informationen in der requestHash für Standardanfragen und der nonce für klassische Anfragen.

Für standardmäßige API-Anfragen:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the request.
  requestPackageName: "com.package.name"
  // Request hash provided by the developer.
  requestHash: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the integrity token
  // was prepared (computed on the server).
  timestampMillis: "1675655009345"
}

Diese Werte sollten denen der ursprünglichen Anfrage entsprechen. Prüfen Sie daher den Teil requestDetails der JSON-Nutzlast. Dazu müssen requestPackageName und requestHash mit dem übereinstimmen, was in der ursprünglichen Anfrage gesendet wurde, wie im folgenden Code-Snippet gezeigt:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val requestHash = requestDetails.getString("requestHash")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

RequestDetails requestDetails =
    decodeIntegrityTokenResponse
    .getTokenPayloadExternal()
    .getRequestDetails();
String requestPackageName = requestDetails.getRequestPackageName();
String requestHash = requestDetails.getRequestHash();
long timestampMillis = requestDetails.getTimestampMillis();
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request.
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Für klassische API-Anfragen:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the
  // request.
  requestPackageName: "com.package.name"
  // base64-encoded URL-safe no-wrap nonce provided by the developer.
  nonce: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the request was made
  // (computed on the server).
  timestampMillis: "1617893780"
}

Diese Werte sollten denen der ursprünglichen Anfrage entsprechen. Prüfen Sie daher den Teil requestDetails der JSON-Nutzlast. Dazu müssen requestPackageName und nonce mit dem übereinstimmen, was in der ursprünglichen Anfrage gesendet wurde, wie im folgenden Code-Snippet gezeigt:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val nonce = requestDetails.getString("nonce")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

JSONObject requestDetails =
    new JSONObject(payload).getJSONObject("requestDetails");
String requestPackageName = requestDetails.getString("requestPackageName");
String nonce = requestDetails.getString("nonce");
long timestampMillis = requestDetails.getLong("timestampMillis");
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Feld für Anwendungsintegrität

Das Feld appIntegrity enthält paketbezogene Informationen.

appIntegrity: {
  // PLAY_RECOGNIZED, UNRECOGNIZED_VERSION, or UNEVALUATED.
  appRecognitionVerdict: "PLAY_RECOGNIZED"
  // The package name of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  packageName: "com.package.name"
  // The sha256 digest of app certificates (base64-encoded URL-safe).
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  certificateSha256Digest: ["6a6a1474b5cbbb2b1aa57e0bc3"]
  // The version of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  versionCode: "42"
}

appRecognitionVerdict kann die folgenden Werte haben:

PLAY_RECOGNIZED
Die App und das Zertifikat stimmen mit den bei Google Play vertriebenen Versionen überein.
UNRECOGNIZED_VERSION
Das Zertifikat oder der Paketname stimmt nicht mit den Google Play-Einträgen überein.
UNEVALUATED
Die Anwendungsintegrität wurde nicht bewertet. Eine erforderliche Voraussetzung wurde nicht erfüllt, z. B. dass das Gerät nicht vertrauenswürdig genug sein muss.

Prüfen Sie, ob die Anwendungsintegrität wie im folgenden Code-Snippet erwartet wird, damit das Token von einer von Ihnen erstellten Anwendung generiert wurde:

Kotlin

val appIntegrity = JSONObject(payload).getJSONObject("appIntegrity")
val appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict")

if (appRecognitionVerdict == "PLAY_RECOGNIZED") {
    // Looks good!
}

Java

JSONObject appIntegrity =
    new JSONObject(payload).getJSONObject("appIntegrity");
String appRecognitionVerdict =
    appIntegrity.getString("appRecognitionVerdict");

if (appRecognitionVerdict.equals("PLAY_RECOGNIZED")) {
    // Looks good!
}

Sie können den App-Paketnamen, die App-Version und die App-Zertifikate auch manuell prüfen.

Feld „Geräteintegrität“

Das Feld deviceIntegrity kann den einzelnen Wert deviceRecognitionVerdict mit einem oder mehreren Labels enthalten, die angeben, wie gut ein Gerät die App-Integrität erzwingen kann. Wenn ein Gerät die Kriterien von Labels nicht erfüllt, ist das Feld deviceIntegrity leer.

deviceIntegrity: {
  // "MEETS_DEVICE_INTEGRITY" is one of several possible values.
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
}

Standardmäßig kann deviceRecognitionVerdict Folgendes enthalten:

MEETS_DEVICE_INTEGRITY
Die App wird auf einem Android-Gerät mit Google Play-Diensten ausgeführt. Das Gerät besteht die Systemintegritätsprüfungen und erfüllt die Android-Kompatibilitätsanforderungen.
Leer (leerer Wert)
Die App wird auf einem Gerät ausgeführt, das Anzeichen von Angriffen (z. B. API-Hooks) oder Systemmanipulationen (z. B. Rooting) aufweist, oder sie wird nicht auf einem physischen Gerät ausgeführt (z. B. einem Emulator, der die Google Play-Integritätsprüfungen nicht besteht).

Prüfen Sie, ob deviceRecognitionVerdict wie erwartet funktioniert, wie im folgenden Code-Snippet gezeigt, damit das Token von einem vertrauenswürdigen Gerät stammt:

Kotlin

val deviceIntegrity =
    JSONObject(payload).getJSONObject("deviceIntegrity")
val deviceRecognitionVerdict =
    if (deviceIntegrity.has("deviceRecognitionVerdict")) {
        deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    } else {
        ""
    }

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

Java

JSONObject deviceIntegrity =
    new JSONObject(payload).getJSONObject("deviceIntegrity");
String deviceRecognitionVerdict =
    deviceIntegrity.has("deviceRecognitionVerdict")
    ? deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    : "";

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

Wenn Sie Probleme mit dem Testgerät haben, das die Geräteintegrität erfüllt, prüfen Sie, ob das Werkseinstellungen installiert ist (z. B. durch Zurücksetzen des Geräts) und der Bootloader gesperrt ist. Sie können auch Play Integrity API-Tests in Ihrer Play Console erstellen.

Bedingte Gerätelabels

Wenn deine App in Google Play Spiele für PC veröffentlicht wird, kann die deviceRecognitionVerdict auch das folgende Label enthalten:

MEETS_VIRTUAL_INTEGRITY
Die App wird in einem Android-Emulator mit Google Play-Diensten ausgeführt. Der Emulator besteht die Systemintegritätsprüfungen und erfüllt die grundlegenden Android-Kompatibilitätsanforderungen.

Optionale Geräteinformationen

Wenn Sie zusätzliche Labels für das Integritätsergebnis aktivieren, kann deviceRecognitionVerdict die folgenden zusätzlichen Labels enthalten:

MEETS_BASIC_INTEGRITY
Die App wird auf einem Gerät ausgeführt, das die grundlegenden Prüfungen zur Systemintegrität bestanden hat. Das Gerät erfüllt möglicherweise nicht die Kompatibilitätsanforderungen von Android und ist möglicherweise nicht für die Ausführung von Google Play-Diensten zugelassen. Es kann beispielsweise sein, dass auf dem Gerät eine unbekannte Version von Android ausgeführt wird, ein entsperrter Bootloader installiert ist oder es nicht vom Hersteller zertifiziert wurde.
MEETS_STRONG_INTEGRITY
Die App wird auf einem Android-Gerät mit Google Play-Diensten ausgeführt und bietet eine starke Garantie für die Systemintegrität, z. B. einen hardwaregestützten Proof of Boot-Integrität. Das Gerät besteht die Systemintegritätsprüfungen und erfüllt die Android-Kompatibilitätsanforderungen.

Für ein einzelnes Gerät werden im Geräteintegritätsergebnis mehrere Gerätelabels zurückgegeben, wenn jedes der Kriterien des Labels erfüllt ist.

Geräteaktivitäten in letzter Zeit (Beta)

Sie können auch die letzten Geräteaktivitäten aktivieren, um zu erfahren, wie oft Ihre App in der letzten Stunde ein Integritätstoken auf einem bestimmten Gerät angefordert hat. Sie können die letzte Geräteaktivität verwenden, um Ihre App vor unerwarteten, hyperaktiven Geräten zu schützen, die ein Hinweis auf einen aktiven Angriff sein könnten. Sie können entscheiden, wie oft jeder aktuellen Geräteaktivitätsstufe vertraut werden soll, je nachdem, wie oft Ihre App voraussichtlich auf einem typischen Gerät pro Stunde ein Integritätstoken anfordert.

Wenn Sie recentDeviceActivity erhalten, hat das Feld deviceIntegrity zwei Werte:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  recentDeviceActivity: {
    // "LEVEL_2" is one of several possible values.
    deviceActivityLevel: "LEVEL_2"
  }
}

Die deviceActivityLevel-Definitionen unterscheiden sich je nach Modi und können einen der folgenden Werte haben:

Aktivitätslevel des letzten Geräts Standardanfragen in der letzten Stunde Klassische Anfragen in der letzten Stunde
LEVEL_1 (niedrigste) Die App hat maximal 10 Integritätstokens auf diesem Gerät angefordert. Die App hat maximal fünf Integritätstokens auf diesem Gerät angefordert.
LEVEL_2 Die App hat zwischen 11 und 25 Integritätstokens auf diesem Gerät angefordert. Die App hat zwischen 6 und 15 Integritätstokens auf diesem Gerät angefordert.
LEVEL_3 Die App hat zwischen 26 und 50 Integritätstokens auf diesem Gerät angefordert. Die App hat zwischen 16 und 30 Integritätstokens auf diesem Gerät angefordert.
LEVEL_4 (höchste) Die App hat mehr als 50 Integritätstokens auf diesem Gerät angefordert. Die App hat mehr als 30 Integritätstokens auf diesem Gerät angefordert.
UNEVALUATED Die letzten Geräteaktivitäten wurden nicht ausgewertet. Das kann folgende Gründe haben:
  • Das Gerät ist nicht vertrauenswürdig genug.
  • Die Version der auf dem Gerät installierten App ist Google Play nicht bekannt.
  • Technische Probleme mit dem Gerät.

Feld für Kontodetails

Das Feld accountDetails enthält den einzelnen Wert appLicensingVerdict für den Google Play-Lizenzstatus der App für das Nutzerkonto, das auf dem Gerät angemeldet ist. Wenn das Nutzerkonto die Play-Lizenz für die App hat, wurde sie heruntergeladen oder bei Google Play gekauft.

accountDetails: {
  // This field can be LICENSED, UNLICENSED, or UNEVALUATED.
  appLicensingVerdict: "LICENSED"
}

appLicensingVerdict kann einen der folgenden Werte haben:

LICENSED
Der Nutzer hat eine App-Berechtigung. Mit anderen Worten: Der Nutzer hat deine App bei Google Play installiert oder gekauft.
UNLICENSED
Der Nutzer hat keine App-Berechtigung. Das ist beispielsweise der Fall, wenn der Nutzer deine App per Sideload oder nicht bei Google Play herunterlädt. Sie können Nutzern das Dialogfeld LIZENZ_LIZENZIEREN einblenden, um das Problem zu beheben.
UNEVALUATED

Lizenzierungsdetails wurden nicht ausgewertet, da eine erforderliche Voraussetzung nicht erfüllt wurde.

Dafür kann es verschiedene Gründe geben:

  • Das Gerät ist nicht vertrauenswürdig genug.
  • Die Version der auf dem Gerät installierten App ist Google Play nicht bekannt.
  • Der Nutzer ist nicht in Google Play angemeldet.

Wenn du prüfen möchtest, ob der Nutzer eine App-Berechtigung für deine App hat, prüfe, ob appLicensingVerdict wie erwartet ist, wie im folgenden Code-Snippet gezeigt:

Kotlin

val accountDetails = JSONObject(payload).getJSONObject("accountDetails")
val appLicensingVerdict = accountDetails.getString("appLicensingVerdict")

if (appLicensingVerdict == "LICENSED") {
    // Looks good!
}

Java

JSONObject accountDetails =
    new JSONObject(payload).getJSONObject("accountDetails");
String appLicensingVerdict = accountDetails.getString("appLicensingVerdict");

if (appLicensingVerdict.equals("LICENSED")) {
    // Looks good!
}

Feld für Umgebungsdetails

Sie können auch zusätzliche Signale zur Umgebung aktivieren. Das Risiko des App-Zugriffs teilt Ihrer App mit, ob andere Apps ausgeführt werden, die für die Bildschirmaufnahme, die Anzeige von Overlays oder die Steuerung des Geräts verwendet werden könnten. Das Play Protect-Ergebnis gibt an, ob Google Play Protect auf dem Gerät aktiviert ist und ob bekannte Malware gefunden wurde.

Wenn Sie sich für das Ergebnis „App-Zugriffsrisiko“ oder das Ergebnis „Play Protect“ in der Google Play Console angemeldet haben, enthält Ihre API-Antwort das Feld environmentDetails. Das Feld environmentDetails kann zwei Werte enthalten: appAccessRiskVerdict und playProtectVerdict.

Ergebnis zum Risiko des App-Zugriffs (Beta)

Nach der Aktivierung enthält das Feld environmentDetails in der Play Integrity API-Nutzlast das neue Ergebnis zum Risiko des Anwendungszugriffs.

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: {
      appAccessRiskVerdict: {
          // This field contains one or more responses, for example the following.
          appsDetected: ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"]
      }
 }
}

Wenn das Risiko des App-Zugriffs bewertet wurde, enthält appAccessRiskVerdict das Feld appsDetected mit einer oder mehreren Antworten. Je nach Installationsquelle der erkannten Apps fallen diese Antworten in eine der folgenden zwei Gruppen:

  • Play- oder System-Apps: Apps, die von Google Play installiert oder vom Gerätehersteller auf der Systempartition des Geräts vorab geladen werden (mit FLAG_SYSTEM gekennzeichnet). Antworten für solche Apps haben das Präfix KNOWN_.

  • Andere Apps: Apps, die nicht von Google Play installiert wurden. Dies schließt Apps aus, die vom Gerätehersteller auf der Systempartition vorab geladen wurden. Antworten für solche Anwendungen ist das Präfix UNKNOWN_ vorangestellt.

Die folgenden Antworten können zurückgegeben werden:

KNOWN_INSTALLED, UNKNOWN_INSTALLED
Es sind Apps installiert, die zur entsprechenden Installationsquelle passen.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
Es gibt aktive Apps, für die Berechtigungen aktiviert sind, mit denen während der Ausführung der App der Bildschirm angezeigt werden kann. Dies schließt alle bestätigten Bedienungshilfen aus, die Google Play bekannt sind und auf dem Gerät ausgeführt werden.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
Es gibt Apps mit aktivierten Berechtigungen, mit denen das Gerät und Eingaben in der App direkt gesteuert und die Ein- und Ausgaben Ihrer App erfasst werden können. Davon ausgenommen sind verifizierte Bedienungshilfen, die Google Play auf dem Gerät ausgeführt haben.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
Es gibt Apps, die ausgeführt werden, für die Berechtigungen aktiviert sind, mit denen Overlays in deiner App eingeblendet werden können. Dies schließt alle bestätigten Bedienungshilfen aus, die Google Play bekannt sind und auf dem Gerät ausgeführt werden.
EMPTY (leerer Wert)

Das Risiko des App-Zugriffs wird nicht bewertet, wenn eine erforderliche Anforderung nicht erfüllt wurde. In diesem Fall ist das Feld appAccessRiskVerdict leer. Dies kann unter anderem folgende Gründe haben:

  • Das Gerät ist nicht vertrauenswürdig genug.
  • Der Formfaktor eines Geräts ist kein Smartphone, Tablet oder faltbares Gerät.
  • Auf dem Gerät wird nicht Android 6 (API-Level 23) oder höher ausgeführt.
  • Die Version der aktuell auf dem Gerät installierten App ist Google Play nicht bekannt.
  • Die Version des Google Play Store auf dem Gerät ist veraltet.
  • Nur Spiele: Das Nutzerkonto hat keine Google Play-Lizenz für das Spiel.

Das Risiko des App-Zugriffs schließt verifizierte Bedienungshilfen aus, die einer erweiterten Prüfung von Google Play auf Bedienungshilfen unterzogen wurden und von einem beliebigen App-Shop auf dem Gerät installiert wurden. „Ausgeschlossen“ bedeutet, dass verifizierte Bedienungshilfen, die auf dem Gerät ausgeführt werden, im Ergebnis zum Risiko des App-Zugriffs keine Erfassung, Steuerung oder Overlays zurückgeben. Wenn du eine erweiterte Prüfung der Bedienungshilfen deiner App bei Google Play beantragen möchtest, musst du sie bei Google Play veröffentlichen. Achte dabei darauf, dass das Flag isAccessibilityTool im Manifest deiner App auf „true“ gesetzt ist, oder fordere eine Überprüfung an.

Die folgende Tabelle enthält einige Beispiele für Ergebnisse und ihre Bedeutung (in dieser Tabelle sind nicht alle möglichen Ergebnisse aufgeführt):

Beispiel für eine Antwort auf ein Ergebnis zum Risiko des App-Zugriffs Interpretation
appsDetected:
["KNOWN_INSTALLED"]
Es sind nur Apps installiert, die von Google Play erkannt oder vom Gerätehersteller auf der Systempartition vorinstalliert sind.
Es werden keine Apps ausgeführt, die zu einem Ergebnis der Erfassung, Steuerung oder Überlagerung führen würden.
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
Es gibt Apps, die von Google Play installiert oder vom Gerätehersteller auf der Systempartition vorinstalliert wurden.
Es werden noch andere Apps ausgeführt, für die Berechtigungen aktiviert sind, mit denen der Bildschirm aufgerufen oder andere Ein- und Ausgaben erfasst werden können.
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
Bei Google Play oder dem System, das ausgeführt wird, sind Berechtigungen aktiviert, mit denen sich der Bildschirm ansehen oder andere Ein- und Ausgaben erfassen können.
Es gibt auch andere ausgeführte Apps, bei denen Berechtigungen aktiviert sind, mit denen das Gerät und die Eingaben in deiner App direkt gesteuert werden können.
appAccessRiskVerdict: {} Das Risiko des App-Zugriffs wird nicht bewertet, da eine erforderliche Anforderung nicht erfüllt wurde. Zum Beispiel war das Gerät nicht vertrauenswürdig genug.

Abhängig von Ihrem Risikoniveau können Sie entscheiden, welche Kombination von Ergebnissen akzeptabel ist und für welche Ergebnisse Sie Maßnahmen ergreifen möchten. Das folgende Code-Snippet veranschaulicht anhand eines Beispiels, dass keine Apps ausgeführt werden, die den Bildschirm erfassen oder die App steuern könnten:

Kotlin

val environmentDetails =
    JSONObject(payload).getJSONObject("environmentDetails")
val appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict")

if (appAccessRiskVerdict.has("appsDetected")) {
    val appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}

Java

JSONObject environmentDetails =
    new JSONObject(payload).getJSONObject("environmentDetails");
JSONObject appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict");

if (appAccessRiskVerdict.has("appsDetected")) {
    String appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}

Ergebnis zu Play Protect

Nach der Aktivierung enthält das Feld environmentDetails in der Play Integrity API-Nutzlast das Play Protect-Ergebnis:

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict kann einen der folgenden Werte haben:

NO_ISSUES
Play Protect ist aktiviert und hat auf dem Gerät keine App-Probleme gefunden.
NO_DATA
Play Protect ist aktiviert, aber es wurde noch kein Scan durchgeführt. Das Gerät oder die Play Store App wurde möglicherweise vor Kurzem zurückgesetzt.
POSSIBLE_RISK
Play Protect ist deaktiviert.
MEDIUM_RISK
Play Protect ist aktiviert und hat potenziell schädliche Apps gefunden, die auf dem Gerät installiert sind.
HIGH_RISK
Play Protect ist aktiviert und hat gefährliche Apps gefunden, die auf dem Gerät installiert sind.
UNEVALUATED

Das Ergebnis von Play Protect wurde nicht bewertet.

Dafür kann es verschiedene Gründe geben:

  • Das Gerät ist nicht vertrauenswürdig genug.
  • Nur Spiele: Das Nutzerkonto hat keine Google Play-Lizenz für das Spiel.

Anleitung zur Verwendung des Play Protect-Ergebnisses

Der Back-End-Server Ihrer App kann auf Grundlage des Ergebnisses anhand Ihrer Risikotoleranz entscheiden, wie zu verfahren ist. Hier sind einige Vorschläge und mögliche Nutzeraktionen:

NO_ISSUES
Play Protect ist aktiviert und hat keine Probleme festgestellt, daher sind keine Nutzeraktionen erforderlich.
POSSIBLE_RISK und NO_DATA
Wenn der Nutzer diese Ergebnisse erhält, muss er prüfen, ob Play Protect aktiviert ist und einen Scan durchgeführt hat. NO_DATA sollte nur in seltenen Fällen angezeigt werden.
MEDIUM_RISK und HIGH_RISK
Je nach Risikotoleranz kannst du den Nutzer bitten, Play Protect zu starten und auf die Play Protect-Warnungen zu reagieren. Wenn der Nutzer diese Anforderungen nicht erfüllen kann, können Sie ihn von der Serveraktion blockieren.