Using Storage Permission in Flutter
Flutter is an awesome toolkit. It allows us for fast UI iteration. But what if we are not able to access the storage of the device we’re running on? In this guide, we’ll go through how we can get the storage permission in a Flutter Application.
Prerequisites
Platform setup
For this guide, I assume you’re using an Android Device.
Normally, In Android, we have to add these lines to our AndroidManifest.xml
file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
For those who don’t know, this file is located in 3 locations.
- One inside
Android > app > src > debug
- Another inside
Android > app > src > main
- And one inside
Android > app > src > profile
I’ll be sufficient to make the changes inside the one inside main folder.
And one thing to take note is that, if your App is Targeting Android Q or above, you’ll have to make the below change also.
<application
android:requestLegacyExternalStorage="true"
Don’t worry! Example file in Embedded below 😊. You can Clear all your doubts by comparing it with yours.
Packages
for this guide, we need a package called permission_handler
in our pubspec.yaml
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
permission_handler: ^6.1.1
Dart Code
The first thing we wanna do is to ask the user permission for accesing the storage. Let’s create a function for this.
Future _getStoragePermission() async {
if (await Permission.storage.request().isGranted) {
setState(() {
permissionGranted = true;
});
}
}
The above code checks if the app have permission to access storage.
And if permission is not granted yet, it’ll request the permission.
And sets the value of the boolean permissionGranted
to true.
But there may be cases when user have already chose, Deny And Don't Ask Again
option android presents.
In that case, the only option we have is to let the user grant the permission manually.
But it is a bad Experience if the user have to go all the way into settings and find your app.
For this purpose, the permission_handler library provides a handy shortcut.
Future _getStoragePermission() async {
if (await Permission.storage.request().isGranted) {
setState(() {
permissionGranted = true;
});
} else if (await Permission.storage.request().isPermanentlyDenied) {
await openAppSettings();
} else if (await Permission.storage.request().isDenied) {
setState(() {
permissionGranted = false;
});
}
}
The above code checks if the Permission is permanentlyDenied
.
If it is , it’ll open the settings page of the App for user by using openAppSettings()
provided by permission_handler package.
You can Alter the above code according to your requirements.
I think this post was useful to you. If it is, please do share this in your circle, so that more people can make use of this 😊. And Follow me on Twitter for getting more posts like these 😉.
Also if you found any mistakes or have any suggestions, don’t hesitate to ping me on my Twitter or to drop a mail at [email protected].
Sample AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.status_downloader">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:requestLegacyExternalStorage="true"
android:label="storage_demo"
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>