Toestemming Beheer in Flutter

Toegangen zijn cruciaal bij het bouwen van mobiele applicaties die toegang vereisen tot apparaatspecifieke functies zoals locatie, camera, contacten en meer. In Flutter zorgt het effectief beheren van deze toegangen ervoor dat de app een naadloze gebruikerservaring biedt, terwijl het voldoet aan privacy- en beveiligingseisen. Een populair pakket om toegangen in Flutter te beheren is permission_handler.

Dit artikel zal je begeleiden bij het aanvragen, controleren en beheren van verschillende toegangen in Flutter met behulp van permission_handler, met praktische voorbeelden gebaseerd op permission_handler.

Eerst voeg je het permission_handler en fluttertoast pakket toe aan je pubspec.yaml bestand:

dependencies:
  permission_handler: ^11.3.1 
  fluttertoast: ^8.2.4

Vervolgens voer je uit:

flutter pub get

Het permission_handler pakket biedt een eenvoudige manier om toegangen aan te vragen en hun statussen te controleren. Hieronder volgt een complete uiteenzetting van het beheren van verschillende toegangen zoals telefoonoproepen, contacten, locatie, SMS, en camera/microfoon.

De Permission Handler kan al deze soorten machtigingen beheren: Kalender, Camera, Contacten, Locatie, Mediabibliotheek, Microfoon, Telefoon, Foto’s, Herinneringen, Sensoren, SMS, Spraakherkenning, Opslag, Negeer batterijoptimalisaties, Meldingen, Toegang tot mediacontact, Activiteitherkenning, Bluetooth-machtigingen, Beheer externe opslag, Systeemwaarschuwingsvenster, Vraag installatiepakketten aan, App-trackingtransparantie, Kritieke waarschuwingen, Toegang tot meldingsbeleid, Nabijgelegen Wi-Fi-apparaten, Audio, Plan exacte alarmen, SensorenAltijd, KalenderAlleenLezen en KalenderVolledigeToegang, maar we gaan een paar hiervan in dit artikel behandelen

Hieronder volgt een gedetailleerde gids over hoe je elke soort machtiging kunt aanvragen, hoe je omgaat met scenario’s zoals weigering of permanente weigering, en wat elke machtiging toegang verleent tot.


  • Machtigingen: calendar, calendarReadOnly, calendarFullAccess

  • Gebruiksscenario: Toegang tot de kalender van de gebruiker om evenementen te lezen of te schrijven.

Future<void> requestCalendarPermission() async {
  var status = await Permission.calendar.request();

  if (status.isGranted) {
    // Permission granted, proceed with calendar access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Calendar permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Calendar permission denied',
    );
  }
}

  • Machtiging: camera

  • Gebruiksscenario: Toegang tot de camera van het apparaat voor het vastleggen van foto’s of video’s.

Future<void> requestCameraPermission() async {
  var status = await Permission.camera.request();

  if (status.isGranted) {
    // Permission granted, proceed with camera access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Camera permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Camera permission denied',
    );
  }
}

  • Machtiging: contacts

  • Gebruiksscenario: Toegang tot de contactenlijst van de gebruiker voor het lezen of wijzigen van contacten.

Future<void> requestContactsPermission() async {
  var status = await Permission.contacts.request();

  if (status.isGranted) {
    // Permission granted, proceed with contacts access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Contacts permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Contacts permission denied',
    );
  }
}

  • Machtigingen: location, locationAlways, locationWhenInUse, accessMediaLocation

  • Gebruiksscenario: Toegang tot de locatie van de gebruiker voor navigatie, geofencing of nabijgelegen services.

Future<void> requestLocationPermission() async {
  var status = await Permission.location.request();

  if (status.isGranted) {
    // Permission granted, proceed with location access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Location permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Location permission denied',
    );
  }
}

  • Machtiging: mediaLibrary

  • Gebruiksscenario: Toegang tot de mediabibliotheek van de gebruiker (alleen iOS).

