Integritätsergebnisse

Auf dieser Seite wird beschrieben, wie Sie das zurückgegebene Integritätsurteil interpretieren und damit arbeiten. Unabhängig davon, ob Sie eine Standard- oder eine klassische API-Anfrage stellen, wird das Integritätsurteil im selben Format mit ähnlichen Inhalten zurückgegeben. Das Integritätsergebnis enthält Informationen zur 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 vorgegangen werden soll.

Zurückgegebenes Format des Integritätsergebnisses

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

Die allgemeine Nutzlaststruktur sieht so aus:

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

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

Feld „Anfragedetails“

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

Für Standard-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 requested.
  "timestampMillis": "1675655009345"
}

Diese Werte sollten mit denen der ursprünglichen Anfrage übereinstimmen. Prüfen Sie daher den requestDetails-Teil der JSON-Nutzlast und achten Sie darauf, dass requestPackageName und requestHash mit den Werten übereinstimmen, die im ursprünglichen Antrag gesendet wurden, 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 mit denen der ursprünglichen Anfrage übereinstimmen. Prüfen Sie daher den requestDetails-Teil der JSON-Nutzlast und achten Sie darauf, dass requestPackageName und nonce mit den Werten in der ursprünglichen Anfrage übereinstimmen, 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 die 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 entsprechen den bei Google Play verfügbaren Versionen.
UNRECOGNIZED_VERSION
Das Zertifikat oder der Paketname stimmt nicht mit den Google Play-Datensätzen überein.
UNEVALUATED
Die App-Integrität wurde nicht bewertet. Eine erforderliche Voraussetzung wurde nicht erfüllt, z. B. dass das Gerät vertrauenswürdig genug sein muss.

Um sicherzustellen, dass der Token von einer von Ihnen erstellten App generiert wurde, prüfen Sie, ob die Anwendungsintegrität wie erwartet ist. Das folgende Code-Snippet zeigt, wie Sie das tun:

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 einen einzelnen Wert, deviceRecognitionVerdict, enthalten, der ein oder mehrere Labels hat, die angeben, wie gut ein Gerät die App-Integrität erzwingen kann. Wenn ein Gerät die Kriterien für keine Labels erfüllt, wird deviceRecognitionVerdict im Feld deviceIntegrity ausgelassen.

"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 echten und zertifizierten Android-Gerät ausgeführt. Unter Android 13 und höher gibt es einen hardwarebasierten Nachweis dafür, dass der Bootloader des Geräts gesperrt ist und das geladene Android-Betriebssystem ein zertifiziertes Image des Geräteherstellers ist.
Leer (leerer Wert)
Die App wird auf einem Gerät ausgeführt, das Anzeichen für Angriffe (z. B. API-Hooks) oder Systemmanipulationen (z. B. durch Rooting) aufweist oder die App wird nicht auf einem physischen Gerät ausgeführt (z. B. einem Emulator, der die Google Play-Integritätsprüfungen nicht besteht).

Um sicherzustellen, dass das Token von einem vertrauenswürdigen Gerät stammt, prüfen Sie, ob deviceRecognitionVerdict wie erwartet ist, wie im folgenden Code-Snippet gezeigt:

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 damit haben, dass Ihr Testgerät die Geräteintegrität erfüllt, achten Sie darauf, dass das werkseitige ROM installiert ist (z. B. durch Zurücksetzen des Geräts) und dass der Bootloader gesperrt ist. Sie können auch Play Integrity API-Tests in der Play Console erstellen.

Bedingte Geräte-Labels

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

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

Optionale Geräteinformationen und Geräterückruf

