compileSDKversion
這個是編譯期間你所使用的api版本,一般越高越好,越高表示開發時可以
使用的api越新,并且可以避免使用被拋棄的sdk。
minSdkVersion
這個是支持的最小SDK版本,很好理解,在小于minSdkVersion的手機系統上無法安裝
targetSdkVersion
為兼容而生,使開發的app在各個版本的手機系統上表現一致,如果實際手機系統低于開發時定義的targetAPI,那么會以系統api版本為準。而如果實際手機系統的api版本高于開發時定義的targetApi,則會以targetSDK版本為準,缺點就是這樣會放棄了新版本的一些特性
在Android 10之前的版本上,我們在做文件的操作時都會申請存儲空間的讀寫權限。但是這些權限完全被濫用,造成的問題就是手機的存儲空間中充斥著大量不明作用的文件,并且應用卸載后它也沒有刪除掉。
為了解決這個問題,Android 10 中引入了Scoped Storage 的概念,通過添加外部存儲訪問限制來實現更好的文件管理。
存儲基本知識
首先明確一個概念,外部儲存和內部儲存。
- 內部儲存:/data 目錄。
獲取本應用的內部儲存路徑,讀寫該路徑下的文件不需要申請儲存空間讀寫權限,且卸載應用時會自動刪除。
一般我們使用getFilesDir() 方法,對應的目錄:`//data/data/com.face.myapplication/files`
getCacheDir() 方法,對應的目錄`/data/user/0/com.face.myapplication/cache`
- 外部儲存:/storage 或 /mnt 目錄。一般我們使用getExternalStorageDirectory()方法獲取的路徑來存取文件。
外部存儲 App私有目錄 (App卸載的時候,會被清除。)
Android/data/--->存儲各個App的外部私有目錄
與內部存儲類似,命名方式是:Android/data/xx------>xx指應用的包名。
如:/sdcard/Android/data/com.fish.myapplication
讀寫App外部私有目錄
private void testAppDir(Context context) {
//4個基本方法
File fileDir = context.getExternalFilesDir(null);
//API>=19
File[] fileList = context.getExternalFilesDirs(null);
File cacheDir = context.getExternalCacheDir();
//API>=19
File[] cacheList = context.getExternalCacheDirs();
//指定目錄,自動生成對應的子目錄
File fileDir2 = context.getExternalFilesDir(Environment.DIRECTORY_DCIM);
}
只要拿到根目錄,就可以遍歷尋找其它子目錄/文件。
private void testOtherDir(Context context) {
File rootDir = Environment.getExternalStorageDirectory();
}
返回的rootDir路徑:/storage/emulated/0/。
其它目錄
比如各個App在/sdcard/目錄下創建的目錄,如支付寶創建的目錄:alipy/,微博創建的目錄: com.sina.weibo/,qq創建的目錄:com.tencent.mobileqq/等。
以下目錄無需存儲權限即可訪問:
1、App自身的內部存儲
2、App自身的自帶外部存儲-私有目錄
剩下的都需要申請存儲權限,Android 10.0前后對于存儲作用域訪問的區別就體現在如何訪問剩余這些目錄內的文件。
其中比較容易混淆的是: 內部存儲與外部存儲里的App私有目錄,兩者命名風格很像。
不同點:
/data/data/com.fish.myapplication/ 位于內部存儲,一般用于存儲容量較小的,私密性較強的文件。而/sdcard/Android/data/com.fish.myapplication/ 位于外部存儲,作為App私有目錄,一般用于存儲容量較大的文件,即使刪除了也不影響App正常功能。
相同點:
屬于App專屬,App自身訪問兩者無需任何權限。
2、App卸載后,兩者皆被刪除。
3、兩者目錄下增加的文件最終會被統計到"設置->存儲和緩存"里。
因為不同廠商、系統版本的原因,所以上述的方法并沒有一個固定的文件路徑。了解了上面的概念,那我們所說的外部儲存訪問限制,可以認為是針對getExternalStorageDirectory()路徑下的文件。
Android 10.0 ( targetSdkVersion 改為 29)訪問方式變更
在Android 10 之前 ,用戶可以隨意在SD 卡創建文件目錄,比如我們能夠直接在/sdcard/目錄下創建目錄/文件。事實上,很多App就是這么干的,目錄結構很亂,而且App卸載后,對應的目錄并沒有刪除,于是就是遺留了很多"垃圾"文件,久而久之不處理,用戶的存儲空間越來越小。
總結弊端如下:
1、在設置里"Clear storage"或者"Clear cache"并不能刪除該目錄下的文件
2、卸載App也不能刪除該目錄下的文件
3、App可以隨意修改其它目錄下的文件,如修改別的App創建的文件等,不安全
好處:
1、此處新建的目錄不會被設置里的App存儲用量統計,讓用戶"看起來"自己的App占用的存儲空間很小
2、方便操作文件
面對眾多App隨意新建目錄/文件的現象,Google在Android 10.0上重拳出擊了引入Scoped Storage、分區存儲,原理如下:
App訪問自身內部存儲空間與 訪問外部存儲空間的App私有目錄不需要任何權限(這個與Android 10.0之前一致)
外部存儲空間-共享存儲空間、外部存儲空間-其它目錄 App無法通過路徑直接訪問,不能新建、刪除、修改目錄/文件等, 需要通過Uri訪問
適配
最簡單粗暴的方法就是在 AndroidManifest.xml 中添加 android:requestLegacyExternalStorage="true" 來請求使用舊的存儲模式。但是我不推薦此方法。因為在下一個版本的Android中,此條配置將會失效
- requestLegacyExternalStorage 是什么?通過翻查官方文檔,大概知道了這個屬性的意思:在配置targetSdk >= 29,應用搭載在Android 10及以上版本的手機運行時,可以暫時停用「分區存儲」
在AndroidManifest.xml 里application標簽下添加:
<application
android:requestLegacyExternalStorage="true"
...>