Veredictos de integridad

En esta página, se describe cómo interpretar el resultado del veredicto de integridad y trabajar con él. Ya sea que realices una solicitud estándar o clásica a la API, el veredicto de integridad se devuelve en el mismo formato con contenido similar. El veredicto de integridad comunica información sobre la validez de los dispositivos, las apps y las cuentas. El servidor de tu app puede usar la carga útil resultante en un veredicto verificado y desencriptado para determinar la mejor manera de proceder con una acción o una solicitud particulares en tu app.

Formato del resultado del veredicto de integridad

La carga útil es un archivo JSON de texto sin formato y contiene indicadores de integridad junto con información que proporciona el desarrollador.

La estructura general de la carga útil es la siguiente:

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

Antes de verificar cada veredicto de integridad, debes comprobar que los valores del campo requestDetails coincidan con los de la solicitud original. En las siguientes secciones, se describe cada campo con mayor detalle.

Campo de detalles de la solicitud

El campo requestDetails contiene información sobre la solicitud, incluida la información proporcionada por el desarrollador en el requestHash de las solicitudes estándar y en el nonce de las solicitudes clásicas.

Para solicitudes estándar a la API:

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"
}

Estos valores deben coincidir con los de la solicitud original. Por lo tanto, verifica la parte requestDetails de la carga útil de JSON asegurándote de que requestPackageName y requestHash coincidan con lo que se envió en la solicitud original, como se muestra en el siguiente fragmento de código:

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.
        ...
}

Para solicitudes clásicas a la API:

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"
}

Estos valores deben coincidir con los de la solicitud original. Por lo tanto, verifica la parte requestDetails de la carga útil de JSON asegurándote de que requestPackageName y nonce coincidan con lo que se envió en la solicitud original, como se muestra en el siguiente fragmento de código:

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.
        ...
}

Campo de integridad de la aplicación

El campo appIntegrity contiene información relacionada con el paquete.

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 puede tener los siguientes valores:

PLAY_RECOGNIZED
La app y el certificado coinciden con las versiones que distribuye Google Play.
UNRECOGNIZED_VERSION
El certificado o el nombre del paquete no coinciden con los registros de Google Play.
UNEVALUATED
No se evaluó la integridad de la aplicación. Se omitió un requisito necesario, por ejemplo, el dispositivo no es lo suficientemente confiable.

Para asegurarte de que el token haya sido generado por una app creada por ti, verifica que la integridad de la aplicación sea la esperada, como se muestra en el siguiente fragmento de código:

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!
}

También puedes verificar el nombre del paquete de la app, su versión y los certificados de forma manual.

Campo de integridad del dispositivo

El campo deviceIntegrity puede contener un solo valor, deviceRecognitionVerdict, que tenga una o más etiquetas que representen la capacidad de un dispositivo para aplicar de manera forzosa la integridad de la app. Si un dispositivo no cumple con los criterios de ninguna etiqueta, el campo deviceIntegrity estará vacío.

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

De forma predeterminada, deviceRecognitionVerdict puede contener lo siguiente:

MEETS_DEVICE_INTEGRITY
La app se está ejecutando en un dispositivo con tecnología Android y los Servicios de Google Play. El dispositivo pasa las verificaciones de integridad del sistema y cumple con los requisitos de compatibilidad de Android.
Vacío (un valor en blanco)
La app se está ejecutando en un dispositivo que muestra indicios de ataque (como trampas de API) o de vulneración del sistema (como un dispositivo con permisos de administrador), o bien no se está ejecutando en un dispositivo físico (como un emulador que no pasa las verificaciones de integridad de Google Play).

Para asegurarte de que el token provenga de un dispositivo confiable, verifica que el deviceRecognitionVerdict sea el esperado, como se muestra en el siguiente fragmento de código:

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!
}

Si tienes problemas con la integridad del dispositivo de prueba, asegúrate de que la ROM de fábrica esté instalada (por ejemplo, puedes restablecer el dispositivo) y de que el bootloader esté bloqueado. También puedes crear pruebas de la API de Play Integrity en tu Play Console.

Etiquetas de dispositivos condicionales

Si tu app se lanza en Google Play Juegos para PC, el deviceRecognitionVerdict también puede contener la siguiente etiqueta:

MEETS_VIRTUAL_INTEGRITY
La app se está ejecutando en un dispositivo con tecnología Android y los Servicios de Google Play. El emulador pasa las verificaciones de integridad del sistema y cumple con los requisitos principales de compatibilidad de Android.