Wenn Sie zustimmen, dass Sie zusätzliche Labels im Integritätsergebnis erhalten, 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. Der Geräte-Bootloader kann gesperrt oder entsperrt sein und der Bootstatus kann verifiziert oder nicht verifiziert sein. Das Gerät ist möglicherweise nicht zertifiziert. In diesem Fall kann Google keine Zusicherungen in Bezug auf Sicherheit, Datenschutz oder App-Kompatibilität geben. Unter Android 13 und höher ist für das Ergebnis MEETS_BASIC_INTEGRITY nur erforderlich, dass der Vertrauensanker der Gerätebestätigung von Google bereitgestellt wird.
MEETS_STRONG_INTEGRITY
Die App wird auf einem echten und zertifizierten Android-Gerät mit einem aktuellen Sicherheitsupdate ausgeführt.
  • Unter Android 13 und höher erfordert das MEETS_STRONG_INTEGRITY-Urteil MEETS_DEVICE_INTEGRITY- und Sicherheitsupdates im letzten Jahr für alle Partitionen des Geräts, einschließlich eines Android-Betriebssystempartitions-Patches und eines Anbieterpartitions-Patches.
  • Bei Android 12 und niedriger ist für das Ergebnis MEETS_STRONG_INTEGRITY nur ein hardwaregestützter Nachweis der Boot-Integrität erforderlich. Das Gerät muss kein aktuelles Sicherheitsupdate haben. Daher wird empfohlen, bei der Verwendung von MEETS_STRONG_INTEGRITY auch die Android SDK-Version im Feld deviceAttributes zu berücksichtigen.

Ein einzelnes Gerät gibt mehrere Gerätelabels im Geräteintegritätsurteil zurück, wenn die Kriterien für jedes Label erfüllt sind.

Geräteattribute

Sie können auch Geräteattribute aktivieren, die die Android SDK-Version des auf dem Gerät ausgeführten Android-Betriebssystems angeben. In Zukunft wird es möglicherweise um weitere Geräteattribute erweitert.

Der SDK-Versionswert ist die Android SDK-Versionsnummer, die in Build.VERSION_CODES definiert ist. Die SDK-Version wird nicht geprüft, wenn eine erforderliche Voraussetzung nicht erfüllt wurde. In diesem Fall ist das Feld sdkVersion nicht festgelegt. Das Feld deviceAttributes ist also leer. Mögliche Gründe:

  • Das Gerät ist nicht vertrauenswürdig genug.
  • Auf dem Gerät sind technische Probleme aufgetreten.

Wenn Sie deviceAttributes aktivieren, enthält das Feld deviceIntegrity das folgende zusätzliche Feld:

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
  "deviceAttributes": {
    // 33 is one possible value, which represents Android 13 (Tiramisu).
    "sdkVersion": 33
  }
}

Wenn die SDK-Version nicht ausgewertet wird, wird das Feld deviceAttributes so festgelegt:

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
  "deviceAttributes": {}  // sdkVersion field is not set.
}

Letzte Geräteaktivitäten

Sie können auch die Funktion „Letzte Geräteaktivitäten“ aktivieren, um zu sehen, wie häufig Ihre App in der vergangenen Stunde ein Integritäts-Token auf einem bestimmten Gerät angefordert hat. Mithilfe dieser Informationen kannst du deine App vor einer Flut an unerwarteten Aktivitäten auf Geräten schützen, was auf einen aktiven Angriff hindeuten könnte. Sie können entscheiden, wie viel Vertrauen Sie in die einzelnen Stufen der letzten Geräteaktivitäten setzen, je nachdem, wie oft Ihre App auf einem typischen Gerät pro Stunde ein Integritäts-Token anfordern sollte.

Wenn Sie sich für den Empfang von recentDeviceActivity entscheiden, hat das Feld deviceIntegrity zwei Werte:

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

Die Definitionen für deviceActivityLevel unterscheiden sich je nach Modus und können einen der folgenden Werte haben:

Aktuelles Aktivitätslevel des Geräts Standardmäßige API-Integritäts-Token-Anfragen auf diesem Gerät in der letzten Stunde pro App Klassische API-Anfragen für Integritäts-Tokens auf diesem Gerät in der letzten Stunde pro App
LEVEL_1 (niedrigster) 10 oder weniger 5 oder weniger
LEVEL_2 Zwischen 11 und 25 Zwischen 6 und 10
LEVEL_3 Zwischen 26 und 50 Zwischen 11 und 15
LEVEL_4 (höchste) Mehr als 50 Mehr als 15
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 aktuell auf dem Gerät installierten App ist Google Play nicht bekannt.
  • Technische Probleme auf dem Gerät

