Skip to content

Commit

Permalink
Introduced new method for checking storage space for a specified path…
Browse files Browse the repository at this point in the history
… & upgraded flutter embedding/dependencies (#3)

* switch to embedding v2

* migrate to AndroidX

* maintain compatibility with embedding v1

* upgrade dependencies

* added function to check available space for a specified directory

* fix v1 embedding

* added check if path exists
  • Loading branch information
phipps980316 authored Sep 15, 2021
1 parent 3eec249 commit 0e8941f
Show file tree
Hide file tree
Showing 14 changed files with 198 additions and 57 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
.pub/

build/
.idea/libraries/Dart_SDK.xml
.idea/workspace.xml
example/.flutter-plugins-dependencies
8 changes: 4 additions & 4 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ group 'de.appgewaltig.disk_space'
version '1.0-SNAPSHOT'

buildscript {
ext.kotlin_version = '1.3.50'
ext.kotlin_version = '1.3.72'
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:4.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand All @@ -25,14 +25,14 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 28
compileSdkVersion 30

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 16
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
lintOptions {
disable 'InvalidPackage'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,32 @@
package de.appgewaltig.disk_space

import android.os.Environment
import android.os.StatFs
import io.flutter.plugin.common.MethodCall
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.BinaryMessenger
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
import io.flutter.plugin.common.PluginRegistry

class DiskSpacePlugin: FlutterPlugin {

class DiskSpacePlugin: MethodCallHandler {
companion object {
private var channel: MethodChannel? = null
private var handler: MethodHandlerImpl = MethodHandlerImpl()

@JvmStatic
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "disk_space")
channel.setMethodCallHandler(DiskSpacePlugin())
fun registerWith(registrar: PluginRegistry.Registrar) {
registerChannel(registrar.messenger())
}
}

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 registerChannel(messenger: BinaryMessenger) {
channel = MethodChannel(messenger, "disk_space")
channel!!.setMethodCallHandler(handler)
}
}

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 onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
registerChannel(binding.binaryMessenger)
}


override fun onMethodCall(call: MethodCall, result: Result) {
when(call.method) {
"getFreeDiskSpace" -> result.success(getFreeDiskSpace())
"getTotalDiskSpace" -> result.success(getTotalDiskSpace())
else -> result.notImplemented()
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel = null
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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

class MethodHandlerImpl : MethodChannel.MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when(call.method) {
"getFreeDiskSpace" -> result.success(getFreeDiskSpace())
"getTotalDiskSpace" -> result.success(getTotalDiskSpace())
"getFreeDiskSpaceForPath" -> result.success(getFreeDiskSpaceForPath(call.argument<String>("path")!!))
else -> result.notImplemented()
}
}

private fun getFreeDiskSpace(): Double {
val stat = StatFs(Environment.getExternalStorageDirectory().path)

val bytesAvailable: Long
bytesAvailable = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
stat.blockSizeLong * stat.availableBlocksLong
else
stat.blockSize.toLong() * stat.availableBlocks.toLong()
return (bytesAvailable / (1024f * 1024f)).toDouble()
}

private fun getFreeDiskSpaceForPath(path: String): Double {
val stat = StatFs(path)

val bytesAvailable: Long
bytesAvailable = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
stat.blockSizeLong * stat.availableBlocksLong
else
stat.blockSize.toLong() * stat.availableBlocks.toLong()
return (bytesAvailable / (1024f * 1024f)).toDouble()
}

private fun getTotalDiskSpace(): Double {
val stat = StatFs(Environment.getExternalStorageDirectory().path)

val bytesAvailable: Long
bytesAvailable = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
stat.blockSizeLong * stat.blockCountLong
else
stat.blockSize.toLong() * stat.blockCount.toLong()
return (bytesAvailable / (1024f * 1024f)).toDouble()
}
}
11 changes: 6 additions & 5 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 28
compileSdkVersion 30

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -40,10 +40,10 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "de.appgewaltig.disk_space_example"
minSdkVersion 16
targetSdkVersion 28
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

buildTypes {
Expand All @@ -62,6 +62,7 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
14 changes: 14 additions & 0 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
android:name=".EmbeddingV1Activity"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package de.appgewaltig.disk_space_example

import android.os.Bundle
import de.appgewaltig.disk_space.DiskSpacePlugin
import io.flutter.app.FlutterActivity


class EmbeddingV1Activity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DiskSpacePlugin.registerWith(registrarFor("de.appgewaltig.disk_space.DiskSpacePlugin"))
}
}
4 changes: 2 additions & 2 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.3.41'
ext.kotlin_version = '1.3.72'
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:4.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
2 changes: 2 additions & 0 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M

2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
44 changes: 42 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:disk_space/disk_space.dart';
import 'package:path_provider/path_provider.dart';

void main() => runApp(MyApp());

Expand All @@ -13,6 +16,7 @@ class MyApp extends StatefulWidget {

class _MyAppState extends State<MyApp> {
double _diskSpace = 0;
Map<Directory, double> _directorySpace = {};

@override
void initState() {
Expand All @@ -25,10 +29,31 @@ class _MyAppState extends State<MyApp> {

diskSpace = await DiskSpace.getFreeDiskSpace;

List<Directory> directories;
Map<Directory, double> directorySpace = {};

if (Platform.isIOS) {
directories = [await getApplicationDocumentsDirectory()];
} else if (Platform.isAndroid) {
directories =
await getExternalStorageDirectories(type: StorageDirectory.movies)
.then(
(list) async => list ?? [await getApplicationDocumentsDirectory()],
);
} else {
return [];
}

for (var directory in directories) {
var space = await DiskSpace.getFreeDiskSpaceForPath(directory.path);
directorySpace.addEntries([MapEntry(directory, space)]);
}

if (!mounted) return;

setState(() {
_diskSpace = diskSpace;
_directorySpace = directorySpace;
});
}

Expand All @@ -39,8 +64,23 @@ class _MyAppState extends State<MyApp> {
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Space on device (MB): $_diskSpace\n'),
body: Column(
children: [
Center(
child: Text('Space on device (MB): $_diskSpace\n'),
),
Center(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
var key = _directorySpace.keys.elementAt(index);
var value = _directorySpace[key];
return Text('Space in ${key.path} (MB): $value\n');
},
itemCount: _directorySpace.keys.length,
),
),
],
),
),
);
Expand Down
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dev_dependencies:

disk_space:
path: ../
path_provider: ^2.0.2

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down
26 changes: 26 additions & 0 deletions ios/Classes/SwiftDiskSpacePlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class SwiftDiskSpacePlugin: NSObject, FlutterPlugin {
result(UIDevice.current.freeDiskSpaceInMB)
case "getTotalDiskSpace":
result(UIDevice.current.totalDiskSpaceInMB)
case "getFreeDiskSpaceForPath":
result(UIDevice.current.freeDiskSpaceForPathInMB(path: (call.arguments as? [String: String])!["path"]!))
default:
result(0.0)
}
Expand All @@ -34,6 +36,12 @@ extension UIDevice {
var usedDiskSpaceInMB:Double {
return Double(usedDiskSpaceInBytes / (1024 * 1024))
}

public func freeDiskSpaceForPathInMB(path: String) -> Double {
return Double(freeDiskSpaceForPathInBytes(path: path) / (1024 * 1024))
}



//MARK: Get raw value
var totalDiskSpaceInBytes:Int64 {
Expand Down Expand Up @@ -67,6 +75,24 @@ extension UIDevice {
var usedDiskSpaceInBytes:Int64 {
return totalDiskSpaceInBytes - freeDiskSpaceInBytes
}

public func freeDiskSpaceForPathInBytes(path: String) -> Int64 {
if #available(iOS 11.0, *) {
if let space = try? URL(fileURLWithPath: path).resourceValues(forKeys: [URLResourceKey.volumeAvailableCapacityForImportantUsageKey]).volumeAvailableCapacityForImportantUsage {
return space ?? 0
} else {
return 0
}
} else {
if let systemAttributes = try? FileManager.default.attributesOfFileSystem(forPath: path),
let freeSpace = (systemAttributes[FileAttributeKey.systemFreeSize] as? NSNumber)?.int64Value {
return freeSpace
} else {
return 0
}
}

}

}

Loading

0 comments on commit 0e8941f

Please sign in to comment.