Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 12 di 97
  • livello avanzato
Indice lezioni

Le permission

Gestire le permission su Android: cosa sono, come aggiungerle al file AndroidManifest.xml, e come gestire la revoca di ognuna di esse in Java.
Gestire le permission su Android: cosa sono, come aggiungerle al file AndroidManifest.xml, e come gestire la revoca di ognuna di esse in Java.
Link copiato negli appunti

Un'applicazione Android vive in all'interno di una sandbox, ovvero un ambiente chiuso in cui l'applicazione opera in maniera sostanzialmente isolata dal resto del sistema. Talvolta, però, può essere necessario che essa debba "uscire" da questa gabbia per accedere a informazioni, funzionalità o apparati hardware del dispositivo. Per far sì che l'app acceda a tali servizi, essa deve possedere alcuni "permessi" speciali - le cosiddette permission - che è necessario dichiarare espressamente nel file AndroidManifest.xml. Ogni permission viene dichiarata tramite il tag <uses-permission>, da collocare al di fuori del nodo <application>:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="...." >
<uses-permission android:name="android.permission.INTERNET" />
<application>
...
...
</application>
...
</manifest>

Fatto ciò, il sistema operativo saprà quali attività particolari l'app dovrà svolgere, e potrà concederle il permesso di effettuarle. Prima dell'installazione dell'app, infatti, l'utente viene sempre avvisato delle permission richieste dall'app: se accetta di installarla, accetta che il suo sistema operativo conceda tali permessi "speciali" all'app.

Tipi di permission

Le permission Android vengono suddivise in tre famiglie in base al livello di protezione:

  • permission normal, che non mettono cioè a rischio la privacy dell'utente, tra le quali troviamo:
    • accesso alla Rete (android.permission.INTERNET, verifica dello stato della rete (android.permission.ACCESS_NETWORK_STATE) e accesso alle informazioni sulle reti Wi-Fi (android.permission.ACCESS_WIFI_STATE);
    • accesso a particolari tecnologie per la connettività: android.permission.BLUETOOTH, android.permission.BLUETOOTH_ADMIN o android.permission.NFC;
    • invio di un Intent per l'impostazione di un allarme: com.android.alarm.permission.SET_ALARM;
    • gestione della vibrazione (android.permission.VIBRATE) o del WaveLock per il controllo dello stand-by (android.permission.WAVE_LOCK);
    • molte altre: una lista completa è disponibile sulla documentazione ufficiale.
  • permission dangerous, potenzialmente più lesive della riservatezza degli utenti, come quelle riguardanti:
    • la localizzazione: android.permission.ACCESS_FINE_LOCATION e android.permission.ACCESS_COARSE_LOCATION;
    • il calendario: android.permission.READ_CALENDAR e android.permission.WRITE_CALENDAR;
    • i contatti: android.permission.READ_CONTACTS e android.permission.WRITE_CONTACTS;
    • attività telefoniche: ad esempio, android.permission.READ_PHONE_STATE e android.permission.SEND_SMS;
    • accesso ai file: android.permission.READ_EXTERNAL_STORAGE e android.permission.WRITE_EXTERNAL_STORAGE.
  • permission signature, gestite a livello di installazione ma utilizzabili
    solo se l'app che le richiede è firmata con lo stesso certificato di quella che
    ha definito la permission.

Gestione delle permission

Le permission dangerous vanno accettate a runtime dall'utente al momento dell'utilizzo delle
funzionalità che le richiedono mentre per quelle normal è sufficiente dichiararne l'impiego
al momento dell'installazione dell'app. Tale distinzione è stata introdotta in Android 6 (API 23) ed
è ormai prassi cui l'utente è totalmente abituato. Inoltre, una permission dangerous già concessa
potrà essere revocata in qualsiasi istante.
Tutto ciò ha determinato un regime di gestione delle attività critiche più flessibile e più protettivo nei confronti dell'utente, ma che richiede agli sviluppatori una gestione più accurata delle eccezioni.

Ciò che cambia sul piano della progettazione è che l'app, in prospettiva, potrebbe avere più comportamenti: uno in cui tutte le permission dangerous sono state concesse dall'utente, altri in cui una o più di esse sono state negate o revocate. L'app, dal canto suo, dovrebbe essere in grado di lavorare correttamente in tutti i casi, semmai disattivando le funzionalità che necessitano delle permission negate. Per sviluppare app moderne, quindi, è necessario gestire le permission a runtime, verificando se esse siano revocate o meno, nonchè richiedendo all'utente di abilitarle.

La classe ContextCompat, inclusa nella libreria di supporto, mette a disposizione un metodo per effettuare questo tipo di controllo:

int statoPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);

dove this rappresenta la nostra Activity (che fungerà da Context). Il valore della variabile intera statoPermission sarà confrontato con le costanti PackageManager.PERMISSION_GRANTED oppure PackageManager.PERMISSION_DENIED che equivalgono, rispettivamente, alla concessione del permesso o al suo diniego.

Per fare in modo che le nostre app funzionino su versioni Android con API 23 o superiori dovremo verificare la disponibilità di una permission prima di utilizzare il metodo che ne ha bisogno, e qualora essa non fosse disponibile dovremo chiedere all'utente di acconsentire lanciando un apposito Intent. Per far comparire una finestra di dialogo che richieda l'accettazione della permission, si può usare il seguente codice Java:

ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ID_RICHIESTA_PERMISSION);

Abbiamo così passato un array di stringhe contenente le permission che dovranno essere accettate, ed una costante intera che noi abbiamo chiamato ID_RICHIESTA_PERMISSION, che permetterà di identificare la specifica richiesta che abbiamo inoltrato. Apparirà così una finestra di dialogo di questo tipo:

Figura 1. Richiesta di permission (click per ingrandire)

Richiesta di permission

Il risultato sarà inviato inviato ad un metodo che noi predisporremo:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case ID_RICHIESTA_PERMISSION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission concessa: eseguiamo il codice
} else {
// permission negata: provvediamo in qualche maniera
}
return;
}
}
}

Il metodo riceverà tre elementi: il codice della richiesta (utile per riconoscere a cosa sta rispondendo), l'array delle permission e l'array dei risultati (che conterrà in ogni posizione se la permission è stata accettata o meno). In base al controllo di quest'ultimo capiremo il da farsi: possiamo eseguire il codice o dobbiamo ovviare facendo qualcos'altro.

Riepilogando, quella che segue è la struttura di controllo da usare per far sì che l'utente acconsenta a svolgere attività soggette ad una permission dangerous. Si noti che viene controllato anche il metodo shouldShowRequestPermissionRationale, che verifica se sia il caso di fornire all'utente ulteriori informazioni rispetto alla permission richiesta e all'uso che l'app deve farne:

// controlliamo se la permission è concessa
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// se arriviamo qui è perchè la permission non è stata ancora concessa
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
// mostriamo ulteriori informazioni all'utente riguardante l'uso della permission nell'app ed eventualmente richiediamo la permission
} else {
// se siamo qui è perchè non si è mostrata alcuna spiegazione all'utente, richiesta di permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ID_RICHIESTA_PERMISSION);
}
}

L'utente sarà sempre padrone di revocare le permission dangerous concesse, semplicemente agendo sul controllo che apparirà tra le impostazioni dell'app:

Figura 2. Revoca di una permission (click per ingrandire)

Revoca di una permission

Ti consigliamo anche