Información opcional del dispositivo

Si aceptas recibir etiquetas adicionales en el veredicto de integridad, deviceRecognitionVerdict puede tener las siguientes etiquetas adicionales:

MEETS_BASIC_INTEGRITY
La app se está ejecutando en un dispositivo que pasa las verificaciones básicas de integridad del sistema. Es posible que el dispositivo no cumpla con los requisitos de compatibilidad de Android y que no esté aprobado para ejecutar los Servicios de Google Play. Por ejemplo, es posible que el dispositivo esté ejecutando una versión no reconocida de Android o que tenga un bootloader desbloqueado, o que el fabricante no haya certificado el dispositivo.
MEETS_STRONG_INTEGRITY
La app se está ejecutando en un dispositivo Android con la tecnología de los Servicios de Google Play y tiene una garantía sólida de integridad del sistema, como una prueba de integridad de inicio con copia de seguridad en hardware. El dispositivo pasa las verificaciones de integridad del sistema y cumple con los requisitos de compatibilidad de Android.

Un solo dispositivo devolverá varias etiquetas de dispositivo en el veredicto de integridad del dispositivo si se cumple cada uno de los criterios de la etiqueta.

Actividad reciente del dispositivo

También puedes habilitar la actividad reciente del dispositivo, que te indica cuántas veces tu app solicitó un token de integridad en un dispositivo específico durante la última hora. Puedes usar la actividad reciente del dispositivo para proteger tu app de dispositivos hiperactivos inesperados que podrían indicar un ataque activo. Puedes decidir cuánto confiar en cada nivel reciente de la actividad del dispositivo según la cantidad de veces que esperas que tu app esté instalada en un dispositivo típico para solicitar un token de integridad cada hora.

Si aceptas recibir recentDeviceActivity, el campo deviceIntegrity tendrá dos valores:

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

Las definiciones de deviceActivityLevel difieren entre los modos y pueden tener uno de los siguientes valores:

Nivel de actividad reciente del dispositivo Solicitudes de tokens de integridad de la API estándar en este dispositivo en la última hora por app Solicitudes de tokens de integridad de la API clásica en este dispositivo en la última hora por app
LEVEL_1 (más bajo) 10 o menos 5 o menos
LEVEL_2 Entre 11 y 25 Entre 6 y 10
LEVEL_3 Entre 26 y 50 Entre 11 y 15
LEVEL_4 (más alto) Más de 50 Más de 15
UNEVALUATED No se evaluó la actividad reciente del dispositivo. Esto puede suceder por los siguientes motivos:
  • El dispositivo no es lo suficientemente confiable.
  • La versión de la app instalada en el dispositivo es desconocida para Google Play.
  • El dispositivo tiene problemas técnicos.

Atributos del dispositivo

También puedes habilitar los atributos del dispositivo, que le indican a la versión del SDK de Android el SO Android que se ejecuta en el dispositivo. En el futuro, es posible que se extienda con otros atributos del dispositivo.

El valor de la versión del SDK es el número de versión del SDK de Android definido en Build.VERSION_CODES. No se evalúa la versión del SDK si se omitió un requisito necesario. En este caso, no se configuró el campo sdkVersion, por lo que el campo deviceAttributes está vacío. Esto puede deberse a lo siguiente:

  • El dispositivo no es lo suficientemente confiable.
  • La versión de la app instalada en el dispositivo es desconocida para Google Play.
  • Hubo problemas técnicos en el dispositivo.

Si aceptas recibir deviceAttributes, el campo deviceIntegrity tendrá el siguiente campo adicional:

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

En caso de que no se evalúe la versión del SDK, el campo deviceAttributes se establecerá de la siguiente manera:

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

Campo de detalles de la cuenta

El campo accountDetails contiene un solo valor, appLicensingVerdict, que representa el estado de la licencia de Google Play de la app para la cuenta de usuario que accedió en el dispositivo. Si la cuenta de usuario tiene la licencia de Play para la app, significa que la descargó o compró en Google Play.

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

appLicensingVerdict puede tener uno de los siguientes valores:

LICENSED
El usuario tiene derechos de acceso a la app. En otras palabras, el usuario instaló o actualizó tu app desde Google Play en su dispositivo.
UNLICENSED
El usuario no tiene derechos de acceso a la app. Esto sucede, por ejemplo, cuando el usuario transfiere tu app desde una fuente desconocida o no la adquiere en Google Play. Para solucionar el problema, puedes mostrarles el diálogo GET_LICENSED a los usuarios.
UNEVALUATED

