En esta página, se describe cómo abordar problemas relacionados con los veredictos de integridad.
Cuando se solicita un token de integridad, tienes la opción de mostrarle al usuario un diálogo de Google Play. Puedes mostrar el diálogo cuando haya uno o más problemas con el veredicto de integridad. El diálogo se muestra en la parte superior de la app y les pide a los usuarios que resuelvan la causa del problema. Una vez que se cierra el cuadro de diálogo, puedes verificar que el problema se haya solucionado con otra solicitud a la API de Integrity.
Diálogos de integridad
GET_LICENSED (código de tipo 1)
Problema con el veredicto
Cuando ocurre appLicensingVerdict == "UNLICENSED"
, significa que la cuenta de usuario no tiene licencia. En otras palabras, no instaló ni compró la app desde Google Play.
Solución
Puedes mostrar el diálogo GET_LICENSED
para solicitarle al usuario que descargue tu app desde Google Play. Si el usuario acepta, su cuenta obtiene una licencia (appLicensingVerdict == "LICENSED"
). La app se agrega a la biblioteca de Google Play del usuario, y Google Play puede entregar actualizaciones de la app en tu nombre.
UX de ejemplo
CLOSE_UNKNOWN_ACCESS_RISK (código de tipo 2)
Problema con el veredicto
Cuando environmentDetails.appAccessRiskVerdict.appsDetected
contiene "UNKNOWN_CAPTURING"
o "UNKNOWN_CONTROLLING"
, significa que hay apps desconocidas ejecutándose en el dispositivo que podrían estar capturando la pantalla o controlando el dispositivo.
Solución
Puedes mostrar el diálogo CLOSE_UNKNOWN_ACCESS_RISK
para solicitarle al usuario que cierre todas las apps desconocidas que podrían estar capturando la pantalla o controlando el dispositivo.
Si el usuario presiona el botón Close all
, se cerrarán todas esas apps.
UX de ejemplo
CLOSE_ALL_ACCESS_RISK (código de tipo 3)
Problema con el veredicto
Cuando environmentDetails.appAccessRiskVerdict.appsDetected
contiene cualquiera de "KNOWN_CAPTURING"
, "KNOWN_CONTROLLING"
,"UNKNOWN_CAPTURING"
o "UNKNOWN_CONTROLLING"
, significa que hay apps en ejecución en el dispositivo que podrían capturar la pantalla o controlar el dispositivo.
Solución
Puedes mostrar el diálogo CLOSE_ALL_ACCESS_RISK
para solicitarle al usuario que cierre todas las apps que podrían estar capturando la pantalla o controlando el dispositivo. Si el usuario presiona el botón Close all
, se cerrarán todas esas apps en el dispositivo.
UX de ejemplo
Cómo solicitar un diálogo de integridad
Cuando el cliente solicite un token de integridad, puedes usar el método que se ofrece en StandardIntegrityToken (API estándar) y en IntegrityTokenResponse (API clásica): showDialog(Activity activity, int integrityDialogTypeCode)
.
En los siguientes pasos, se describe cómo puedes usar la API de Play Integrity para mostrar el diálogo GET_LICENSED:
Solicita un token de integridad a tu app y envíalo a tu servidor. Puedes usar la solicitud estándar o clásica.
Kotlin
// Request an integrity token val tokenResponse: StandardIntegrityToken = requestIntegrityToken() // Send token to app server and get response on what to do next val yourServerResponse: YourServerResponse = sendToServer(tokenResponse.token())
Java
// Request an integrity token StandardIntegrityToken tokenResponse = requestIntegrityToken(); // Send token to app server and get response on what to do next YourServerResponse yourServerResponse = sendToServer(tokenResponse.token());
Unity
// Request an integrity token StandardIntegrityToken tokenResponse = RequestIntegrityToken(); // Send token to app server and get response on what to do next YourServerResponse yourServerResponse = sendToServer(tokenResponse.Token);
Nativo
/// Request an integrity token StandardIntegrityToken* response = requestIntegrityToken(); /// Send token to app server and get response on what to do next YourServerResponse yourServerResponse = sendToServer(StandardIntegrityToken_getToken(response));
En tu servidor, desencripta el token de integridad y verifica el campo
appLicensingVerdict
. Tal vez se vería así:// Licensing issue { ... accountDetails: { appLicensingVerdict: "UNLICENSED" } }
Si el token contiene
appLicensingVerdict: "UNLICENSED"
, responde al cliente de tu app y solicítale que muestre el diálogo de licencia:Kotlin
private fun getDialogTypeCode(integrityToken: String): Int{ // Get licensing verdict from decrypted and verified integritytoken val licensingVerdict: String = getLicensingVerdictFromDecryptedToken(integrityToken) return if (licensingVerdict == "UNLICENSED") { 1 // GET_LICENSED } else 0 }
Java
private int getDialogTypeCode(String integrityToken) { // Get licensing verdict from decrypted and verified integrityToken String licensingVerdict = getLicensingVerdictFromDecryptedToken(integrityToken); if (licensingVerdict.equals("UNLICENSED")) { return 1; // GET_LICENSED } return 0; }
Unity
private int GetDialogTypeCode(string IntegrityToken) { // Get licensing verdict from decrypted and verified integrityToken string licensingVerdict = GetLicensingVerdictFromDecryptedToken(IntegrityToken); if (licensingVerdict == "UNLICENSED") { return 1; // GET_LICENSED } return 0; }
Nativo
private int getDialogTypeCode(string integrity_token) { /// Get licensing verdict from decrypted and verified integrityToken string licensing_verdict = getLicensingVerdictFromDecryptedToken(integrity_token); if (licensing_verdict == "UNLICENSED") { return 1; // GET_LICENSED } return 0; }
En tu app, llama a
showDialog
con el código solicitado recuperado de tu servidor:Kotlin
// Show dialog as indicated by the server val showDialogType: Int? = yourServerResponse.integrityDialogTypeCode() if (showDialogType != null) { // Call showDialog with type code, the dialog will be shown on top of the // provided activity and complete when the dialog is closed. val integrityDialogResponseCode: Task<Int> = tokenResponse.showDialog(activity, showDialogType) // Handle response code, call the Integrity API again to confirm that // verdicts have been resolved. }
Java
// Show dialog as indicated by the server @Nullable Integer showDialogType = yourServerResponse.integrityDialogTypeCode(); if (showDialogType != null) { // Call showDialog with type code, the dialog will be shown on top of the // provided activity and complete when the dialog is closed. Task<Integer> integrityDialogResponseCode = tokenResponse.showDialog(activity, showDialogType); // Handle response code, call the Integrity API again to confirm that // verdicts have been resolved. }
Unity
IEnumerator ShowDialogCoroutine() { int showDialogType = yourServerResponse.IntegrityDialogTypeCode(); // Call showDialog with type code, the dialog will be shown on top of the // provided activity and complete when the dialog is closed. var showDialogTask = tokenResponse.ShowDialog(showDialogType); // Wait for PlayAsyncOperation to complete. yield return showDialogTask; // Handle response code, call the Integrity API again to confirm that // verdicts have been resolved. }
Nativo
// Show dialog as indicated by the server int show_dialog_type = yourServerResponse.integrityDialogTypeCode(); if (show_dialog_type != 0) { /// Call showDialog with type code, the dialog will be shown on top of the /// provided activity and complete when the dialog is closed. StandardIntegrityErrorCode error_code = IntegrityTokenResponse_showDialog(response, activity, show_dialog_type); /// Proceed to polling iff error_code == STANDARD_INTEGRITY_NO_ERROR if (error_code != STANDARD_INTEGRITY_NO_ERROR) { /// Remember to call the *_destroy() functions. return; } /// Use polling to wait for the async operation to complete. /// Note, the polling shouldn't block the thread where the IntegrityManager /// is running. IntegrityDialogResponseCode* response_code; error_code = StandardIntegrityToken_getDialogResponseCode(response, response_code); if (error_code != STANDARD_INTEGRITY_NO_ERROR) { /// Remember to call the *_destroy() functions. return; } /// Handle response code, call the Integrity API again to confirm that /// verdicts have been resolved. }
El diálogo se muestra en la parte superior de la actividad proporcionada. Cuando el usuario cierra el diálogo, la tarea se completa con un código de respuesta.
(Opcional) Solicita otro token para mostrar otros diálogos. Si realizas solicitudes estándar, debes volver a preparar el proveedor de tokens para obtener un veredicto nuevo.