Future<void> requestMediaLibraryPermission() async {
  var status = await Permission.mediaLibrary.request();

  if (status.isGranted) {
    // Permission granted, proceed with media library access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Media Library permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Media Library permission denied',
    );
  }
}

  • Machtiging: microphone

  • Gebruiksscenario: Toegang krijgen tot de microfoon van het apparaat voor het opnemen van audio.

Future<void> requestMicrophonePermission() async {
  var status = await Permission.microphone.request();

  if (status.isGranted) {
    // Permission granted, proceed with microphone access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Microphone permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Microphone permission denied',
    );
  }
}

  • Machtiging: telefoon

  • Gebruiksscenario: Telefoongesprekken voeren, telefoonstatus lezen of toegang krijgen tot oproeplogs.

Future<void> requestPhonePermission() async {
  var status = await Permission.phone.request();

  if (status.isGranted) {
    // Permission granted, proceed with phone access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Phone permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Phone permission denied',
    );
  }
}

  • Machtigingen: foto's, alleenFoto'sToevoegen

  • Gebruiksscenario: Toegang krijgen tot de fotobibliotheek van de gebruiker voor het lezen of toevoegen van foto’s.

Future<void> requestPhotosPermission() async {
  var status = await Permission.photos.request();

  if (status.isGranted) {
    // Permission granted, proceed with photos access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Photos permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Photos permission denied',
    );
  }
}

  • Machtiging: herinneringen

  • Gebruiksscenario: Toegang krijgen tot en herinneringen beheren op het apparaat van de gebruiker.

Future<void> requestRemindersPermission() async {
  var status = await Permission.reminders.request();

  if (status.isGranted) {
    // Permission granted, proceed with reminders access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Reminders permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Reminders permission denied',
    );
  }
}

  • Machtigingen: sensoren, altijdSensoren

  • Gebruikscase: Toegang tot de sensoren van het apparaat, zoals versnellingsmeter en gyroscoop.

Future<void> requestSensorsPermission() async {
  var status = await Permission.sensors.request();

  if (status.isGranted) {
    // Permission granted, proceed with sensors access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Sensors permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Sensors permission denied',
    );
  }
}

  • Toestemming: sms

  • Gebruikscase: Toegang tot SMS-functies, inclusief het lezen of verzenden van SMS-berichten.

Future<void> requestSmsPermission() async {
  var status = await Permission.sms.request();

  if (status.isGranted) {
    // Permission granted, proceed with SMS access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'SMS permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'SMS permission denied',
    );
  }
}

  • Toestemming: speech

  • Gebruikscase: Toegang tot spraak-naar-tekst functies.

Future<void> requestSpeechPermission() async {
  var status = await Permission.speech.request();

  if (status.isGranted) {
    // Permission granted, proceed with speech recognition
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Speech recognition permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Speech recognition permission denied',
    );
  }
}

  • Toestemmingen: storage, manageExternalStorage

  • Gebruikscase: Toegang tot de interne of externe opslag van de gebruiker om bestanden te lezen of te schrijven.

Future<void> requestStoragePermission() async {
  var status = await Permission.storage.request();

  if (status.isGranted) {
    // Permission granted, proceed with storage access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Storage permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Storage permission denied',
    );
  }
}

  • Toestemming: ignoreBatteryOptimizations

  • Gebruikscase: Vraag het systeem om de app uit te sluiten van batterijoptimalisatiemaatregelen.

Future<void> requestIgnoreBatteryOptimizationsPermission() async {
  var status = await Permission.ignoreBatteryOptimizations.request();

  if (status.isGranted) {
    // Permission granted, proceed with ignoring battery optimizations
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Battery optimization permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Battery optimization permission denied',
    );
  }
}

  • Toestemming: notification

  • Gebruikscase: Sta uw app toe om meldingen te verzenden.