Gerätewiedererkennung (Beta)

Sie können auch Geräte-Recall aktivieren. Damit können Sie benutzerdefinierte Daten für bestimmte Geräte speichern, die Sie zuverlässig abrufen können, wenn Ihre App später auf demselben Gerät neu installiert wird. Nachdem Sie ein Integritätstoken angefordert haben, führen Sie einen separaten Server-zu-Server-Aufruf aus, um die Werte für den Geräterückruf für ein bestimmtes Gerät zu ändern.

Wenn Sie deviceRecall aktivieren, enthält das Feld deviceIntegrity die Informationen zum Rückruf des Geräts, die Sie für das jeweilige Gerät festgelegt haben:

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
  "deviceRecall": {
    "values": {
      "bitFirst": true,
      "bitSecond": false,
      "bitThird": true
    },
    "writeDates": {
      // Write time in YYYYMM format in UTC.
      "yyyymmFirst": 202401,
      // Note that yyyymmSecond is not set because bitSecond is false.
      "yyyymmThird": 202310
    }
  }
}

deviceRecall ist in zwei Felder unterteilt:

  • values: Ruft die Bitwerte ab, die Sie zuvor für dieses Gerät festgelegt haben.
  • writeDates: Rufe die Bit-Schreibdaten in UTC auf, auf das Jahr und den Monat genau. Das Schreibdatum eines Recall-Bits wird jedes Mal aktualisiert, wenn das Bit auf true gesetzt wird. Es wird entfernt, wenn das Bit auf false gesetzt wird.

Wenn keine Informationen zum Geräterückruf verfügbar sind, ist der Wert für den Geräterückruf leer:

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
  "deviceRecall": {
    "values": {},
    "writeDates": {}
  }
}

Feld „Kontodetails“

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

"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. Der Nutzer hat Ihre App also bei Google Play auf seinem Gerät installiert oder aktualisiert.
UNLICENSED
Der Nutzer hat keine App-Berechtigung. Dies ist beispielsweise der Fall, wenn der Nutzer die App per Sideload oder nicht bei Google Play heruntergeladen hat. Sie können Nutzern das Dialogfeld GET_LICENSED anzeigen, um das Problem zu beheben.
UNEVALUATED

Lizenzierungsdetails wurden nicht geprüft, 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 aktuell auf dem Gerät installierten App ist Google Play nicht bekannt.
  • Der Nutzer ist nicht bei Google Play angemeldet.

Prüfen Sie, ob der Nutzer eine App-Berechtigung für Ihre App hat, indem Sie prüfen, ob appLicensingVerdict wie erwartet ist. Das folgende Code-Snippet zeigt, wie das geht:

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 „Umgebungsdetails“

Sie können auch zusätzliche Signale zur Umgebung aktivieren. Das Signal „Risiko von App-Zugriffen“ informiert Ihre App darüber, ob andere Apps ausgeführt werden, die den Bildschirm aufzeichnen, Overlays einblenden oder das Gerät steuern könnten. Im Play Protect-Ergebnis erfährst du, ob Google Play Protect auf dem Gerät aktiviert ist und ob bekannte Malware gefunden wurde.

Wenn Sie in der Google Play Console die Bewertung „App-Zugriffsrisiko“ oder „Play Protect“ aktiviert haben, enthält Ihre API-Antwort das Feld environmentDetails. Das Feld environmentDetails kann zwei Werte enthalten: appAccessRiskVerdict und playProtectVerdict.

Ergebnis zum Risiko von App-Zugriffen

Sobald das Signal aktiviert ist, enthält das Feld environmentDetails im Payload der Play Integrity API das neue Ergebnis zum Risiko von App-Zugriffen.

