它是这样的:我正在开发一个记录视频块的应用程序。当它检测到可用空间低于某个阈值时,它会尝试删除旧视频,直到空闲存储量超过阈值。如果免费存储空间低于另一个阈值(低于第一个阈值),则应用程序将停止录制并显示一个对话框,通知存储空间不足。
我写过一个应该帮助解决这些存储问题的课程:
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;
}
}
然而,我的课对我没有帮助。会发生什么:视频被删除但hasLowSpace()仍然返回true。 I. e。
long freeSpace = new File(Environment.getExternalStorageDirectory(),
"DashEyeApp").getFreeSpace();
不考虑删除视频所获得的可用空间。下面是日志的样本:
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中的这个错误。在带有自定义Android 4.4.4 ROM的Galaxy S1 GT-i9000上遇到同样的问题。
答案 0 :(得分:1)
正如android开发人员所说&#34; getFreeSpace方法返回root&#34;可能可用的字节数。因此,如果不以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);
}
答案 1 :(得分:0)
Android Doc说getFreeSpace()方法返回root可能使用的字节数,而getUsableSpace()返回非root用户可用的空闲字节数。
您可以试试getUsableSpace()。