考慮FileProvider
問題,也因爲我想實現對採集的臨時文件最大緩存大小,我去了ContentProvider
解決方案,它的工作原理治療。基本上,您可以毫無問題地使用內部緩存,但仍可向第三方應用程序提供一個可用於引用要與之共享的臨時文件的URI。因爲你使用你的內部緩存,所以不會有不必要的WRITE_EXTERNAL_STORAGE
許可請求。
增加的最大緩存大小限制(您可以通過簡單地刪除從checkSize()
到課程末尾的所有內容(例如,如果您可以確保在共享之後直接刪除所有文件,則可以從課程中刪除)保留在設備上)通過檢查每次調用時的累積最大大小並在必要時清除一半高速緩存(刪除最早的文件)來工作。
public class TemporaryFile extends ContentProvider {
private static final long MAX_SIZE = 512 * 1024;
// commented out on purpose so that you don't forget to rewrite it...
// public static final String AUTHORITY = "com.example.tempfile";
private UriMatcher uriMatcher;
@Override
public boolean onCreate() {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "*", 1);
return true;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
if (uriMatcher.match(uri) == 1) {
final String file = getContext().getCacheDir() + File.separator + uri.getLastPathSegment();
return ParcelFileDescriptor.open(new File(file), ParcelFileDescriptor.MODE_READ_ONLY);
}
else
throw new FileNotFoundException(uri.toString());
}
@Override
public int update (Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int delete (Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return null;
}
public static File getFile(Context context, String prefix, String extension) throws IOException {
checkSize(context);
File file = File.createTempFile(prefix, extension, context.getCacheDir());
file.setReadable(true);
file.deleteOnExit();
return file;
}
public static Uri getPublicUri(File file) {
return Uri.withAppendedPath(Uri.parse("content://" + AUTHORITY), file.getName());
}
public static void checkSize(Context context) throws IOException {
File dir = context.getCacheDir();
if (getDirSize(dir) > MAX_SIZE)
cleanDir(dir, MAX_SIZE/2);
}
private static long getDirSize(File dir) {
long size = 0;
for (File file : dir.listFiles())
if (file.isFile())
size += file.length();
return size;
}
private static void cleanDir(File dir, long atLeast) {
long deleted = 0;
File[] files = dir.listFiles();
Arrays.sort(files, new Comparator<File>() {
public int compare(File f1, File f2) {
return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
}
});
for (File file : files) {
deleted += file.length();
file.delete();
if (deleted >= atLeast)
break;
}
}
}
使用它,不能再簡單,只需撥打
File file = TemporaryFile.getFile(this, "prefix", ".extension");
,每當你想創建一個新的文件,並
TemporaryFile.getPublicUri(file)
,只要你想獲得公衆開放的到文件,例如。將其傳遞給數據或Intent.EXTRA_STREAM
。
作爲一個供應商,不要忘了添加必要的清單條目,或者:
<provider
android:name=".TemporaryFile"
android:authorities="com.example.tempfile"
android:exported="true"
tools:ignore="ExportedContentProvider" >
</provider>
什麼是'destFile'的價值? – CommonsWare 2014-08-27 19:39:43
我建議你看看https://developer.android.com/reference/android/support/v4/content/FileProvider.html – Simon 2014-08-27 19:47:16
@Simon我會測試它併發布結果。看起來這正是我需要的!請注意,這些圖像適用於許多其他應用程序。另外,添加了「destFile」的描述。 – 2014-08-28 20:38:00