Hello friends, Few days ago when I was reading about Runtime permissions in android for flutter then I thought, Why should not make a tutorial on this topic. So I started reading about this topic further. After searching a few queries on Google, I realized that flutter makes implementing runtime permissions for android is so much easy for us by providing us a Pub Package known as permission_handler. So in today’s tutorial we would learn about Example of Permission Handler Request Runtime Permission in Flutter Android. Today we are only implementing single runtime permission. So we will learn about the source code for requesting GPS location permission access and requesting camera access permission in today’s tutorial.
Contents in this project Example of Permission Handler Request Single Runtime Permission in Flutter Android :-
1. First of all we have to download and install the permission_handler PUB Package in our current flutter project. So open your flutter project Root directory in CMD in windows and in Terminal in MAC and execute below command.
1 |
flutter pub add permission_handler |
Screenshot :-
2. Now the package is successfully installed in our project, Next step is to add the Permission in our AndroidManifest.xml file. So Goto Your_Flutter_Project -> android -> app -> src -> main -> AndroidManifest.xml. Open the AndroidManifest.xml file in any code editor. I’m using Visual Studio Code editor. Now here comes the main part we’re implementing Access Location Permission and Camera Access Permission. So we have to add both of these permissions in our AndroidManifest.xml file.
1 2 |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.CAMERA"/> |
Source Code of my AndroidManifest.xml file after adding above permission :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.CAMERA"/> <application android:label="myapp" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> <meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> <!-- Displays an Android View that continues showing the launch screen Drawable until Flutter paints its first frame, then this splash screen fades out. A splash screen is useful to avoid any visual gap between the end of Android's launch screen and the painting of Flutter's first frame. --> <meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <meta-data android:name="flutterEmbedding" android:value="2" /> </application> </manifest> |
3. Now all the config part has finished. In next step we would start writing code for application. So open your project’s main.dart file and import material.dart and permission_handler.dart package.
1 2 |
import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; |
4. Creating our main void main runApp() method and here we would call our main App class.
1 |
void main() => runApp(App()); |
5. Creating our main App extends StatelessWidget class. In this class we would call AppState class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class App extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("Request RunTime Permission in Android Flutter"), ), body: SafeArea( child: Center( child: AppState(), ))), ); } } |
6. Creating our AppState extends StatefulWidget class. In this class we would make createState() State management method along with AppPermission class to enable mutable state in AppPermission class.
1 2 3 4 |
class AppState extends StatefulWidget { @override AppPermission createState() => AppPermission(); } |
7. Creating our main Child AppPermission extends State<AppState> class. In this class we would do all the main coding for app.
1 2 3 4 5 |
class AppPermission extends State<AppState> { } |
8. Creating a function named as requestCameraPermission() Future type of ASYNC. In this function we would request runtime camera permission for android.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Future<void> requestCameraPermission() async { final serviceStatus = await Permission.camera.isGranted ; bool isCameraOn = serviceStatus == ServiceStatus.enabled; final status = await Permission.camera.request(); if (status == PermissionStatus.granted) { print('Permission Granted'); } else if (status == PermissionStatus.denied) { print('Permission denied'); } else if (status == PermissionStatus.permanentlyDenied) { print('Permission Permanently Denied'); await openAppSettings(); } } |
9. Creating another function named as requestLocationPermission() Future type of ASYNC. In this function we would ask for Location permission on app runtime.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Future<void> requestLocationPermission() async { final serviceStatusLocation = await Permission.locationWhenInUse.isGranted ; bool isLocation = serviceStatusLocation == ServiceStatus.enabled; final status = await Permission.locationWhenInUse.request(); if (status == PermissionStatus.granted) { print('Permission Granted'); } else if (status == PermissionStatus.denied) { print('Permission denied'); } else if (status == PermissionStatus.permanentlyDenied) { print('Permission Permanently Denied'); await openAppSettings(); } } |
10. Creating Widget Build area then we would make 2 ElevatedButton widget and call above both requestLocationPermission() and requestCameraPermission() function on button onPress event.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( margin: const EdgeInsets.all(10), child: ElevatedButton( style: ElevatedButton.styleFrom( primary: Colors.lightBlue, padding: EdgeInsets.all(8), textStyle: TextStyle(fontSize: 20), ), child: Text('Request Runtime Camera Permission'), onPressed: requestCameraPermission, ), ), Container( margin: const EdgeInsets.all(10), child: ElevatedButton( style: ElevatedButton.styleFrom( primary: Colors.lightBlue, padding: EdgeInsets.all(8), textStyle: TextStyle(fontSize: 20), ), child: Text('Request Runtime Location Permission'), onPressed: requestLocationPermission, ), ), ], )); } |
11. Complete source code for main.dart file :-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; void main() => runApp(App()); class App extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("Request RunTime Permission in Android Flutter"), ), body: SafeArea( child: Center( child: AppState(), ))), ); } } class AppState extends StatefulWidget { @override AppPermission createState() => AppPermission(); } class AppPermission extends State<AppState> { Future<void> requestCameraPermission() async { final serviceStatus = await Permission.camera.isGranted ; bool isCameraOn = serviceStatus == ServiceStatus.enabled; final status = await Permission.camera.request(); if (status == PermissionStatus.granted) { print('Permission Granted'); } else if (status == PermissionStatus.denied) { print('Permission denied'); } else if (status == PermissionStatus.permanentlyDenied) { print('Permission Permanently Denied'); await openAppSettings(); } } Future<void> requestLocationPermission() async { final serviceStatusLocation = await Permission.locationWhenInUse.isGranted ; bool isLocation = serviceStatusLocation == ServiceStatus.enabled; final status = await Permission.locationWhenInUse.request(); if (status == PermissionStatus.granted) { print('Permission Granted'); } else if (status == PermissionStatus.denied) { print('Permission denied'); } else if (status == PermissionStatus.permanentlyDenied) { print('Permission Permanently Denied'); await openAppSettings(); } } Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( margin: const EdgeInsets.all(10), child: ElevatedButton( style: ElevatedButton.styleFrom( primary: Colors.lightBlue, padding: EdgeInsets.all(8), textStyle: TextStyle(fontSize: 20), ), child: Text('Request Runtime Camera Permission'), onPressed: requestCameraPermission, ), ), Container( margin: const EdgeInsets.all(10), child: ElevatedButton( style: ElevatedButton.styleFrom( primary: Colors.lightBlue, padding: EdgeInsets.all(8), textStyle: TextStyle(fontSize: 20), ), child: Text('Request Runtime Location Permission'), onPressed: requestLocationPermission, ), ), ], )); } } |
Screenshots :-