No se evaluó la información de las licencias porque se omitió un requisito necesario.

Estos son algunos de los diversos motivos por los que podría suceder:

  • El dispositivo no es lo suficientemente confiable.
  • La versión de tu app instalada en el dispositivo es desconocida para Google Play.
  • El usuario no accedió a Google Play.

Para verificar que el usuario tenga derechos de acceso a tu app, comprueba que el objeto appLicensingVerdict sea el esperado, como se muestra en el siguiente fragmento de código:

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!
}

Campo de detalles del entorno

También puedes habilitar indicadores adicionales sobre el entorno. El riesgo de acceso a la app le indica a tu app si hay otras apps en ejecución que se podrían usar para capturar la pantalla, mostrar superposiciones o controlar el dispositivo. El veredicto de Play Protect te indica si Google Play Protect está habilitado en el dispositivo y si encontró software malicioso conocido.

Si habilitaste el veredicto de riesgo de acceso a la app o el veredicto de Play Protect en Google Play Console, tu respuesta de la API incluirá el campo environmentDetails. El campo environmentDetails puede contener dos valores, appAccessRiskVerdict y playProtectVerdict.

Veredicto del riesgo de acceso a la app

Una vez habilitado, el campo environmentDetails de la carga útil de la API de Play Integrity contendrá el nuevo veredicto de riesgo de acceso de apps.

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

Si se evaluó el riesgo de acceso de apps, appAccessRiskVerdict contiene el campo appsDetected con una o más respuestas. Estas respuestas se dividen en uno de los siguientes dos grupos según la fuente de instalación de las apps detectadas:

  • Apps de Google Play o del sistema: Son las apps instaladas por Google Play o precargadas por el fabricante del dispositivo en la partición del sistema del dispositivo (identificadas con FLAG_SYSTEM). Las respuestas de estas apps tienen el prefijo KNOWN_.

  • Otras apps: Son las apps que no instaló Google Play. Esto excluye las apps precargadas en la partición del sistema por el fabricante del dispositivo. Las respuestas de estas apps llevan el prefijo UNKNOWN_.

Se pueden mostrar las siguientes respuestas:

KNOWN_INSTALLED, UNKNOWN_INSTALLED
Hay apps instaladas que coinciden con la fuente de instalación correspondiente.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
Hay apps en ejecución que tienen permisos habilitados que podrían usarse para ver la pantalla mientras tu app se está ejecutando. Esto excluye cualquier servicio de accesibilidad verificado conocido por Google Play que se ejecute en el dispositivo.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
Hay apps en ejecución que tienen permisos habilitados que se podrían usar para controlar el dispositivo y las entradas en tu app directamente, y para capturar entradas y salidas de tu app. Esto excluye cualquier servicio de accesibilidad verificado conocido por Google Play que se ejecute en el dispositivo.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
Hay apps en ejecución que tienen permisos habilitados que se podrían usar para mostrar superposiciones en tu app. Esto excluye cualquier servicio de accesibilidad verificado que Google Play conozca y que se ejecute en el dispositivo.
Vacío (un valor en blanco)

No se evalúa el riesgo de acceso de apps si se omitió un requisito necesario. En este caso, el campo appAccessRiskVerdict está vacío. Esto puede suceder por varios motivos, entre los que se incluyen los siguientes:

  • El dispositivo no es lo suficientemente confiable.
  • El factor de forma del dispositivo no es un teléfono, una tablet ni un dispositivo plegable.
  • El dispositivo no ejecuta Android 6 (nivel de API 23) o una versión posterior.
  • La versión de la app instalada en el dispositivo es desconocida para Google Play.
  • La versión de Google Play Store del dispositivo está desactualizada.
  • Solo juegos: La cuenta de usuario no tiene una licencia de Play para el juego.
  • Se usó una solicitud estándar con el parámetro verdictOptOut.
  • Se usó una solicitud estándar con una versión de la biblioteca de la API de Play Integrity que aún no admite el riesgo de acceso a la app para las solicitudes estándar.

El riesgo de acceso de apps excluye automáticamente los servicios de accesibilidad verificados que hayan pasado por una revisión de accesibilidad mejorada de Google Play (instalada por cualquier tienda de aplicaciones en el dispositivo). "Excluido" significa que los servicios de accesibilidad verificados que se ejecutan en el dispositivo no mostrarán una respuesta de captura, control ni superposición en el veredicto de riesgo de acceso de apps. Para solicitar una revisión de accesibilidad mejorada de Google Play para tu app de accesibilidad, publícala en Google Play y asegúrate de que la marca isAccessibilityTool esté establecida como verdadera en el manifiesto de tu app o solicita una revisión.

