Flutter Lesson 62 of 83 4 min read
Flutter Plugins and Permissions
Learn how Flutter plugins work, how to pick good ones, and how to declare and request permissions on Android and iOS correctly.
On this page
Packages and plugins #
| Package | Plugin | |
|---|---|---|
| Contains | Dart code only | Dart code plus native code (Kotlin, Swift, JavaScript, C++) |
| Examples | http, provider, intl | camera, geolocator, shared_preferences |
| Works on | Every platform | Only the platforms it implements |
| After adding | Hot restart is enough | Stop and run again, since native code must be rebuilt |
Both are added the same way:
flutter pub add image_picker
Choosing a plugin #
Check on pub.dev before depending on one:
- Platforms. Does it support every platform you ship on?
- Publisher.
flutter.devanddart.devare the official teams. Other verified publishers are a good sign. - Maintenance. When was it last updated? Are issues being answered?
- Pub points and likes.
- Setup. Read the README. Most plugin problems come from a skipped setup step.
Plugins worth knowing #
| Feature | Plugin |
|---|---|
| Photos and camera | image_picker, camera |
| Pick any file | file_picker |
| Location | geolocator, location |
| Maps | google_maps_flutter, flutter_map |
| Open links, call, email | url_launcher |
| Share | share_plus |
| Local notifications | flutter_local_notifications |
| Push notifications | firebase_messaging |
| Fingerprint and face unlock | local_auth |
| Device and app information | device_info_plus, package_info_plus |
| Network status | connectivity_plus |
| In-app web pages | webview_flutter |
| QR and barcode scanning | mobile_scanner |
| Audio and video | just_audio, video_player |
| In-app purchases | in_app_purchase |
Permissions #
Sensitive features need the user’s permission. There are two parts, and missing either one breaks the feature.
1. Declare it in the native project #
Android, in android/app/src/main/AndroidManifest.xml, above <application>:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
iOS, in ios/Runner/Info.plist, with a sentence explaining why:
<key>NSCameraUsageDescription</key>
<string>The camera is used to take your profile photo.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is used to show shops near you.</string>
On iOS, the app crashes the moment it asks for a permission whose description is missing. Apple also rejects vague descriptions such as “We need the camera”.
Each plugin’s README lists exactly which entries it needs.
2. Ask at run time #
Many plugins ask on their own when you first use them. For control, use permission_handler.
flutter pub add permission_handler
import 'package:permission_handler/permission_handler.dart';
Future<bool> ensureCameraPermission() async {
var status = await Permission.camera.status;
if (status.isDenied) {
status = await Permission.camera.request(); // shows the system dialog
}
if (status.isPermanentlyDenied) {
// The system will not ask again. Send the user to the settings app.
await openAppSettings();
return false;
}
return status.isGranted;
}
| Status | Meaning |
|---|---|
granted | Allowed |
denied | Not allowed yet. You may ask |
permanentlyDenied | The user chose “Don’t ask again”, or denied twice. Only the settings app can change it |
restricted | Blocked by parental or company controls (iOS) |
limited | Partial access, such as selected photos only (iOS) |
Asking well #
How you ask affects whether people say yes.
- Ask in context. Request the camera when the user taps “Take photo”, not when the app starts.
- Explain first if the reason is not obvious. Show your own short message, then the system dialog.
- Ask for the least. Location “while using the app” is enough for most apps.
- Handle no. The app must still work. Offer an alternative, such as typing an address.
- Never ask repeatedly. After a permanent denial, explain how to enable it in settings and move on.
Future<void> _onTakePhoto() async {
if (!await ensureCameraPermission()) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Camera access is needed to take a photo.')),
);
return;
}
// open the camera
}
Store requirements #
Google Play and the App Store review how apps use permissions. Request only what the app really uses, describe it honestly in the store listing and privacy policy, and expect extra scrutiny for background location, contacts and SMS.
When a plugin does not work #
- Stop the app completely and run again. Hot reload does not load native code.
- Read the plugin’s setup section again.
- Run
flutter clean, thenflutter pub get. - On iOS, run
pod installin theiosfolder, or deleteios/Podsand build again. - Check the minimum Android SDK and iOS version the plugin requires.
- Test on a real device. Emulators lack some hardware.
Try it yourself #
Add permission_handler to a project. Build a screen with buttons for camera, location and notifications. Each button shows the current status, asks when tapped, and offers “Open settings” when the permission is permanently denied.