Future<void> requestNotificationPermission() async {
  var status = await Permission.notification.request();

  if (status.isGranted) {
    // Permission granted, proceed with notifications access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Notification permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Notification permission denied',
    );
  }
}

  • Toestemmingen: bluetooth, bluetoothScan, bluetoothAdvertise, bluetoothConnect

  • Gebruikscase: Toegang tot Bluetooth-functies voor het verbinden met of beheren van Bluetooth-apparaten.

Future<void> requestBluetoothPermission() async {
  var status = await Permission.bluetooth.request();

  if (status.isGranted) {
    // Permission granted, proceed with Bluetooth access
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'Bluetooth permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'Bluetooth permission denied',
    );
  }
}

  • Toestemming: appTrackingTransparency

  • Gebruikscase: Vraag de gebruiker om toestemming voor tracking, een vereiste voor app-tracking in iOS.

Future<void> requestAppTrackingTransparencyPermission() async {
  var status = await Permission.appTrackingTransparency.request();

  if (status.isGranted) {
    // Permission granted, proceed with app tracking
  } else if (status.isPermanentlyDenied) {
    ShowToast.showErrorText(
      text: 'App tracking permission permanently denied. Please enable it in the app settings.',
    );
    openAppSettings();
  } else {
    ShowToast.showErrorText(
      text: 'App tracking permission denied',
    );
  }
}

Toestemmingen spelen een cruciale rol in het bieden van een naadloze ervaring aan gebruikers, terwijl hun privacy wordt gerespecteerd. Het is essentieel om deze toestemmingen op een elegante manier te beheren en gebruikers te informeren waarom jouw app ze nodig heeft.

Door gebruik te maken van het permission_handler pakket, kun je alle noodzakelijke toestemmingen voor jouw Flutter-applicatie op zowel Android- als iOS-platforms aanvragen, controleren en beheren. Geef gebruikers altijd betekenisvolle feedback en overweeg om alternatieve stromen toe te voegen voor het geval toestemmingen worden geweigerd of ingetrokken.

Android- en iOS-configuraties

Het is essentieel om de nodige Android- en iOS-configuraties op te nemen. Voor Android betekent dit het bijwerken van het AndroidManifest.xml met de juiste toestemmingsverklaringen. Voor iOS moeten beschrijvingen van het gebruik van toestemmingen worden toegevoegd aan het Info.plist bestand om gebruikers te informeren waarom bepaalde toestemmingen worden aangevraagd.

Voor elke toestemming in de 17 voorbeelden moet je de bijbehorende <uses-permission> tag toevoegen in het AndroidManifest.xml. Hier is hoe de toestemmingen zich verhouden tot het permission_handler pakket:

  1. Camera-toestemming

     <uses-permission android:name="android.permission.CAMERA" />
    
  2. Contacten-toestemming

     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    
  3. Locatiepermissies

     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    
  4. Mediabibliotheek/Opslagtoestemming

     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage"/>
     <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
     <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
     <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    
  5. Microfoon Toestemming

     <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
  6. Telefoon Toestemming

     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    
  7. Foto’s Toestemming

     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
  8. Herinneringen Toestemming (Geen expliciete Android toestemming)

  9. Sensoren Toestemming

     <uses-permission android:name="android.permission.BODY_SENSORS" />
    
  10. SMS Machtiging

    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    
  11. Spreekherkenning Machtiging

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
  12. Negeer Batterijoptimalisaties

    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
    
  13. Machtiging voor Meldingen (Natuurlijk afgehandeld in Android 13+)

  14. Toegang tot Media Locatie Toestemming

    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
    
  15. Activiteitsherkenning Toestemming

    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
    
  16. Bluetooth Machtigingen

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    
  17. Toestemming voor App Tracking Transparency (alleen iOS)


