最近項目在做視頻加解密的東西,由于時間比較趕,視頻在線解密播放沒時間做,所以將方案改成先下載到本地然后解密以后播放,加解密的部分放到以后文章分析。公司的測試人員在測試后問我,當APP卸載時下載到緩存路徑的視頻會不會自動刪除,這個時候才發現不會自動刪除,大寫的尷尬。。。。。。今天就講一下Android的文件緩存路徑。
一、基礎知識
應用程序在運行的過程中如果需要向手機上保存數據,一般是把數據保存在SDcard中的。大部分應用是直接在SDCard的根目錄下創建一個文件夾,然后把數據保存在該文件夾中。這樣當該應用被卸載后,這些數據還保留在SDCard中,留下了垃圾數據。如果你想讓你的應用被卸載后,與該應用相關的數據也清除掉,該怎么辦呢?
內存緩存目錄:
相對于應用的專屬SD卡緩存有兩個內存緩存地址:
Content. getCacheDir(); // /data/data/app_package_name/cache;
Content. getFilesDir(); // /data/data/app_package_name/files
這兩個目錄中的文件會隨著app的刪除而清空
SD卡緩存目錄:
當應用需要將圖片或者文件緩存到SD卡中時要去申請創建目錄,有下面幾種途徑
我們可以通過API調用應用專屬目錄:
Content.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
/storage/emulated/0/Android/data/app_package_name/files/Pictures
通過Context.getExternalFilesDir()方法可以獲取到 SDCard/Android/data/你的應用的包名/files/ 目錄,一
般放一些長時間保存的數據
Content.getExternalCacheDir();
/storage/emulated/0/Android/data/app_package_name/cache
通過Context.getExternalCacheDir()方法可以獲取到 SDCard/Android/data/你的應用包名/cache/目錄,一
般存放臨時緩存數據
如果使用上面的方法,當你的應用在被用戶卸載后,SDCard/Android/data/你的應用的包名/ 這個目錄下
的所有文件都會被刪除,不會留下垃圾信息。
而且上面二個目錄分別對應 設置->應用->應用詳情里面的”清除數據“與”清除緩存“選項
當系統版本大于等于4.4時,對通過上面4個API調用得到的目錄進行文件的讀寫操作不需要申請SD卡的讀寫權限,所以6.0及以上系統使用時也不需要動態申請讀寫權限
分別對應下圖:
image.png
外部公共存儲目錄:
如果你的APP產生的文件不需要隱藏,即對用戶是可見的,那么你可以把文件放在外部的公共存儲文件下面。我們可以通過下面的代碼獲取到公共存儲目錄。
Environment.getExternalStorageDirectory() //獲取到的其實是外部存儲的根目錄
Environment.getExternalStoragePublicDirectory() //獲取到得則是外部存儲的公共目錄
在訪問權限上是沒有區別的,不同點是getExternalStoragePublicDirectory()在運行的時候,會需要你帶有一個特定的參數來指定這些public的文件類型,以便于與其他public文件進行分類。參數類型包括DIRECTORY_MUSIC 或者 DIRECTORY_PICTURES. 如下:
public File getAlbumStorageDir(Context context, String albumName) {
// Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
二.緩存目錄API使用及方法封裝
package com.ubtechinc.alpha2_alexa.utils;
import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import com.ubtechinc.alpha2_alexa.common.NLog;
import java.io.File;
/**
* @author:liuhai
* @date:2017/10/14 14:47
* @modifier:ubt
* @modify_date:2017/10/14 14:47
* 文件緩存存儲
* version
*/
public class FileUtils {
/**
* 獲取應用專屬緩存目錄
* android 4.4及以上系統不需要申請SD卡讀寫權限
* 因此也不用考慮6.0系統動態申請SD卡讀寫權限問題,切隨應用被卸載后自動清空 不會污染用戶存儲空間
*
* @param context 上下文
* @param type 文件夾類型 可以為空,為空則返回API得到的一級目錄
* @return 緩存文件夾 如果沒有SD卡或SD卡有問題則返回內存緩存目錄,否則優先返回SD卡緩存目錄
*/
public static String getCacheDirectory(Context context, String type) {
File appCacheDir = getExternalCacheDirectory(context, type);
if (appCacheDir == null) {
appCacheDir = getInternalCacheDirectory(context, type);
}
if (appCacheDir == null) {
NLog.e("FileUtils", "getCacheDirectory fail ,the reason is mobile phone unknown exception !");
} else {
if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
NLog.e("FileUtils", "getCacheDirectory fail ,the reason is make directory fail !");
}
}
NLog.d("FileUtil", "appCacheDir===" + appCacheDir.getPath() + File.separator);
return appCacheDir.getPath() + File.separator;
}
/**
* 獲取SD卡緩存目錄
*
* @param context 上下文
* @param type 文件夾類型 如果為空則返回 /storage/emulated/0/Android/data/app_package_name/cache
* 否則返回對應類型的文件夾如Environment.DIRECTORY_PICTURES 對應的文件夾為 .../data/app_package_name/files/Pictures
* {@link android.os.Environment#DIRECTORY_MUSIC},
* {@link android.os.Environment#DIRECTORY_PODCASTS},
* {@link android.os.Environment#DIRECTORY_RINGTONES},
* {@link android.os.Environment#DIRECTORY_ALARMS},
* {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
* {@link android.os.Environment#DIRECTORY_PICTURES}, or
* {@link android.os.Environment#DIRECTORY_MOVIES}.or 自定義文件夾名稱
* @return 緩存目錄文件夾 或 null(無SD卡或SD卡掛載失敗)
*/
public static File getExternalCacheDirectory(Context context, String type) {
File appCacheDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
if (TextUtils.isEmpty(type)) {
appCacheDir = context.getExternalCacheDir();
} else {
appCacheDir = context.getExternalFilesDir(type);
}
if (appCacheDir == null) {// 有些手機需要通過自定義目錄
appCacheDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/cache/" + type);
}
if (appCacheDir == null) {
NLog.e("FileUtils", "getExternalDirectory fail ,the reason is sdCard unknown exception !");
} else {
if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
NLog.e("FileUtils", "getExternalDirectory fail ,the reason is make directory fail !");
}
}
} else {
NLog.e("FileUtils", "getExternalDirectory fail ,the reason is sdCard nonexistence or sdCard mount fail !");
}
return appCacheDir;
}
/**
* 獲取內存緩存目錄
*
* @param type 子目錄,可以為空,為空直接返回一級目錄
* @return 緩存目錄文件夾 或 null(創建目錄文件失敗)
* 注:該方法獲取的目錄是能供當前應用自己使用,外部應用沒有讀寫權限,如 系統相機應用
*/
public static File getInternalCacheDirectory(Context context, String type) {
File appCacheDir = null;
if (TextUtils.isEmpty(type)) {
appCacheDir = context.getCacheDir();// /data/data/app_package_name/cache
} else {
appCacheDir = new File(context.getFilesDir(), type);// /data/data/app_package_name/files/type
}
if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
NLog.e("FileUtils", "getInternalDirectory fail ,the reason is make directory fail !");
}
return appCacheDir;
}
/**
* 刪除視頻文件
* @param context
* @param fileName 視頻文件名稱
*/
public static void clearCacheFile(Context context, String fileName) {
String filepath = getCacheDirectory(context, "");
File file = new File(filepath + fileName);
if (file.exists()) {
file.delete();
}
}
}
之前對文件緩存一直不了解,寫完文章后有一種恍然大明白的感覺