shouldShowRequestPermissionRationale in Android — cos'è, logica di visualizzazione e implementazione

Autore: IT Sectr Pubblicato: 2026-05-20 Tempo di lettura: 8 min

shouldShowRequestPermissionRationale è un metodo dell'API Android che indica allo sviluppatore se mostrare una spiegazione all'utente prima di richiedere un'autorizzazione pericolosa. Secondo il Riferimento per Sviluppatori Android, 2024, il metodo restituisce true se l'utente ha negato in precedenza la richiesta ma non ha impostato il flag Never Ask Again. Questo è uno strumento fondamentale per costruire un'UX rispettosa quando si lavora con le autorizzazioni runtime.

Punti Chiave

  • shouldShowRequestPermissionRationale — un metodo che determina se mostrare una spiegazione prima di richiedere un'autorizzazione.
  • Restituisce true dopo il primo rifiuto dell'utente se Never Ask Again non è attivato.
  • Restituisce false se l'autorizzazione non è mai stata richiesta, concessa o bloccata permanentemente.
  • Utilizzato per mostrare un dialogo personalizzato che spiega perché è necessaria un'autorizzazione specifica.
  • In caso di never ask again (false + denied), è necessario reindirizzare l'utente alle Impostazioni.

Cos'è shouldShowRequestPermissionRationale

shouldShowRequestPermissionRationale è un metodo delle classi Activity e Fragment in Android, disponibile tramite ActivityCompat per la compatibilità. Prende un nome di autorizzazione e restituisce un Boolean che indica se mostrare all'utente una spiegazione aggiuntiva prima di richiedere nuovamente. Il metodo è apparso in Android 6.0 Marshmallow insieme al modello di autorizzazioni runtime.

Il meccanismo di spiegazione si basa sul monitoraggio della cronologia delle interazioni dell'utente con i dialoghi delle autorizzazioni. Il sistema ricorda se l'utente ha negato la richiesta in precedenza. Se il rifiuto è avvenuto senza impostare il flag Never Ask Again, shouldShowRequestPermissionRationale restituisce true. Questo è un segnale per lo sviluppatore: l'utente non capisce perché l'autorizzazione è necessaria e serve una spiegazione aggiuntiva. Secondo le Linee Guida Material Design di Google, mostrare un dialogo di spiegazione dopo il primo rifiuto aumenta la probabilità di concedere nuovamente l'autorizzazione del 35 percento.