Voor iOS moet je beschrijvende sleutels in het Info.plist bestand opgeven om gebruikers te informeren waarom jouw app specifieke machtigingen nodig heeft. Hieronder staan de configuraties voor elk machtigingsvoorbeeld:

  1. Camera Toestemming

     <key>NSCameraUsageDescription</key>
     <string>We hebben toegang tot uw camera nodig om foto's te maken.</string>
    
  2. Contacten Toestemming

     <key>NSContactsUsageDescription</key>
     <string>We hebben toegang tot uw contacten nodig voor betere communicatie.</string>
    
  3. Locatie Machtigingen

     <key>NSLocationWhenInUseUsageDescription</key>
     <string>We hebben toegang tot uw locatie nodig om locatiegebaseerde diensten te bieden.</string>
     <key>NSLocationAlwaysUsageDescription</key>
     <string>We hebben toegang tot uw locatie nodig om uw beweging te volgen, zelfs wanneer de app niet actief is.</string>
    
  4. Media Bibliotheek/Opslag Machtiging

     <key>NSPhotoLibraryUsageDescription</key>
     <string>We hebben toegang tot uw foto's nodig om media te delen of te uploaden.</string>
    
  5. Microfoon Toestemming

     <key>NSMicrophoneUsageDescription</key>
     <string>We hebben toegang tot uw microfoon nodig voor spraakopnames.</string>
    
  6. Telefoon Toestemming

     <key>NSPhoneUsageDescription</key>
     <string>We hebben toegang tot telefoonservices nodig om oproepen mogelijk te maken.</string>
    
  7. Foto’s Toestemming

     <key>NSPhotoLibraryAddUsageDescription</key>
     <string>We hebben toestemming nodig om foto's aan uw bibliotheek toe te voegen.</string>
    
  8. Herinneringen Toestemming

     <key>NSRemindersUsageDescription</key>
     <string>We hebben toegang nodig tot uw herinneringen voor taakbeheer.</string>
    
  9. Sensors Toestemming

     <key>NSSensorsUsageDescription</key>
     <string>We hebben toegang tot uw sensoren nodig voor fitness tracking.</string>
    
  10. SMS Toestemming (Automatisch afgehandeld door iOS als SMS-diensten worden aangevraagd)

  11. Spreekherkenning Toestemming

<key>NSSpeechRecognitionUsageDescription</key>
<string>We need access to speech recognition for voice commands.</string>
  1. Negeer Batterijoptimalisaties (Niet van toepassing op iOS)

  2. Notificaties Toestemming

<key>NSUserNotificationUsageDescription</key>
<string>We need permission to send notifications.</string>
  1. Toegang Media Locatie Toestemming (Automatisch afgehandeld op iOS)

  2. Activiteit Herkenning Toestemming

<key>NSMotionUsageDescription</key>
<string>We need access to motion data for fitness tracking.</string>
  1. Bluetooth Toestemmingen
<key>NSBluetoothPeripheralUsageDescription</key>
<string>We need access to Bluetooth for device connectivity.</string>
  1. App Tracking Transparantie
<key>NSUserTrackingUsageDescription</key>
<string>We need permission to track your activity across apps and websites for personalized ads.</string>

Om je app volledig functioneel en compliant met de nieuwste privacyregels te maken, is het essentieel om de machtigingen goed te beheren. Door zowel AndroidManifest.xml als Info.plist bij te werken, samen met het implementeren van de correcte machtigingsbehandelingslogica in je Flutter-app, bied je een naadloze en transparante ervaring voor gebruikers terwijl je toegang vraagt tot gevoelige functies.

Zorg er altijd voor dat je de machtigingen op beide platforms test en geef betekenisvolle uitleg aan gebruikers over waarom de machtigingen nodig zijn om afwijzing tijdens app store beoordelingen te voorkomen.

Voor grondiger onderzoek kun je de officiële documentatie voor machtigingsbeheerders bekijken om andere machtigingstypen te verkennen. Zorg er ook voor dat je je platformspecifieke bestanden (zoals AndroidManifest.xml en Info.plist) bijwerkt met de noodzakelijke verklaringen voor elk machtigingstype.

Source:
https://atuoha.hashnode.dev/permission-handling-in-flutter