詳解Android數(shù)據(jù)存儲之Android 6.0運行時權限下文件存儲的思考
前言:
在我們做App開發(fā)的過程中基本上都會用到文件存儲,所以文件存儲對于我們來說是相當熟悉了,不過自從Android 6.0發(fā)布之后,基于運行時權限機制訪問外置sdcard是需要動態(tài)申請權限,所以以往直接sdcard根目錄上直接新建了一個xxx/cache/目錄來做文件存儲就會不是那么容易控制了,所以有必要重新認識一下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之后就需要動態(tài)申請讀寫權限了,所以我們該如何適配Android 6.0來進行文件存儲。首先我們在使用文件存儲的時候盡量做到以下幾點:
- 不要隨意占用用戶的內置存儲
- 不要隨意在SD卡上新建目錄,應該放置自己應用包名對應的擴展存儲目錄下,卸載App時可以被自動清除。
- 對占用的磁盤空間有上限,并按照一定的策略進行清除,比如DiskLru算法等。
Android文件存儲目錄:
1.)應用私有存儲(內置存儲)
| 訪問方式 | 詳細路徑 | 是否需要申請權限 |
|
Context.getFileDir();獲取內置存儲下的文件目錄,可以用來保存不能公開給其他應用的一些敏感數(shù)據(jù)如用戶個人信息 |
/data/data/應用包名/files/ | 否 |
|
Context.getCacheDir();獲取內置存儲下的緩存目錄,可以用來保存一些緩存文件如圖片,當內置存儲的空間不足時將系統(tǒng)自動被清除 |
/data/data/應用包名/cache/ | 否 |
注意:
由于這里使用的是Android 手機內置存儲,如果手機沒有獲得root權限的話文件瀏覽器是無法訪問的,同樣這種存儲也會隨之app被刪除而被刪除。
2.)應用擴展存儲(SD卡)
| 訪問方式 | 路徑詳情 | 是否需要申請權限 |
|
|
SDCard/Android/data/應用包名/files/ |
API < 19:是 API >= 19:否 |
|
|
SDCard/Android/data/應用包名/cache/ |
API < 19:是 API >= 19:否 |
注意:
由于存儲在sdcard上所以盡量不要存在敏感數(shù)據(jù)比如用戶信息等,這里的文件也會隨著app 被刪除而被刪除。
3.)公共存儲(SD卡)
| 訪問方式 | 路徑詳情 | 是否需要申請權限 |
| Environment.getExternalStorageDirectory();獲取sdcard根目錄 | SDCard/xxx文件夾名字/ | 是 |
注意:
有時我們也是需要存儲一些公共文件,而且希望這些文件能夠不隨著App被刪除而被刪除,例如我們錄制的視頻或者下載的音樂等。由于這個目錄可以被任何app訪問,所以我們在使用的時候是需要申請權限的。
兼容Android 6.0 文件緩存實現(xiàn)
前提:這里主要處理一些非永久保存數(shù)據(jù),需要永久保存的數(shù)據(jù)盡量還是要選擇sdcard 公共存儲方式的。
1.)獲取緩存根目錄
/**
* 獲取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();
}
2.)獲取指定功能的目錄
/**
* 獲取相關功能業(yè)務目錄
*
* @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();
}
在日常開發(fā)過程中,我們需要不同的文件放在不同的目錄下,比如:log日志文件需要放在log文件下,就可以通過上面的方法傳入“l(fā)og”獲取該業(yè)務功能的文件夾。
3.)獲取指定功能文件路徑
/**
* 獲取log日志根目錄
* @return
*/
public static String getLogDir(){
return getDiskCacheDir(LOG);
}
/**
* 根據(jù)logName 獲取log文件全路徑
* @param logName
* @return
*/
public static String getLogFilePath(String logName){
return getLogDir()+logName;
}
總結:
今天總結了Android的文件存儲及在6.0上的適配問題,最近突然覺得自己有太多的知識需要學習了,也許由于現(xiàn)在的經濟大環(huán)境導致互聯(lián)網遇到了資本寒冬了,其實對于我來說2012年已經經歷過一次了,對于技術人員來說應該冷靜的看待這個問題,需要做的就是在寒冬里播種希望,那就是學習。以此共勉之~
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android?14新功能HighLights快速實現(xiàn)文本高亮
這篇文章主要為大家介紹了Android?14新功能HighLights快速實現(xiàn)文本高亮示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03
Flutter?WebView?預加載實現(xiàn)方法(Http?Server)
這篇文章主要介紹了Flutter?WebView?預加載實現(xiàn)方法,包括資源的配置,資源的下載和存儲,版本的管理,如何根據(jù)實際url獲取對應HttpServer?bind的url等,需要的朋友可以參考下2022-05-05
Android將camera獲取到的YuvData在jni中轉化為Mat方法
今天小編就為大家分享一篇Android將camera獲取到的YuvData在jni中轉化為Mat方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
通過實例簡單講解Android App中的Activity組件
這篇文章主要介紹了通過Android App中的Activity組件,包括Activity的定義和繼承以及啟動等基本知識,需要的朋友可以參考下2016-04-04
詳解Android 多級聯(lián)動控件實現(xiàn)思路討論
這篇文章主要介紹了詳解Android 多級聯(lián)動控件實現(xiàn)思路討論,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11
Android 6.0以上權限拒絕打開權限設置界面的解決方法
今天小編就為大家分享一篇Android 6.0以上權限拒絕打開權限設置界面的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07

