Gestire i permessi runtime in Flutter con permission_handler
GuideIntermedio35 min Flutter 3.x

Gestire i permessi runtime in Flutter con permission_handler

Molte funzionalità delle app moderne — accedere alla fotocamera, alla posizione GPS o ai contatti — richiedono il consenso esplicito dell'utente. In Flutter la gestione dei permessi runtime è semplificata dal pacchetto permission_handler, che offre un'API unificata per Android e iOS.

In questo tutorial vedremo come installare il pacchetto, configurare correttamente i file nativi, richiedere un permesso, gestire i diversi stati (concesso, negato, negato permanentemente) e reindirizzare l'utente alle impostazioni di sistema quando necessario.

  1. 1

    Aggiungere la dipendenza permission_handler

    Apri il file pubspec.yaml e aggiungi il pacchetto permission_handler nella sezione delle dipendenze. Successivamente esegui flutter pub get dal terminale per scaricarlo.

    dependencies:
      flutter:
        sdk: flutter
      permission_handler: ^11.3.1

    Risultato atteso

    Il pacchetto viene scaricato correttamente ed è disponibile per l'import nel progetto.

  2. 2

    Configurare Android

    Su Android devi dichiarare i permessi nel file android/app/src/main/AndroidManifest.xml. Aggiungi le voci relative ai permessi che intendi utilizzare, ad esempio fotocamera e posizione. I permessi runtime funzionano da Android 6.0 (API 23) in poi.

    Verifica inoltre che minSdkVersion nel file android/app/build.gradle sia almeno 21 (raccomandato dalla libreria).

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

    Risultato atteso

    L'app Android riconosce i permessi dichiarati e può richiederli a runtime.

  3. 3

    Configurare iOS

    Su iOS ogni permesso richiede una descrizione testuale nel file ios/Runner/Info.plist, altrimenti l'app verrà rifiutata dall'App Store o crasherà al momento della richiesta. Aggiungi le chiavi NSCameraUsageDescription e NSLocationWhenInUseUsageDescription con un messaggio chiaro.

    Inoltre, permission_handler richiede di abilitare le macro dei permessi nel Podfile. Aggiungi il blocco post_install per definire solo i permessi che usi.

    <key>NSCameraUsageDescription</key>
    <string>L'app usa la fotocamera per scattare foto.</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>L'app usa la posizione per mostrarti contenuti vicini.</string>

    Risultato atteso

    iOS mostrerà i messaggi descrittivi nel popup di richiesta permesso, evitando crash.

  4. 4

    Verificare lo stato di un permesso

    Prima di richiedere un permesso è buona pratica controllarne lo stato corrente. Il metodo .status restituisce un oggetto PermissionStatus che può assumere valori come granted, denied, permanentlyDenied o restricted.

    Questo ti permette di evitare richieste inutili se il permesso è già stato concesso.

    import 'package:permission_handler/permission_handler.dart';
    
    Future<void> checkCameraStatus() async {
      final status = await Permission.camera.status;
    
      if (status.isGranted) {
        print('Permesso fotocamera già concesso');
      } else if (status.isDenied) {
        print('Permesso negato, va richiesto');
      } else if (status.isPermanentlyDenied) {
        print('Permesso negato permanentemente');
      }
    }

    Risultato atteso

    In console viene stampato lo stato attuale del permesso fotocamera.

  5. 5

    Richiedere il permesso e gestire l'esito

    Per richiedere un permesso usa il metodo .request(), che mostra il popup di sistema e restituisce il nuovo PermissionStatus. Gestisci tutti i casi: se concesso procedi con la funzionalità, se negato mostra un messaggio, se negato permanentemente indirizza l'utente alle impostazioni.

    Il metodo openAppSettings() apre la schermata delle impostazioni dell'app, unico modo per riabilitare un permesso negato permanentemente.

    Future<void> requestCameraPermission() async {
      final status = await Permission.camera.request();
    
      if (status.isGranted) {
        // Procedi: apri la fotocamera
        print('Permesso concesso');
      } else if (status.isPermanentlyDenied) {
        // L'utente ha negato definitivamente
        await openAppSettings();
      } else {
        print('Permesso negato');
      }
    }

    Risultato atteso

    Viene mostrato il popup di sistema; in base alla scelta dell'utente l'app procede o apre le impostazioni.

  6. 6

    Creare un widget di esempio completo

    Uniamo tutto in una schermata pratica con un pulsante che richiede il permesso fotocamera e mostra un SnackBar con l'esito. Questo pattern è riutilizzabile per qualsiasi altro permesso cambiando semplicemente Permission.camera.

    import 'package:flutter/material.dart';
    import 'package:permission_handler/permission_handler.dart';
    
    class PermissionScreen extends StatelessWidget {
      const PermissionScreen({super.key});
    
      Future<void> _handleCamera(BuildContext context) async {
        final status = await Permission.camera.request();
        String message;
    
        if (status.isGranted) {
          message = 'Fotocamera abilitata!';
        } else if (status.isPermanentlyDenied) {
          message = 'Permesso bloccato: apri le impostazioni';
          await openAppSettings();
        } else {
          message = 'Permesso negato';
        }
    
        if (context.mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(message)),
          );
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Permessi')),
          body: Center(
            child: ElevatedButton.icon(
              onPressed: () => _handleCamera(context),
              icon: const Icon(Icons.camera_alt),
              label: const Text('Richiedi fotocamera'),
            ),
          ),
        );
      }
    }

    Risultato atteso

    Toccando il pulsante appare il popup di permesso e successivamente uno SnackBar con l'esito della richiesta.

  7. 7

    Gestire più permessi contemporaneamente

    Spesso serve richiedere più permessi in una sola volta, ad esempio fotocamera e microfono per registrare un video. Puoi passare una lista di Permission al metodo request() di una List, ottenendo una mappa con lo stato di ciascuno.

    Questo approccio riduce il numero di popup e migliora l'esperienza utente.

    Future<void> requestMultiple() async {
      final Map<Permission, PermissionStatus> statuses = await [
        Permission.camera,
        Permission.microphone,
      ].request();
    
      final tuttiConcessi = statuses.values.every((s) => s.isGranted);
    
      if (tuttiConcessi) {
        print('Tutti i permessi concessi');
      } else {
        statuses.forEach((permission, status) {
          print('$permission: $status');
        });
      }
    }

    Risultato atteso

    Vengono richiesti in sequenza i permessi della lista e si ottiene lo stato dettagliato di ognuno.

CondividiXLinkedInFacebookWhatsApp

Commenti (0)

Ancora nessun commento. Inizia tu!