shouldShowRequestPermissionRationale în Android — ce este, logica de afișare și implementare

Autor: IT Sectr Publicat: 2026-05-20 Timp de citire: 8 min

shouldShowRequestPermissionRationale — este o metodă Android API care îi sugerează dezvoltatorului dacă trebuie să arate o explicație utilizatorului înainte de a solicita o permisiune periculoasă. Conform Android Developer Reference, 2024, metoda rational returnează true dacă utilizatorul a respins anterior cererea, dar nu a setat flag-ul Never Ask Again. Este un instrument cheie pentru construirea unui UX politicos atunci când lucrați cu permisiuni runtime.

Principalul

  • shouldShowRequestPermissionRationale — metodă care determină dacă trebuie arătată o explicație înainte de solicitarea permisiunii.
  • Returnează true după primul refuz al utilizatorului, dacă Never Ask Again nu este activat.
  • Returnează false dacă permisiunea nu a fost niciodată solicitată, a fost acordată sau blocată permanent.
  • Este utilizată pentru a afișa un dialog personalizat cu explicarea de ce este nevoie de permisiunea specifică.
  • În cazul never ask again (false + denied) este necesar să redirecționați utilizatorul la Setări.

Ce este shouldShowRequestPermissionRationale

shouldShowRequestPermissionRationale — este o metodă a claselor Activity și Fragment în Android, disponibilă prin ActivityCompat pentru compatibilitate. Primește numele permisiunii și returnează un Boolean care indică dacă trebuie arătată utilizatorului o explicație suplimentară înainte de o solicitare repetată. Metoda a apărut în Android 6.0 Marshmallow odată cu modelul de permisiuni runtime.

Mecanismul rationale este construit pe urmărirea istoricului interacțiunii utilizatorului cu dialogurile de permisiuni. Sistemul îți amintește dacă utilizatorul a respins cererea anterior. Dacă respingerea a avut loc fără setarea flag-ului Never Ask Again, shouldShowRequestPermissionRationale returnează true. Acesta este un semnal pentru dezvoltator: utilizatorul nu înțelege de ce este necesară permisiunea și este necesară o explicație suplimentară. Conform Google Material Design Guidelines, afișarea dialogului rationale după primul refuz crește probabilitatea acordării repetate a permisiunii cu 35 de procente.

Este important să înțelegeți semantica valorilor returnate: true înseamnă că are sens să afișați dialogul, false — dialogul fie nu este necesar (permisiunea este deja acordată sau nu a fost niciodată solicitată), fie este inutil (Never Ask Again este activ). Metoda nu este o garanție că dialogul va fi afișat — ea oferă doar o recomandare. Dezvoltatorul decide singur ce UI să arate ca răspuns.

Când a apărut metoda

shouldShowRequestPermissionRationale a fost introdus în API Level 23 împreună cu un grup de metode pentru permisiuni runtime. Înainte de Android 6.0, toate permisiunile erau solicitate la instalare și mecanismul de explicare nu era necesar — utilizatorul accepta sau respingea întreaga listă odată. Modelul runtime a făcut posibilă situația în care utilizatorul respinge cererea fără a înțelege contextul și exact de aceea este necesar rationale.

Cum funcționează shouldShowRequestPermissionRationale

Logica metodei este următoarea. La prima apelare a requestPermissions pentru o permisiune specifică, shouldShowRequestPermissionRationale returnează false — utilizatorul nu s-a confruntat încă cu dialogul. Dacă utilizatorul a respins cererea (a apăsat Deny), metoda începe să returneze true. După respingerea repetată cu flag-ul Never Ask Again, metoda returnează false.

Tabelul complet al stărilor:

StareshouldShowRationalecheckSelfPermissionAcțiunea dezvoltatorului
NesolicitatfalseDENIEDAfișați dialogul de sistem
AcordatfalseGRANTEDExecutați funcția
Respins prima datătrueDENIEDAfișați rationale, apoi dialogul de sistem
Never Ask AgainfalseDENIEDRedirecționați la Setări

