如何检查设备存储,是否可以在Flutter中实现而不需要本地操作?我想知道设备是否有足够的存储空间来下载图片。如何实现这一点?
有一个名为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。
其中一种可能性是使用之前提到的DiskSpace
,稍作修改即可。
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()
}
}
}
我添加了另一种通道方法(以及一个用于获取内部存储的KT文件方法):
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()
}
}
}
在 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库开发者的联系方式,可以询问他是否能够将提到的某些内容添加到库中?谢谢。
测试是扩展存储空间
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()
}
DiskSpace.getTotalDiskSpace
只访问内部存储还是包括SD卡存储吗?我尝试将其实现到我的项目中,但与手机上的空间相比,我得到了不同的结果。 - wahyu