{
  "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. Diese Antworten fallen je nach Installationsquelle der erkannten Apps in eine der folgenden beiden Gruppen:

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

  • Andere Apps: Apps, die nicht über Google Play installiert wurden. Ausgenommen sind Apps, die vom Gerätehersteller auf der Systempartition vorinstalliert wurden. Antworten für solche Apps haben das Präfix UNKNOWN_.

Die folgenden Antworten können zurückgegeben werden:

KNOWN_INSTALLED, UNKNOWN_INSTALLED
Es sind Apps installiert, die der entsprechenden Installationsquelle entsprechen.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
Es werden Apps ausgeführt, für die Berechtigungen aktiviert sind, die verwendet werden könnten, um den Bildschirm zu sehen, während Ihre App ausgeführt wird. Ausgenommen sind alle bestätigten Bedienungshilfen, die auf dem Gerät ausgeführt werden und Google Play bekannt sind.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
Es werden Apps ausgeführt, für die Berechtigungen aktiviert sind, die verwendet werden könnten, um das Gerät zu steuern und Eingaben in Ihre App direkt zu steuern. Außerdem könnten sie verwendet werden, um Ein- und Ausgaben Ihrer App zu erfassen. Ausgenommen sind alle bestätigten Barrierefreiheitsdienste, die auf dem Gerät ausgeführt werden und Google Play bekannt sind.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
Es werden Apps ausgeführt, für die Berechtigungen aktiviert sind, die zum Anzeigen von Overlays in Ihrer App verwendet werden könnten. Ausgenommen sind alle bestätigten Barrierefreiheitsdienste, die auf dem Gerät ausgeführt werden und Google Play bekannt sind.
Leer (leerer Wert)

Das Risiko des App-Zugriffs wird nicht bewertet, wenn eine erforderliche Voraussetzung nicht erfüllt wurde. In diesem Fall ist das Feld appAccessRiskVerdict leer. Dafür kann es verschiedene Gründe geben:

  • Das Gerät ist nicht vertrauenswürdig genug.
  • Der Geräteformfaktor ist kein Smartphone, Tablet oder faltbares Gerät.
  • Auf dem Gerät ist nicht Android 6 (API-Level 23) oder höher installiert.
  • 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.
  • Das Nutzerkonto hat keine Play-Lizenz.
  • Es wurde eine Standardanfrage mit dem Parameter verdictOptOut verwendet.
  • Es wurde eine Standardanfrage mit einer Play Integrity API-Bibliotheksversion verwendet, die das Risiko von App-Zugriffen für Standardanfragen noch nicht unterstützt.

Durch das App-Zugriffsrisiko werden automatisch geprüfte Barrierefreiheitsdienste ausgeschlossen, die eine erweiterte Google Play-Überprüfung der Barrierefreiheit durchlaufen haben und über einen beliebigen App-Store auf dem Gerät installiert wurden. „Ausgeschlossen“ bedeutet, dass für geprüfte Barrierefreiheitsdienste, die auf dem Gerät ausgeführt werden, im Urteil zum App-Zugriffsrisiko keine Antwort für das Erfassen, Steuern oder für Overlays zurückgegeben wird. Wenn Sie eine erweiterte Google Play-Überprüfung der Barrierefreiheit für Ihre Barrierefreiheits-App beantragen möchten, veröffentlichen Sie sie bei Google Play und achten Sie darauf, dass in der Manifestdatei Ihrer App das Flag isAccessibilityTool auf „true“ gesetzt ist. Alternativ können Sie auch eine Überprüfung beantragen.

Beispiele für Ergebnisse zum Risiko des App-Zugriffs

In der folgenden Tabelle finden Sie einige Beispiele für Risikobewertungen für den App-Zugriff und deren Bedeutung (diese Tabelle enthält nicht alle möglichen Ergebnisse):

Beispiel für eine Antwort mit dem 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 wurden.
Es werden keine Apps ausgeführt, die zu den Ergebnissen „Aufzeichnen“, „Steuern“ oder „Overlays“ führen würden.
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
Es sind Apps installiert, die von Google Play stammen oder vom Gerätehersteller auf der Systempartition vorinstalliert wurden.
Es werden andere Apps ausgeführt, die Berechtigungen haben, mit denen der Bildschirm angezeigt oder andere Ein- und Ausgaben erfasst werden können.
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
Es werden Play- oder System-Apps ausgeführt, für die Berechtigungen aktiviert sind, die verwendet werden könnten, um den Bildschirm anzusehen oder andere Ein- und Ausgaben aufzuzeichnen.
 Es werden auch andere Apps ausgeführt, für die Berechtigungen aktiviert sind, die zum Steuern des Geräts und zum direkten Steuern von Eingaben in Ihrer App verwendet werden könnten.
appAccessRiskVerdict: {} Das Risiko des App-Zugriffs wird nicht bewertet, da eine erforderliche Voraussetzung nicht erfüllt wurde. Das Gerät war beispielsweise nicht vertrauenswürdig genug.

Je nach Risikostufe können Sie entscheiden, welche Kombination von Ergebnissen akzeptabel ist und bei welchen Ergebnissen Sie Maßnahmen ergreifen möchten. Das folgende Code-Snippet zeigt ein Beispiel dafür, wie Sie prüfen können, ob Apps ausgeführt werden, die den Bildschirm aufnehmen oder Ihre 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!
    }
}
Ergebnisse zum Risiko des App-Zugriffs beheben

