How to check device storage is it possible to do in flutter by without doing natively. I want to know if the device has enough storage to download images. How to achieve this
There is a package called disk_space that allows you to get exactly the information you are looking for. You can use it like this:
import 'package:disk_space/disk_space.dart';
void getDiskSpaceInfo() async{
print(await DiskSpace.getFreeDiskSpace);
print(await DiskSpace.getTotalDiskSpace);
}
EDIT: This package has been updated to version 0.1.0+2 for Dart 2.12 on Mar 9, 2021. But still has no link to GitHub.
One of the possibilities is to use already mentioned DiskSpace
with a bit of a change.
disk_space.dart
:
import 'dart:async';
import 'package:flutter/services.dart';
class DiskSpace {
static const MethodChannel _channel =
const MethodChannel('disk_space');
static Future<String?> get platformVersion async {
final String? version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
static Future<double?> get getFreeDiskSpace async {
final double? freeDiskSpace = await _channel.invokeMethod('getFreeDiskSpace');
return freeDiskSpace;
}
static Future<double?> get getTotalDiskSpace async {
final double? totalDiskSpace = await _channel.invokeMethod('getTotalDiskSpace');
return totalDiskSpace;
}
}
and
DiskSpacePlugin.kt
:
package de.appgewaltig.disk_space
import android.os.Environment
import android.os.StatFs
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar
class DiskSpacePlugin: MethodCallHandler {
companion object {
@JvmStatic
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "disk_space")
channel.setMethodCallHandler(DiskSpacePlugin())
}
}
private fun getFreeDiskSpace(): Double {
val stat = StatFs(Environment.getExternalStorageDirectory().path)
var bytesAvailable: Long
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
bytesAvailable = stat.blockSizeLong * stat.availableBlocksLong
else
bytesAvailable = stat.blockSize.toLong() * stat.availableBlocks.toLong()
return (bytesAvailable / (1024f * 1024f)).toDouble()
}
private fun getTotalDiskSpace(): Double {
val stat = StatFs(Environment.getExternalStorageDirectory().path)
var bytesAvailable: Long
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
bytesAvailable = stat.blockSizeLong * stat.blockCountLong
else
bytesAvailable = stat.blockSize.toLong() * stat.blockCount.toLong()
return (bytesAvailable / (1024f * 1024f)).toDouble()
}
override fun onMethodCall(call: MethodCall, result: Result) {
when(call.method) {
"getFreeDiskSpace" -> result.success(getFreeDiskSpace())
"getTotalDiskSpace" -> result.success(getTotalDiskSpace())
else -> result.notImplemented()
}
}
}
I've added another channel method (and a method to the KT file to get internal storage):
class DiskSpacePlugin: MethodCallHandler {
...
private fun getFreeDiskSpace(String path): Double {
val stat = StatFs(path) // dynamic path from the Flutter
var bytesAvailable: Long
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
bytesAvailable = stat.blockSizeLong * stat.availableBlocksLong
else
bytesAvailable = stat.blockSize.toLong() * stat.availableBlocks.toLong()
return (bytesAvailable / (1024f * 1024f)).toDouble()
}
private fun getFreeInternalDiskSpace(): Double {
val stat = StatFs(Environment.getDataDirectory().path) // changed to get internal directory
...
}
private fun getFreeExternalDiskSpace(): Double {...} // Changed name to reflect external directory
private fun getTotalDiskSpace(): Double {...}
override fun onMethodCall(call: MethodCall, result: Result) {
when(call.method) {
"getFreeDiskSpace" -> {
var path = call.argument("path") as String
result.success(getFreeDiskSpace(path)) // added this
}
"getFreeInternalDiskSpace" -> result.success(getFreeInternalDiskSpace())
"getFreeExternalDiskSpace" -> result.success(getFreeExternalDiskSpace())
"getTotalDiskSpace" -> result.success(getTotalDiskSpace())
else -> result.notImplemented()
}
}
}
Registered the Plugin in the FlutterActivity
:
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
DiskSpacePlugin.registerWith(registrarFor("<your_package>.DiskSpacePlugin"));
}
}
Added a Storage
helper:
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class Storage {
static Future<Directory> internal() async {
return getApplicationDocumentsDirectory();
}
static Future<Directory> external() async {
return getExternalStorageDirectory();
}
static Future<Directory> sdCard() async {
return (await getExternalStorageDirectories()).firstWhere(
(directory) => !directory.path.contains("emulated"),
orElse: () => null,
);
}
}
And now you can call these from the dart code:
static const MethodChannel _channel = const MethodChannel('disk_space');
void getFreeMemory() async {
final String internal = (await Storage.internal()).path;
final String external = (await Storage.external()).path;
final String sdCard = (await Storage.sdCard()).path;
final double freeDiskSpace = await _channel.invokeMethod('getFreeDiskSpace', {"path": internal});
final double freeExternalDiskSpace = await _channel.invokeMethod('getFreeDiskSpace', {"path": external});
if (sdCard != null) {
final double freeSdCardSpace = await _channel.invokeMethod('getFreeDiskSpace', {"path": sdCard});
}
}
PS: If someone has a contact to the DiskSpace lib developer - what if ask him to add something mentioned to the library? thx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With