Combinația shouldShowRequestPermissionRationale = false și checkSelfPermission = DENIED — este cel mai dificil caz de procesat. Însemnă că fie permisiunea nu a fost niciodată solicitată, fie Never Ask Again a fost setat. Dezvoltatorul trebuie să distingă aceste două stări. Singura modalitate — stocarea flag-ului firstRequest în SharedPreferences sau utilizarea SavedStateHandle. La prima solicitare setați flag-ul, iar dacă shouldShowRationale a returnat false iar flag-ul este deja true — înseamnă Never Ask Again.

Resetarea stării

shouldShowRequestPermissionRationale se resetează dacă utilizatorul șterge și reinstalează aplicația, șterge datele aplicației sau resetează setările de permisiuni. După reinstalare, metoda va returna din nou false pentru prima solicitare. Actualizările de sistem și schimbarea versiunii Android nu resetează istoricul — acesta este stocat în datele aplicației.

Implementarea dialogului rationale

Implementarea corectă a rationale include trei componente: verificarea shouldShowRequestPermissionRationale după refuz, afișarea unui dialog personalizat cu explicația și apelarea repetată a requestPermissions după răspunsul pozitiv al utilizatorului. Dialogul trebuie să fie concis, specific și să explice de ce aplicația are nevoie exact de această permisiune.

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("De ce este necesar accesul la geolocație")
        .setMessage(
            "Aplicația folosește geolocația pentru a marca" +
            " locurile pe hartă. Fără această permisiune" +
            " funcția nu va funcționa."
        )
        .setPositiveButton("Permite") { _, _ ->
            requestPermissionLauncher.launch(permission)
        }
        .setNegativeButton("Anulare", null)
        .show()
}

Pattern-uri UI pentru rationale

Cele mai bune practici Material Design recomandă utilizarea bottom sheet sau a bannerului inline în locul dialogului modal pentru rationale. Bottom sheet este mai puțin intruziv și oferă utilizatorului context. Elementul inline în ecran (de exemplu, o carte cu explicație și butonul Permite) arată că funcția nu este disponibilă fără permisiune, dar nu blochează restul interfeței.

Localizarea rationale

Textul rationale trebuie localizat și adaptat pentru funcția specifică. Nu utilizați fraze generice precum „Este necesar pentru funcționarea aplicației”. Indicați concret: „Pentru afișarea vremii din apropierea dvs.” sau „Pentru salvarea fotografiilor în galerie”. Conform Google UX Research, explicațiile concrete cresc probabilitatea acordării permisiunii cu 50 de procente.

Rationale vs Never Ask Again

Diferența dintre shouldShowRequestPermissionRationale = true (primul refuz) și false în cazul DENIED (Never Ask Again) — este punctul cheie în procesarea permisiunilor. În primul caz, utilizatorul a ezitat și o explicație suplimentară poate să-l convingă să acorde accesul. În al doilea — utilizatorul a luat o decizie finală și dialogul de sistem repetat va provoca doar iritare.

Algoritmul de procesare după refuz ar trebui să arate astfel:

  • Obțineți rezultatul DENIED din callback-ul cererii
  • Apelați shouldShowRequestPermissionRationale
  • Dacă true — afișați un dialog personalizat rationale cu butonul Repetare
  • Dacă false — afișați un dialog cu butonul Deschideți setările

Este important să nu confundați ordinea: mai întâi verificați shouldShowRequestPermissionRationale, nu checkSelfPermission. checkSelfPermission va returna oricum DENIED în ambele cazuri. Doar shouldShowRequestPermissionRationale distinge primul refuz de Never Ask Again. Utilizați SavedStateHandle sau SharedPreferences pentru stocarea flag-ului „prima cerere a fost” — aceasta este singura modalitate sigură de a distinge „nesolicitat” de „blocat”.

Cele mai bune practici pentru afișarea rationale

Afișați rationale doar o dată. Dacă utilizatorul a respins din nou cererea după rationale — nu mai afișați explicația. Treceți direct la propunerea de a deschide setările. Afișarea repetată a rationale este percepută ca intruzivă și scade ratingul aplicației. Scenariul optim: cerere — refuz — rationale — cerere repetată — refuz — Setări.

Nu afișați rationale înainte de prima cerere. Unii dezvoltatori afișează din greșeală explicația înainte de primul dialog, argumentând că „utilizatorul trebuie să înțeleagă”. Acest lucru înrăutățește UX: utilizatorul vede două dialoguri consecutive în loc de unul. Google recomandă afișarea dialogului de sistem imediat, iar rationale — doar după refuz.