Abhängig von Ihrem Risikograd können Sie entscheiden, auf welche Risikobewertungen für den App-Zugriff Sie reagieren möchten, bevor der Nutzer eine Anfrage oder Aktion abschließen kann. Es gibt optionale Google Play-Aufforderungen, die Sie dem Nutzer nach der Überprüfung des Risikos von App-Zugriffen anzeigen können. Sie können CLOSE_UNKNOWN_ACCESS_RISK anzeigen, um den Nutzer aufzufordern, unbekannte Apps zu schließen, die das Risiko von App-Zugriffen verursacht haben, oder CLOSE_ALL_ACCESS_RISK, um den Nutzer aufzufordern, alle Apps (bekannte und unbekannte) zu schließen, die das Risiko von App-Zugriffen verursacht haben.

Ergebnis zu Play Protect

Sobald das Signal aktiviert ist, enthält das Feld environmentDetails im Payload der Play Integrity API das Play Protect-Ergebnis:

"environmentDetails": {
  "playProtectVerdict": "NO_ISSUES"
}

playProtectVerdict kann einen der folgenden Werte haben:

NO_ISSUES
Play Protect ist aktiviert und hat keine App-Probleme auf dem Gerät gefunden.
NO_DATA
Play Protect ist aktiviert, es wurde aber 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 Play Protect-Ergebnis wurde nicht ausgewertet.

Dafür kann es verschiedene Gründe geben:

  • Das Gerät ist nicht vertrauenswürdig genug.
  • Das Nutzerkonto hat keine Play-Lizenz.

Hinweise zur Verwendung des Play Protect-Ergebnisses

Der Backend-Server Ihrer App kann basierend auf Ihrer Risikotoleranz entscheiden, wie er als Nächstes vorgehen soll. Hier einige Vorschläge und mögliche Nutzeraktionen:

NO_ISSUES
Play Protect ist aktiviert und hat keine Probleme gefunden. Sie müssen nichts weiter tun.
POSSIBLE_RISK und NO_DATA
Wenn Sie diese Ergebnisse erhalten, bitten Sie den Nutzer, zu prüfen, ob Play Protect aktiviert ist und ein Scan durchgeführt wurde. NO_DATA sollte nur in seltenen Fällen angezeigt werden.
MEDIUM_RISK und HIGH_RISK
Je nach Risikobereitschaft können Sie den Nutzer auffordern, 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 für die Serveraktion blockieren.