È importante comprendere la semantica dei valori restituiti: true significa che mostrare il dialogo ha senso, false significa che il dialogo non è necessario (l'autorizzazione è già stata concessa o non è mai stata richiesta) o è inutile (Never Ask Again attivo). Il metodo non è una garanzia che il dialogo verrà mostrato — fornisce solo una raccomandazione. Lo sviluppatore decide quale UI mostrare in risposta.

Quando è stato introdotto il metodo

shouldShowRequestPermissionRationale è stato introdotto al Livello API 23 insieme a un gruppo di metodi per le autorizzazioni runtime. Prima di Android 6.0, tutte le autorizzazioni venivano richieste all'installazione e non era necessario alcun meccanismo di spiegazione — l'utente accettava o rifiutava l'intero elenco in una volta. Il modello runtime ha reso possibile che un utente rifiutasse una richiesta senza comprendere il contesto, ed è proprio per questo che serve la spiegazione.

Come funziona shouldShowRequestPermissionRationale

La logica del metodo funziona come segue. Alla prima chiamata di requestPermissions per un'autorizzazione specifica, shouldShowRequestPermissionRationale restituisce false — l'utente non ha ancora incontrato il dialogo. Se l'utente rifiuta la richiesta (preme Nega), il metodo inizia a restituire true. Dopo un rifiuto ripetuto con il flag Never Ask Again, il metodo restituisce false.

Tabella completa degli stati:

StatoshouldShowRationalecheckSelfPermissionAzione dello sviluppatore
Non richiestofalseDENIEDMostra dialogo di sistema
ConcessofalseGRANTEDEsegui funzione
Rifiutato prima voltatrueDENIEDMostra spiegazione, poi dialogo di sistema
Never Ask AgainfalseDENIEDReindirizza a Impostazioni

La combinazione shouldShowRequestPermissionRationale = false e checkSelfPermission = DENIED è il caso più difficile da gestire. Significa che l'autorizzazione non è mai stata richiesta o che Never Ask Again è impostato. Lo sviluppatore deve distinguere questi due stati. L'unico modo è memorizzare un flag isFirstRequest in SharedPreferences o usando SavedStateHandle. Imposta il flag alla prima richiesta, e se shouldShowRationale restituisce false mentre il flag è già true — significa Never Ask Again.

Reimpostazione dello stato

shouldShowRequestPermissionRationale viene reimpostato se l'utente disinstalla e reinstalla l'app, cancella i dati dell'app o reimposta le impostazioni delle autorizzazioni. Dopo la reinstallazione, il metodo restituirà nuovamente false per la prima richiesta. Gli aggiornamenti di sistema e i cambi di versione di Android non reimpostano la cronologia — è memorizzata nei dati dell'app.

Implementazione del dialogo di spiegazione

Un'implementazione corretta della spiegazione include tre componenti: verificare shouldShowRequestPermissionRationale dopo il rifiuto, mostrare un dialogo personalizzato con una spiegazione e richiamare requestPermissions dopo una risposta positiva dell'utente. Il dialogo deve essere breve, specifico e spiegare perché l'app ha bisogno di questa particolare autorizzazione.

kotlin
private fun requestLocationWithRationale() {
    val permission = Manifest.permission.ACCESS_FINE_LOCATION

    when {
        ContextCompat.checkSelfPermission(
            this, permission
        ) == PackageManager.PERMISSION_GRANTED -> {
            startLocationTracking()
        }
        ActivityCompat.shouldShowRequestPermissionRationale(
            this, permission
        ) -> {
            showRationaleDialog(permission)
        }
        else -> {
            requestPermissionLauncher.launch(permission)
        }
    }
}

private fun showRationaleDialog(
    permission: String
) {
    AlertDialog.Builder(this)
        .setTitle("Perché è necessario l'accesso alla posizione")
        .setMessage(
            "L'app utilizza la posizione per segnare" +
            " luoghi sulla mappa. Senza questa autorizzazione," +
            " la funzione non funzionerà."
        )
        .setPositiveButton("Consenti") { _, _ ->
            requestPermissionLauncher.launch(permission)
        }
        .setNegativeButton("Annulla", null)
        .show()
}

Pattern UI per la spiegazione

Le buone pratiche di Material Design raccomandano di utilizzare un foglio inferiore o un banner in linea invece di un dialogo modale per la spiegazione. Un foglio inferiore è meno invadente e fornisce contesto all'utente. Un elemento in linea sullo schermo (ad esempio, una scheda con una spiegazione e un pulsante Consenti) mostra che la funzione non è disponibile senza l'autorizzazione, ma non blocca il resto dell'interfaccia.

Localizzazione della spiegazione

Il testo della spiegazione deve essere localizzato e adattato alla funzione specifica. Non utilizzare frasi generiche come “Questo è necessario per il funzionamento dell'app.” Specifica concretamente: “Per mostrare il meteo vicino a te” o “Per salvare le foto nella galleria.” Le spiegazioni specifiche aumentano la probabilità di concedere l'autorizzazione del 50 percento secondo la Ricerca UX di Google.

Spiegazione vs Never Ask Again

La differenza tra shouldShowRequestPermissionRationale = true (primo rifiuto) e false con DENIED (Never Ask Again) è un punto chiave nella gestione delle autorizzazioni. Nel primo caso, l'utente era indeciso e una spiegazione aggiuntiva può convincerlo a concedere l'accesso. Nel secondo, l'utente ha preso una decisione finale e ripetere il dialogo di sistema causerà solo irritazione.

L'algoritmo di gestione dopo il rifiuto dovrebbe essere il seguente:

  • Ottenere il risultato DENIED dal callback della richiesta
  • Chiamare shouldShowRequestPermissionRationale
  • Se true — mostrare un dialogo di spiegazione personalizzato con un pulsante Riprova
  • Se false — mostrare un dialogo con un pulsante Apri Impostazioni

È importante non confondere l'ordine: verificare prima shouldShowRequestPermissionRationale, non checkSelfPermission. checkSelfPermission restituirà comunque DENIED in entrambi i casi. Solo shouldShowRequestPermissionRationale distingue il primo rifiuto da Never Ask Again. Utilizza SavedStateHandle o SharedPreferences per memorizzare il flag “prima richiesta effettuata” — questo è l'unico modo affidabile per distinguere “non richiesto” da “bloccato.”

Buone pratiche per mostrare la spiegazione

Mostra la spiegazione solo una volta. Se l'utente rifiuta nuovamente la richiesta dopo aver visto la spiegazione, non mostrare più la spiegazione. Vai direttamente a offrire l'apertura delle Impostazioni. Mostrare la spiegazione ripetutamente viene percepito come fastidioso e abbassa la valutazione dell'app. Lo scenario ottimale: richiesta — rifiuto — spiegazione — nuova richiesta — rifiuto — Impostazioni.

Non mostrare la spiegazione prima della prima richiesta. Alcuni sviluppatori mostrano erroneamente una spiegazione prima del primo dialogo, sostenendo che “l'utente deve capire.” Questo peggiora l'UX: l'utente vede due dialoghi consecutivi invece di uno. Google raccomanda di mostrare il dialogo di sistema immediatamente e la spiegazione solo dopo il rifiuto.

Utilizza una spiegazione contestuale legata al momento in cui la funzione è effettivamente necessaria. Non richiedere tutte le autorizzazioni all'avvio dell'app — questo ha il tasso di concessione più basso. Richiedi la FOTOCAMERA quando l'utente tocca “Scatta foto” e la POSIZIONE quando apre la mappa. La richiesta contestuale combinata con la spiegazione aumenta le concessioni all'80 percento contro il 30 percento quando richiesta all'avvio.

Test degli scenari di spiegazione

Testare shouldShowRequestPermissionRationale richiede la verifica dei quattro stati della tabella: non richiesto, concesso, rifiutato, Never Ask Again. Nei test unitari, utilizza FakePermissionHandler con comportamento shouldShowRationale configurabile. Nei test di strumentazione, utilizza UiAutomator o Espresso con emulazione delle risposte dei dialoghi.

kotlin
class RationaleViewModelTest {

    private val handler = FakePermissionHandler()
    private val viewModel = PermissionsViewModel(handler)

    fun testFirstDenial_shouldShowRationale() {
        handler.shouldShowRationale = true
        handler.cameraResult =
            PermissionResult.DENIED(true)

        viewModel.onCameraRequested()

        assertEquals(
            PermissionUiState.Denied(true),
            viewModel.uiState.value
        )
    }

    fun testNeverAskAgain_redirectToSettings() {
        handler.shouldShowRationale = false
        handler.cameraResult =
            PermissionResult.DENIED(false)

        viewModel.onCameraRequested()

        assertEquals(
            PermissionUiState.RedirectToSettings,
            viewModel.uiState.value
        )
    }
}

Lo scenario principale per un test di strumentazione è verificare che il dialogo di spiegazione appaia effettivamente dopo il primo rifiuto. Utilizza Espresso con idling resources per attendere il dialogo di sistema, quindi premi Nega, verifica la comparsa del dialogo di spiegazione personalizzato e premi Consenti — verifica la concessione. UIAutomator consente di interagire con il dialogo di sistema tramite il testo del pulsante, rendendo il test più stabile.

Vale anche la pena testare lo scenario di rifiuto all'interno del dialogo di spiegazione. Se l'utente preme Nega nella spiegazione personalizzata, shouldShowRequestPermissionRationale dovrebbe restituire nuovamente true, poiché Never Ask Again non è ancora stato attivato. La buona pratica è reindirizzare alle Impostazioni dopo due rifiuti consecutivi per evitare di infastidire l'utente con spiegazioni ripetute e abbassare la valutazione dell'app.

Domande frequenti

Cosa restituisce shouldShowRequestPermissionRationale?

true — se la richiesta è stata precedentemente rifiutata e Never Ask Again non è impostato. false — se l'autorizzazione non è mai stata richiesta, concessa o bloccata permanentemente. La combinazione false + DENIED richiede la verifica tramite un flag aggiuntivo.

Quando mostrare il dialogo di spiegazione?

Mostra la spiegazione solo dopo il primo rifiuto dell'utente, quando shouldShowRequestPermissionRationale ha restituito true. Prima della prima richiesta, la spiegazione non è necessaria — peggiora l'UX e crea dialoghi inutili.

Come distinguere la prima richiesta da Never Ask Again?

Memorizza un flag isFirstRequest in SharedPreferences o SavedStateHandle. Se shouldShowRationale = false, checkSelfPermission = DENIED e il flag è true — Never Ask Again è attivo. Se il flag è false — è la prima richiesta.

Cosa fare in caso di Never Ask Again?

Mostra un dialogo con un pulsante “Apri Impostazioni” che reindirizza l'utente a ACTION_APPLICATION_DETAILS_SETTINGS. Non chiamare requestPermissions di nuovo — il dialogo non apparirà e il risultato arriverà come DENIED senza messaggio.

Come testare shouldShowRequestPermissionRationale?

Nei test unitari, utilizza FakePermissionHandler con un campo shouldShowRationale configurabile. Nei test di strumentazione, utilizza Espresso o UIAutomator con emulazione del dialogo di sistema. Verifica tutti i 4 stati della tabella.

Riepilogo

  • shouldShowRequestPermissionRationale — un metodo che determina se mostrare una spiegazione prima di richiedere un'autorizzazione.
  • Restituisce true dopo il primo rifiuto senza Never Ask Again, false negli altri tre casi.
  • La combinazione false + DENIED è lo scenario più difficile, che richiede un flag aggiuntivo per la distinzione.
  • Il dialogo di spiegazione viene mostrato solo dopo il rifiuto, non prima della prima richiesta.
  • Utilizza un foglio inferiore o un elemento in linea invece di un dialogo modale per una migliore UX.
  • Quando Never Ask Again è attivo — reindirizza alle Impostazioni tramite ACTION_APPLICATION_DETAILS_SETTINGS.
  • La spiegazione contestuale legata al momento dell'uso della funzione aumenta le concessioni all'80 percento.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche