英文:
Flutter: Check Device Available Storage using Dart
问题
如何检查设备存储是否足够,是否可以在Flutter中实现而无需本地操作?我想知道设备是否有足够的存储空间来下载图片。如何实现这一点?
英文:
How to check device storage is it possible to do it in Flutter without doing natively? I want to know if the device has enough storage to download images. How to achieve this?
答案1
得分: 15
有一个名为disk_space的包,允许您获取您要查找的确切信息。您可以像这样使用它:
import 'package:disk_space/disk_space.dart';
void getDiskSpaceInfo() async{
print(await DiskSpace.getFreeDiskSpace);
print(await DiskSpace.getTotalDiskSpace);
}
编辑:此包已于2021年3月9日升级到Dart 2.12的版本0.1.0+2。但仍然没有GitHub链接。
英文:
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.
答案2
得分: 4
我已经为您翻译了您提供的代码部分,如下所示:
一个可能性是使用已经提到的 `DiskSpace` 并稍作更改。
该库包含两个文件:
-------------------------------
`disk_space.dart`:
```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;
}
}
和
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()
}
}
}
我的更改:
我已经添加了另一个通道方法(并在KT文件中添加了一个用于获取内部存储的方法):
class DiskSpacePlugin: MethodCallHandler {
...
private fun getFreeDiskSpace(path: String): Double {
val stat = StatFs(path) // 动态路径来自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) // 更改为获取内部目录
...
}
private fun getFreeExternalDiskSpace(): Double {...} // 更改名称以反映外部目录
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)) // 添加了这个
}
"getFreeInternalDiskSpace" -> result.success(getFreeInternalDiskSpace())
"getFreeExternalDiskSpace" -> result.success(getFreeExternalDiskSpace())
"getTotalDiskSpace" -> result.success(getTotalDiskSpace())
else -> result.notImplemented()
}
}
}
在 FlutterActivity
中注册了插件:
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
DiskSpacePlugin.registerWith(registrarFor("<your_package>.DiskSpacePlugin"));
}
}
添加了一个 Storage
辅助类:
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,
);
}
}
现在您可以从Dart代码中调用这些方法:
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:如果有人与DiskSpace库的开发者有联系,您可以询问他是否愿意将所提到的内容添加到库中。谢谢!
英文:
One of the possibilities is to use already mentioned DiskSpace
with a bit of a change.
The library contains two files:
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()
}
}
}
My changes:
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
答案3
得分: 0
以下是翻译好的部分:
"扩展存储空间的测试是"
"private fun getFreeDiskSpace(): Double {"
"private fun getTotalDiskSpace(): Double {"
英文:
The test is to expand the storage space
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
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()
}
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论