Działania naprawcze

Na tej stronie opisano, jak radzić sobie z problemami z orzeczeniami dotyczącymi integralności.

Gdy zostanie przesłane żądanie tokena integralności, możesz wyświetlić użytkownikowi okno Google Play. Możesz wyświetlić okno dialogowe, jeśli wystąpi co najmniej 1 problem z osądem dotyczącym integralności. Okno z informacjami wyświetla się u góry aplikacji i zachęca użytkowników do rozwiązania problemu. Po zamknięciu okna możesz sprawdzić, czy problem został rozwiązany, wysyłając kolejną prośbę do interfejsu Integrity API.

Okna integralności

GET_LICENSED (kod typu 1)

Problem z oceną

Gdy appLicensingVerdict == "UNLICENSED". Oznacza to, że konto użytkownika nie ma licencji. Inaczej mówiąc: nie zainstalował ani nie kupił aplikacji z Google Play.

Działania naprawcze

Możesz wyświetlić okno GET_LICENSED, aby poprosić użytkownika o pobranie aplikacji z Google Play. Jeśli użytkownik zaakceptuje zaproszenie, jego konto otrzyma licencję (appLicensingVerdict == "LICENSED"). Aplikacja zostanie dodana do biblioteki Google Play użytkownika i będzie ona mogła dostarczać aktualizacje w Twoim imieniu.

Przykładowy UX

Okno GET_LICENSED w Google Play

CLOSE_UNKNOWN_ACCESS_RISK (kod typu 2)

Problem z oceną

Jeśli environmentDetails.appAccessRiskVerdict.appsDetected zawiera "UNKNOWN_CAPTURING" lub "UNKNOWN_CONTROLLING", oznacza to, że na urządzeniu są uruchomione nieznane aplikacje, które mogą rejestrować to, co widać na ekranie, lub kontrolować urządzenie.

Działania naprawcze

Możesz wyświetlić okno CLOSE_UNKNOWN_ACCESS_RISK, aby poprosić użytkownika o zamknięcie wszystkich nieznanych aplikacji, które mogą przechwytywać obraz z ekranu lub sterować urządzeniem. Jeśli użytkownik kliknie przycisk Close all, wszystkie takie aplikacje zostaną zamknięte.

Przykład UX

Okno z zapytaniem o zamknięcie nieznanego ryzyka dostępu

CLOSE_ALL_ACCESS_RISK (kod typu 3)

Problem z oceną

Jeśli environmentDetails.appAccessRiskVerdict.appsDetected zawiera "KNOWN_CAPTURING", "KNOWN_CONTROLLING", "UNKNOWN_CAPTURING" lub "UNKNOWN_CONTROLLING", oznacza to, że na urządzeniu działają aplikacje, które mogą rejestrować to, co widać na ekranie, lub kontrolować urządzenie.

Działania naprawcze

Możesz wyświetlić okno CLOSE_ALL_ACCESS_RISK, aby poprosić użytkownika o zamknięcie wszystkich aplikacji, które mogą rejestrować to, co widać na ekranie, lub kontrolować urządzenie. Jeśli użytkownik kliknie przycisk Close all, wszystkie takie aplikacje zostaną zamknięte na urządzeniu.

Przykładowy UX

Okno zamykania całego ryzyka dostępu

Prośba o okno integralności

Gdy klient żąda tokena integralności, możesz użyć metody oferowanej w StandardIntegrityToken (standardowy interfejs API) i IntegrityTokenResponse (klasyczny interfejs API):showDialog(Activity activity, int integrityDialogTypeCode).

Aby za pomocą interfejsu Play Integrity API wyświetlić okno GET_LICENSED:

  1. Poproś o token integralności z aplikacji i wyślij go na serwer. Możesz użyć żądania standardowego lub klasycznego.

    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); 

    Rodzimy użytkownik

    /// 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));
  2. Odszyfruj token integralności na serwerze i sprawdź pole appLicensingVerdict. Może to wyglądać mniej więcej tak:

    // Licensing issue
    {
      ...
      accountDetails: {
          appLicensingVerdict: "UNLICENSED"
      }
    }
  3. Jeśli token zawiera appLicensingVerdict: "UNLICENSED", odpowiedz na klienta aplikacji, prosząc o wyświetlenie okna licencjonowania:

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

    Rodzimy użytkownik

    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;
    }
  4. W aplikacji wywołaj funkcję showDialog, podając żądany kod pobrany z serwera:

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

    Rodzimy użytkownik

    // 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.
    }
  5. Okno dialogowe wyświetla się u góry podanej aktywności. Gdy użytkownik zamknie okno dialogowe, zadanie zostanie ukończone z kodem odpowiedzi.

  6. (Opcjonalnie) Poproś o nowy token, aby wyświetlić kolejne okna dialogowe. Jeśli wysyłasz standardowe żądania, musisz ponownie wstępnie zainicjować dostawcę tokenów, aby uzyskać nową opinię.