En la siguiente tabla, se proporcionan algunos ejemplos de veredictos y su significado (en esta tabla, no se enumeran todos los resultados posibles):

Ejemplo de respuesta de veredicto de riesgo de acceso de apps Interpretación
appsDetected:
["KNOWN_INSTALLED"]
Solo hay apps instaladas que Google Play reconoce o que fueron precargadas en la partición del sistema por el fabricante del dispositivo.
No hay apps en ejecución que generen veredictos sobre CAPTURAR, CONTROLAR o SUPERPOSICIONES.
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
Hay apps instaladas por Google Play o precargadas en la partición del sistema por el fabricante del dispositivo.
Hay otras apps en ejecución que tienen habilitados los permisos que se podrían usar para ver la pantalla o capturar otras entradas y salidas.
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
Hay apps de Play o del sistema en ejecución que tienen habilitados los permisos que se podrían usar para ver la pantalla o capturar otras entradas y salidas.
También hay otras apps en ejecución que tienen permisos habilitados que podrían usarse para controlar el dispositivo y controlar directamente las entradas de tu app.
appAccessRiskVerdict: {} No se evalúa el riesgo de acceso de apps porque se omitió un requisito necesario. Por ejemplo, el dispositivo no era lo suficientemente confiable.

Según tu nivel de riesgo, puedes decidir qué combinación de veredictos es aceptable para continuar y sobre qué veredictos deseas tomar medidas. En el siguiente fragmento de código, se muestra un ejemplo de verificación de que no hay apps en ejecución que puedan capturar la pantalla o controlar tu app:

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!
    }
}
Soluciona los veredictos de riesgo de acceso de apps

Según tu nivel de riesgo, puedes decidir sobre qué veredictos de riesgo de acceso de apps quieres tomar medidas antes de permitir que el usuario complete una solicitud o acción. Hay mensajes opcionales de Google Play que puedes mostrarle al usuario después de verificar el veredicto de riesgo de acceso de la app. Puedes mostrar CLOSE_UNKNOWN_ACCESS_RISK para solicitarle al usuario que cierre las apps desconocidas que generan el veredicto de riesgo de acceso a la app, o bien puedes mostrar CLOSE_ALL_ACCESS_RISK para solicitarle al usuario que cierre todas las apps (conocidas y desconocidas) que generan el veredicto de riesgo de acceso a la app.

Veredicto de Play Protect

Una vez habilitado, el campo environmentDetails de la carga útil de la API de Play Integrity contendrá el veredicto de Play Protect:

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict puede tener uno de los siguientes valores:

NO_ISSUES
Play Protect está activado y no detectó ningún problema con las apps del dispositivo.
NO_DATA
Play Protect está activado, pero aún no se realizó ningún análisis. Es posible que el dispositivo o la app de Play Store se hayan restablecido recientemente.
POSSIBLE_RISK
Play Protect está desactivado.
MEDIUM_RISK
Play Protect está activado y encontró apps potencialmente dañinas instaladas en el dispositivo.
HIGH_RISK
Play Protect está activado y encontró apps peligrosas instaladas en el dispositivo.
UNEVALUATED

No se evaluó el veredicto de Play Protect.

Estos son algunos de los diversos motivos por los que podría suceder:

  • El dispositivo no es lo suficientemente confiable.
  • Solo juegos: La cuenta de usuario no tiene una licencia de Play para el juego.

Guía para usar el veredicto de Play Protect

El servidor de backend de tu app puede decidir cómo actuar en función del veredicto según tu tolerancia al riesgo. A continuación, se incluyen algunas sugerencias y posibles acciones de los usuarios:

NO_ISSUES
Play Protect está activado y no detectó ningún problema, por lo que no se requiere ninguna acción por parte del usuario.
POSSIBLE_RISK y NO_DATA
Cuando recibas estos veredictos, pídele al usuario que compruebe si Play Protect está activado y si realizó un análisis. NO_DATA debe aparecer solo en circunstancias excepcionales.
MEDIUM_RISK y HIGH_RISK
Según tu tolerancia al riesgo, puedes pedirle al usuario que inicie Play Protect y realice acciones en las advertencias de Play Protect. Si el usuario no puede cumplir con estos requisitos, puedes bloquearlo de la acción del servidor.