Java Android-外部存储的可用空间未正确显示
它是这样的:我正在开发一个应用程序,记录视频块。当它检测到可用空间落在某个树下时,它会尝试删除旧视频,直到可用存储量超过阈值。如果可用存储低于另一个阈值(低于第一个阈值),应用程序将停止录制并显示一个对话框,通知存储不足 我已经编写了一个类,可以帮助解决这些存储问题:Java Android-外部存储的可用空间未正确显示,java,android,storage,Java,Android,Storage,它是这样的:我正在开发一个应用程序,记录视频块。当它检测到可用空间落在某个树下时,它会尝试删除旧视频,直到可用存储量超过阈值。如果可用存储低于另一个阈值(低于第一个阈值),应用程序将停止录制并显示一个对话框,通知存储不足 我已经编写了一个类,可以帮助解决这些存储问题: package net.ghetu.dasheye; import java.io.File; import java.util.Collections; import java.util.Vector; import and
package net.ghetu.dasheye;
import java.io.File;
import java.util.Collections;
import java.util.Vector;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
class StorageManager extends Thread {
private static final String TAG = "StorageManager";
private static File mediaStorageDir = new File(
Environment.getExternalStorageDirectory(), "DashEyeApp");
private static long totalSpace = mediaStorageDir.getTotalSpace();
private static long full99 = (long) (0.01 * totalSpace);
private static long full97 = (long) (0.03 * totalSpace);
private boolean isStopped = false;
private Vector<VideoItem> directoryEntries = null;
private GlobalState mAppState;
private PreviewService mPreviewService;
public void setStopped() {
isStopped = true;
}
public StorageManager(Context appState, PreviewService previewService) {
mAppState = (GlobalState) appState;
mPreviewService = previewService;
}
public static boolean hasRunOutOufSpace() {
long freeSpace = Environment.getExternalStorageDirectory()
.getFreeSpace();
if (freeSpace <= full99)
return true;
return false;
}
public static boolean hasLowSpace() {
long freeSpace = new File(Environment.getExternalStorageDirectory(),
"DashEyeApp").getFreeSpace();
Log.d(TAG,
"Free space: "
+ Long.toString((long) (freeSpace / (1024 * 1024)))
+ "MB");
if (freeSpace <= full97)
return true;
return false;
}
@Override
public void run() {
super.run();
while (!isStopped) {
if (hasLowSpace()) {
if (hasRunOutOufSpace()) {
if (mPreviewService != null) {
if (mAppState.isRecording()) {
mPreviewService.stopRecording();
mPreviewService.displayStorageDialog();
isStopped = true;
} else {
mPreviewService.displayStorageDialog();
isStopped = true;
}
}
} else {
if (mAppState.detectLoopModeActive()) {
Log.d(TAG, "Making space ...");
directoryEntries = getAllVideos();
Log.d(TAG, Integer.toString(directoryEntries.size()));
if (directoryEntries.size() > 1) {
directoryEntries.get(directoryEntries.size() - 1)
.getmFile().delete();
directoryEntries
.remove(directoryEntries.size() - 1);
}
directoryEntries.clear();
}
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private Vector<VideoItem> getAllVideos() {
Vector<VideoItem> directoryEntries = new Vector<VideoItem>();
File files[] = mediaStorageDir.listFiles();
if (files != null) {
if (files.length > 0) {
for (File file : files) {
if (VideoDetector.isVideo(file))
directoryEntries.add(new VideoItem(file));
}
Collections.sort(directoryEntries,
VideoItem.VideoDateComparatorDesc);
}
}
files = null;
Log.d(TAG,
"Fetching files: " + directoryEntries.size() + " files US: "
+ mediaStorageDir.getUsableSpace() + " FS: "
+ mediaStorageDir.getFreeSpace());
return directoryEntries;
}
}
不考虑删除视频所获得的可用空间。下面是日志示例:
03-11 00:19:54.995: D/StorageManager(2863): Free space: 236MB
03-11 00:19:54.995: D/StorageManager(2863): Making space ...
03-11 00:19:55.015: D/StorageManager(2863): Fetching files: 3 files US: 248168448 FS: 248168448
03-11 00:19:55.015: D/StorageManager(2863): 3
03-11 00:20:00.015: D/StorageManager(2863): Free space: 230MB
03-11 00:20:00.015: D/StorageManager(2863): Making space ...
03-11 00:20:00.030: D/StorageManager(2863): Fetching files: 2 files US: 242081792 FS: 242081792
03-11 00:20:00.030: D/StorageManager(2863): 2
请注意,可用空间会减少,而文件夹中的视频数量也会减少。
你知道为什么会这样吗?在这一点上,我是绝望的,并愿意尝试一切。在三星Galaxy i9305上的Android 4.4.4中遇到此错误。在Galaxy S1 GT-i9000上有相同的问题,该Galaxy S1 GT-i9000带有定制的Android 4.4.4 ROM。正如Android开发人员所说的“getFreeSpace方法返回可能可供root用户使用的字节数”。因此,如果不以root身份运行,则无法使用它。所以我有一个方法来计算可用的块字节
public static float megabytesAvailable(File f) {
StatFs stat = new StatFs(f.getPath());
long bytesAvailable = (long)stat.getBlockSizeLong() * (long)stat.getAvailableBlocksLong();
return bytesAvailable / (1024.f * 1024.f);
}
Android Doc说getFreeSpace()方法返回root用户可能可用的字节数,而getUsableSpace()返回非root用户可用的空闲字节数
您可以尝试getUsableSpace()。Hm,是否显示不正确?那么,如果你的手机显示230MB,那么它有多少空闲空间呢?它应该有更多的空间。如果您签出日志,它首先有236MB,包含3个文件,删除一个文件后,它的大小小于这一大小(230MB)。删除文件应该会释放空间,尽管看起来不会。为什么要使用Long.toString?为什么不使用String.valueOf?也许我还不清楚:问题是getFreeSpace()返回错误的值。
public static float megabytesAvailable(File f) {
StatFs stat = new StatFs(f.getPath());
long bytesAvailable = (long)stat.getBlockSizeLong() * (long)stat.getAvailableBlocksLong();
return bytesAvailable / (1024.f * 1024.f);
}