在咱們作App開發的過程當中基本上都會用到文件存儲,因此文件存儲對於咱們來講是至關熟悉了,不過自從Android 6.0發佈以後,基於運行時權限機制訪問外置sdcard是須要動態申請權限,因此以往直接sdcard根目錄上直接新建了一個xxx/cache/
目錄來作文件存儲就會不是那麼容易控制了,因此有必要從新認識一下Android文件存儲的相關知識了。android
有關外置sdcard的讀寫權限算法
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
在Android 6.0 以前只要申明瞭上述兩個權限就能夠放心大膽的在sdcard上進行讀寫了,惋惜Android 6.0以後就須要動態申請讀寫權限了,因此咱們該如何適配Android 6.0來進行文件存儲。首先咱們在使用文件存儲的時候儘可能作到如下幾點:瀏覽器
不要隨意佔用用戶的內置存儲緩存
不要隨意在SD卡上新建目錄,應該放置本身應用包名對應的擴展存儲目錄下,卸載App時能夠被自動清除。app
對佔用的磁盤空間有上限,並按照必定的策略進行清除,好比DiskLru算法等。學習
訪問方式 | 詳細路徑 | 是否須要申請權限 |
Context.getFileDir();獲取內置存儲下的文件目錄,能夠用來保存不能公開給其餘應用的一些敏感數據如用戶我的信息spa |
/data/data/應用包名/files/ | 否 |
Context.getCacheDir();獲取內置存儲下的緩存目錄,能夠用來保存一些緩存文件如圖片,當內置存儲的空間不足時將系統自動被清除日誌 |
/data/data/應用包名/cache/ | 否 |
注意:code
因爲這裏使用的是Android 手機內置存儲,若是手機沒有得到root權限的話文件瀏覽器是沒法訪問的,一樣這種存儲也會隨之app被刪除而被刪除。orm
訪問方式 | 路徑詳情 | 是否須要申請權限 |
|
SDCard/Android/data/應用包名/files/ |
API < 19:是 API >= 19:否 |
|
SDCard/Android/data/應用包名/cache/ |
API < 19:是 API >= 19:否 |
注意:
因爲存儲在sdcard上因此儘可能不要存在敏感數據好比用戶信息等,這裏的文件也會隨着app 被刪除而被刪除。
訪問方式 | 路徑詳情 | 是否須要申請權限 |
Environment.getExternalStorageDirectory();獲取sdcard根目錄 | SDCard/xxx文件夾名字/ | 是 |
注意:
有時咱們也是須要存儲一些公共文件,並且但願這些文件可以不隨着App被刪除而被刪除,例如咱們錄製的視頻或者下載的音樂等。因爲這個目錄能夠被任何app訪問,因此咱們在使用的時候是須要申請權限的。
前提:這裏主要處理一些非永久保存數據,須要永久保存的數據儘可能仍是要選擇sdcard 公共存儲方式的。
/** * 獲取app的根目錄 * * @return 文件緩存根路徑 */ public static String getDiskCacheRootDir() { File diskRootFile; if (existsSdcard()) { diskRootFile = LeeApplication.getApp().getExternalCacheDir(); } else { diskRootFile = LeeApplication.getApp().getCacheDir(); } String cachePath; if (diskRootFile != null) { cachePath = diskRootFile.getPath(); } else { throw new IllegalArgumentException("disk is invalid"); } return cachePath; }
這裏須要判斷sdcard是否可用
/** * 判斷外置sdcard是否能夠正常使用 * * @return */ public static Boolean existsSdcard() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable(); }
/** * 獲取相關功能業務目錄 * * @return 文件緩存路徑 */ public static String getDiskCacheDir(String dirName) { String dir = String.format("%s/%s/", getDiskCacheRootDir(), dirName); File file = new File(dir); if (!file.exists()) { boolean isSuccess = file.mkdirs(); if (isSuccess) { Log.d(TAG, "dir mkdirs success"); } } return file.getPath(); }
在平常開發過程當中,咱們須要不一樣的文件放在不一樣的目錄下,好比:log日誌文件須要放在log文件下,就能夠經過上面的方法傳入「log」獲取該業務功能的文件夾。
/** * 獲取log日誌根目錄 * @return */ public static String getLogDir(){ return getDiskCacheDir(LOG); } /** * 根據logName 獲取log文件全路徑 * @param logName * @return */ public static String getLogFilePath(String logName){ return getLogDir()+logName; }
今天總結了Android的文件存儲及在6.0上的適配問題,最近忽然以爲本身有太多的知識須要學習了,也許因爲如今的經濟大環境致使互聯網遇到了資本寒冬了,其實對於我來講2012年已經經歷過一次了,對於技術人員來講應該冷靜的看待這個問題,須要作的就是在寒冬裏播種但願,那就是學習。以此共勉之~