AndroidManifest Permissions sono dichiarazioni di permessi nel file AndroidManifest.xml che determinano a quali risorse di sistema e dati un’applicazione può accedere. Android richiede che ogni permesso sia dichiarato nel manifesto prima di utilizzare l’API corrispondente: dalla fotocamera e geolocalizzazione all’invio di SMS e all’accesso ai contatti. Secondo la Documentazione per sviluppatori Android, ogni permesso rientra in uno dei quattro livelli di protezione: normal, dangerous, signature e special.
Punti chiave
AndroidManifest Permissions è il meccanismo di sicurezza di Android che controlla l’accesso delle applicazioni a dati protetti e funzioni di sistema. Ogni applicazione deve dichiarare i permessi necessari nel file AndroidManifest.xml utilizzando l’elemento
Il modello di permessi di Android ha attraversato diverse fasi evolutive. Prima di Android 6.0 (API 23), tutti i permessi venivano concessi all’installazione — l’utente vedeva l’elenco completo e accettava o rifiutava l’installazione dell’applicazione. A partire da Android 6.0, i permessi di livello dangerous vengono richiesti in fase di esecuzione (Runtime Permissions), dando all’utente un controllo più flessibile.
I permessi sono suddivisi in quattro livelli di protezione: normal (concessi automaticamente all’installazione), dangerous (richiedono richiesta in fase di esecuzione), signature (disponibili solo per applicazioni firmate con lo stesso certificato) e special (richiedono attivazione separata nelle impostazioni). Ogni livello ha il proprio meccanismo di concessione e revoca.
Secondo Google I/O 2024, Android 15 prevede di introdurre permessi più granulari — l’utente potrà concedere l’accesso solo a file specifici nella libreria multimediale, non all’intera raccolta. Ciò prosegue la tendenza di Android a minimizzare la quantità di dati forniti per impostazione predefinita.
A differenza di iOS, dove tutti i permessi vengono richiesti in fase di esecuzione, Android divide i permessi in tipi di installazione (install-time) ed esecuzione (runtime). Il livello normal viene concesso automaticamente all’installazione senza notifica all’utente. Il livello dangerous richiede un dialogo esplicito, come in iOS.
Un’altra differenza: in Android, i permessi sono raggruppati in gruppi di permessi. Se l’utente acconsente all’accesso alla fotocamera, l’applicazione ottiene automaticamente l’accesso al microfono — si trovano nello stesso gruppo MICROPHONE. In iOS, ogni permesso viene richiesto indipendentemente dai gruppi.
| Versione Android | Modifica nel modello di permessi |
|---|---|
| Android 1.0–5.x | Tutti i permessi concessi all’installazione |
| Android 6.0 (API 23) | Introduzione delle Runtime Permissions per il livello dangerous |
| Android 10 (API 29) | Scoped Storage — accesso limitato al file system |
| Android 11 (API 30) | Auto-reset dei permessi — i permessi inutilizzati vengono reimpostati |
| Android 14 (API 34) | Permessi in fase di esecuzione per l’accesso ai media (foto, video, audio) |
Android definisce quattro livelli di protezione per i permessi, ciascuno con le proprie regole di concessione. Esaminiamo ogni livello in dettaglio.
I permessi normal vengono concessi automaticamente all’installazione dell’applicazione senza notifica o richiesta all’utente. Coprono funzioni a basso rischio che non minacciano la privacy dell’utente: INTERNET, ACCESS_NETWORK_STATE, VIBRATE, BLUETOOTH. L’utente non vede alcun dialogo di consenso — il permesso si considera concesso al momento dell’installazione.
Lo sviluppatore non deve gestire richieste nel codice per i permessi normal — è sufficiente dichiararli nel manifesto. Tuttavia, su Android 12+, durante l’installazione da Google Play, l’utente vede una scheda “Permessi” che elenca tutti i permessi normal, aumentando la trasparenza. Secondo Statista (2024), oltre il 90% delle applicazioni su Google Play utilizza INTERNET come permesso normal più comune.
I permessi dangerous coprono l’accesso a dati e funzioni che possono compromettere la privacy: fotocamera, microfono, geolocalizzazione, contatti, SMS, telefono, calendario, sensori corporei. Questi permessi richiedono un meccanismo in due fasi: dichiarazione nel manifesto + richiesta in fase di esecuzione tramite ActivityCompat.requestPermissions().
L’utente può negare un permesso dangerous, e l’applicazione deve gestire correttamente questo scenario. Su Android 11+, se l’utente nega due volte, le richieste successive non mostrano il dialogo di sistema — il sistema restituisce automaticamente DENIED. In questo caso, l’applicazione deve indirizzare l’utente alle impostazioni.
Il livello signature — il permesso viene concesso automaticamente se l’applicazione è firmata con lo stesso certificato del sistema o di un’altra applicazione che ha definito il permesso. Utilizzato per applicazioni di sistema e aziendali. Esempio: BIND_ACCESSIBILITY_SERVICE — disponibile solo per applicazioni di sistema.
Il livello special (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, REQUEST_INSTALL_PACKAGES, MANAGE_EXTERNAL_STORAGE) — richiede un’azione esplicita dell’utente tramite le impostazioni di sistema. L’applicazione può aprire la pagina delle impostazioni con Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION). Google Play limita l’uso dei permessi special e richiede una giustificazione nel modulo di pubblicazione.
Da Android 6.0, tutti i permessi dangerous richiedono una richiesta in fase di esecuzione. Esaminiamo il ciclo completo di lavoro con i runtime permissions in Kotlin.
Prima di chiamare un’API che richiede un permesso dangerous, verifica sempre lo stato corrente tramite ContextCompat.checkSelfPermission(). Se lo stato è PERMISSION_GRANTED, puoi chiamare l’API. Se è PERMISSION_DENIED, devi richiedere il permesso tramite ActivityResultContract RequestPermission (AndroidX) o il deprecato requestPermissions().
Si raccomanda di utilizzare ActivityResultContracts.RequestMultiplePermissions per richiedere più permessi contemporaneamente. Google raccomanda di raggruppare permessi correlati (ad esempio, fotocamera + microfono per la registrazione video) in un unico dialogo, in modo che l’utente veda il contesto completo della richiesta.
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
class CameraActivity : AppCompatActivity() {
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
openCamera()
} else {
explainWhyPermissionNeeded()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
checkCameraPermission()
}
private fun checkCameraPermission() {
when {
ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
openCamera()
}
shouldShowRequestPermissionRationale(
Manifest.permission.CAMERA
) -> {
showRationale()
}
else -> {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
}
}
Se l’utente rifiuta due volte, Android porta la richiesta allo stato “Never ask again”. In questo caso, shouldShowRequestPermissionRationale() restituisce false e il dialogo di sistema non verrà mostrato. L’applicazione deve indirizzare l’utente alle impostazioni di sistema tramite Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).
Importante: non mostrare un dialogo che offre di aprire le impostazioni subito dopo il primo rifiuto — viene percepito come comportamento aggressivo. Usa shouldShowRequestPermissionRationale() per determinare se è necessario mostrare una spiegazione. Le Linee guida Material Design raccomandano di mostrare una schermata che spiega il valore dell’accesso, non solo un pulsante “Apri impostazioni”.
private fun openAppSettings() {
Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)
).also { intent ->
startActivity(intent)
}
}
private fun showPermissionSettings() {
AlertDialog.Builder(this)
.setTitle("Accesso alla fotocamera")
.setMessage("Consenti l’accesso alla fotocamera nelle Impostazioni, "
+ "per scattare foto del profilo")
.setPositiveButton("Apri impostazioni") { _, _ ->
openAppSettings()
}
.setNegativeButton("Annulla", null)
.show()
}
Il file AndroidManifest.xml contiene l’elemento
Ogni permesso viene dichiarato con un elemento
Ad esempio, il permesso WRITE_EXTERNAL_STORAGE non è necessario su Android 10+ (Scoped Storage), quindi specifica maxSdkVersion="28" (Android 9). Ciò previene domande inutili da parte degli utenti sulle versioni più recenti. Android Studio avvisa sui maxSdkVersion raccomandati tramite Lint.
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Normal permissions (install-time) -->
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Dangerous permissions (runtime) -->
<uses-permission
android:name="android.permission.CAMERA" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Legacy storage permission limited to API 28 and below -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<application>
<!-- ... -->
</application>
</manifest>
L’elemento
Si raccomanda di impostare required="false" per tutte le funzionalità hardware e verificare la disponibilità a livello di codice tramite PackageManager.hasSystemFeature(). Ciò amplia il pubblico della tua applicazione. L’unica eccezione è se la funzionalità è critica per il funzionamento dell’applicazione (un’app di taxi senza GPS non ha senso).
La corretta gestione dei permessi è un aspetto fondamentale della qualità di un’applicazione Android. Esaminiamo le principali raccomandazioni e gli errori tipici.
Richiedi solo i permessi realmente necessari per il funzionamento dell’applicazione. Ogni permesso extra riduce il tasso di conversione delle installazioni e aumenta il numero di rifiuti. La Google Play Console mostra quanti utenti hanno rifiutato l’installazione a causa dell’insieme di permessi. Secondo AppBrain (2024), le applicazioni con 10+ permessi dangerous hanno il 35% in meno di installazioni.
Rivedi regolarmente il tuo elenco di permessi. Rimuovi quelli non utilizzati, specialmente quando migri a versioni più recenti di Android dove alcuni permessi diventano opzionali. Ad esempio, con il selettore foto (ActivityResultContracts.PickVisualMedia) su Android 13+, l’accesso alla libreria multimediale può essere ottenuto senza il permesso dangerous READ_MEDIA_IMAGES.
Prima di richiedere un permesso dangerous, mostra all’utente una schermata che spiega perché questo permesso è necessario e quale valore offre. Material Design raccomanda di utilizzare un foglio inferiore o un dialogo con un’icona, testo breve e un pulsante “Continua”. La spiegazione aumenta il consenso del 20–30% rispetto a una richiesta diretta.
Verifica shouldShowRequestPermissionRationale() prima di chiamare launch(). Se true, mostra la spiegazione. Se false, il permesso è già stato concesso o l’utente lo ha negato permanentemente (never ask again). In quest’ultimo caso, mostra un pulsante “Apri impostazioni” invece di ripetere la richiesta.
Testa tutti gli scenari possibili: concessione del permesso, rifiuto, rifiuto permanente, revoca del permesso nelle impostazioni, reimpostazione dei permessi (Android 11+ auto-reset). Ogni scenario deve essere gestito senza crash o perdita di dati. La Guida ai test Android raccomanda di utilizzare la libreria TestPermission per automatizzare i test.
Presta particolare attenzione allo scenario in cui l’utente revoca un permesso mentre l’applicazione è in esecuzione (app minimizzata → Impostazioni → revoca). Al ritorno nell’applicazione, verifica tutti i permessi in onResume(). Non affidarti alla memorizzazione nella cache dello stato dei permessi — l’utente può modificarli in qualsiasi momento.
Domande frequenti
Sì, se un SDK include un permesso nel suo manifesto, viene unito al manifesto dell’applicazione durante la compilazione. Puoi rimuovere un permesso SDK non necessario usando tools:node="remove" in AndroidManifest.xml.
Chiamare un’API senza permesso genererà una SecurityException, causando l’arresto anomalo dell’applicazione. Verifica sempre lo stato del permesso prima di utilizzare l’API corrispondente e gestisci il rifiuto correttamente.
Nelle impostazioni del dispositivo: Impostazioni → App → [tua app] → Permessi. Per reimpostare tutti i permessi, usa il comando adb: adb shell pm reset-permissions.
Sì, utilizzando ActivityResultLauncher in un Fragment o Service. Tuttavia, il dialogo di richiesta richiede sempre un contesto UI dell’Activity. Per un Service, puoi mostrare una Notifica con un Intent che apre l’Activity di richiesta.
Ad esempio, WRITE_EXTERNAL_STORAGE non è necessario su Android 10+ (Scoped Storage). Specificando android:maxSdkVersion="28", escludi la dichiarazione del permesso sulle versioni più recenti, migliorando la compatibilità e riducendo l’elenco dei permessi richiesti.
Riepilogo
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.
Leggi anche