Utilizați rationale contextual, legat de momentul când funcția este cu adevărat necesară. Nu solicitați toate permisiunile la pornirea aplicației — aceasta este cea mai scăzută rată de acordare. Solicitați CAMERA când utilizatorul a apăsat butonul „Faceți o fotografie” și LOCATION când a deschis harta. Cererea contextuală în combinație cu rationale crește acordarea la 80 de procente față de 30 de procente la cererea inițială.

Testarea scenariilor rationale

Testarea shouldShowRequestPermissionRationale necesită verificarea celor patru stări din tabel: nesolicitat, acordat, respins, Never Ask Again. În testele unitare se utilizează FakePermissionHandler cu comportament configurabil al shouldShowRationale. În testele instrumentale — UiAutomator sau Espresso cu emularea răspunsurilor la dialogurile de sistem.

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

Scenariul cheie pentru testul instrumental — verificarea că dialogul rationale se afișează într-adevăr după primul refuz. Utilizați Espresso cu idling resources pentru a aștepta dialogul de sistem, apoi apăsați Deny, verificați apariția dialogului personalizat cu textul explicației și apăsați Allow — verificați acordarea. UIAutomator permite interacțiunea cu dialogul de sistem prin textul butonului, ceea ce face testul mai stabil.

De asemenea, merită să testați scenariul de refuz în interiorul dialogului rationale. Dacă utilizatorul a apăsat Deny în explicația personalizată, shouldShowRequestPermissionRationale ar trebui să returneze din nou true, deoarece Never Ask Again nu a fost încă activat. Cea mai bună practică — după două refuzuri consecutive să redirecționați direct la Setări pentru a nu irita utilizatorul cu explicații repetate și a nu scădea ratingul aplicației.

Întrebări frecvente

Ce returnează shouldShowRequestPermissionRationale?

true — dacă cererea a fost respinsă anterior și Never Ask Again nu a fost setat. false — dacă permisiunea nu a fost solicitată, a fost acordată sau este blocată permanent. Combinația false + DENIED necesită verificare printr-un flag suplimentar.

Când să afișați dialogul rationale?

Afișați rationale doar după primul refuz al utilizatorului, când shouldShowRequestPermissionRationale a returnat true. Înainte de prima cerere, rationale nu este necesar — acest lucru înrăutățește UX și creează dialoguri inutile.

Cum să distingem prima cerere de Never Ask Again?

Stocați flag-ul isFirstRequest în SharedPreferences sau SavedStateHandle. Dacă shouldShowRationale = false, checkSelfPermission = DENIED și flag-ul = true — înseamnă că Never Ask Again este activat. Dacă flag-ul = false — aceasta este prima cerere.

Ce să faceți în cazul Never Ask Again?

Afișați un dialog cu butonul „Deschideți setările” care redirecționează utilizatorul la ACTION_APPLICATION_DETAILS_SETTINGS. Nu apelați din nou requestPermissions — dialogul nu va apărea, iar rezultatul va veni cu DENIED fără mesaj.

Cum să testați shouldShowRequestPermissionRationale?

În testele unitare, utilizați FakePermissionHandler cu câmpul configurabil shouldShowRationale. În testele instrumentale — Espresso sau UIAutomator cu emularea dialogului de sistem. Verificați toate cele 4 stări din tabel.

Rezumat

  • shouldShowRequestPermissionRationale — metodă care determină necesitatea afișării unei explicații înainte de solicitarea permisiunii.
  • Returnează true după primul refuz fără Never Ask Again, false — în celelalte trei cazuri.
  • Combinația false + DENIED — cel mai dificil scenariu care necesită un flag suplimentar pentru distingere.
  • Dialogul rationale se afișează doar după refuz, nu înainte de prima cerere.
  • Utilizați bottom sheet sau element inline în locul dialogului modal pentru un UX mai bun.
  • În cazul Never Ask Again — redirecționați la Setări prin ACTION_APPLICATION_DETAILS_SETTINGS.
  • Rationale contextual legat de momentul utilizării funcției crește acordarea la 80 de procente.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și