Android

【Android】Data and File Storage 內部儲存&外部儲存&分區儲存 範例

【Android】Data and File Storage 內部儲存&外部儲存&分區儲存 範例

Android Data and File Storage提供了方便且安全的數據和文件存儲解決方案,以保護用戶隱私和數據安全。

它可以為每個應用程序提供個人的儲存區,幫助保護數據,避免未授權的存取。

Android Data and File Storage 也支持內部和外部存儲設備,可以幫助用戶有效地管理數據,高效率地儲存和獲取信息。


文章目錄

  1. 內部儲存(Internal storage)
  2. 外部儲存(External storage)
  3. 分區儲存(Scope storage)
  4. 總結
  5. Developer Documents Data and File Storage

1.內部儲存(Internal storage)

1只有自己APP可以訪問到
2.檔案會隨著APP被刪除而遺失
File資料夾
val file = File(filesDir, "test.jpg")
file.createNewFile()
path:
data/user/0/{packageName}/files/test.jpg

Device File Explorer:
data/data/{packageName}/files/test.jpg
Cache資料夾
val cache = File(cacheDir, "test.jpg")
cache.createNewFile()
path:
data/user/0/{packageName}/cache/test.jpg

Device File Explorer:
data/data/{packageName}/cache/test.jpg
自訂資料夾名稱
val myFile = File(getDir("myFile", Context.MODE_PRIVATE), "test.jpg")
myFile.createNewFile()
path:
data/user/0/{packageName}/app_myFile/test.jpg

Device File Explorer:
data/data/{packageName}/app_myFile/test.jpg

2.外部儲存(External storage)

分為機身外部儲存&SD卡外部儲存
判斷是否有裝SD卡(有裝會回傳2個)
val files = getExternalFilesDirs(Environment.MEDIA_MOUNTED)

機身外部儲存

1.只有自己APP可以訪問到
2.檔案會隨著APP被刪除而遺失
File資料夾下自訂資料夾
val externalFilesDir = File(getExternalFilesDir("myFile"), "test.jpg")
externalFilesDir.createNewFile()
path:
storage/emulated/0/Android/data/{packageName}/files/myFile/test.jpg

Device File Explorer:
sdcard/Android/data/{packageName}/files/myFile/test.jpg
Cache資料夾
val externalCacheDir = File(externalCacheDir, "test.jpg")
externalCacheDir.createNewFile()
path:
storage/emulated/0/Android/data/{packageName}/cache/test.jpg

Device File Explorer:
sdcard/Android/data/{packageName}/cache/test.jpg

SD卡外部儲存

1.所有APP都可以訪問到
2.檔案不會隨著APP被刪除而遺失
儲存圖片
val contentValues = ContentValues()
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "圖片名稱")
contentValues.put(MediaStore.Images.Media.MIME_TYPE, MimeType._png.value)
val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.girl)
val outputStream = contentResolver.openOutputStream(uri!!)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
outputStream?.close()
儲存音樂
val contentValues = ContentValues()
contentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, "音樂名稱")
contentValues.put(MediaStore.Audio.Media.MIME_TYPE, MimeType._mp3.value)
val uri = contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentValues)

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.girl)
val outputStream = contentResolver.openOutputStream(uri!!)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
outputStream?.close()
儲存影片
val contentValues = ContentValues()
contentValues.put(MediaStore.Video.Media.DISPLAY_NAME, "影片名稱")
contentValues.put(MediaStore.Video.Media.MIME_TYPE, MimeType._mp4.value)
val uri = contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues)

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.girl)
val outputStream = contentResolver.openOutputStream(uri!!)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
outputStream?.close()
儲存檔案
val contentValues = ContentValues()
contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, "檔案名稱")
contentValues.put(MediaStore.Files.FileColumns.MIME_TYPE, MimeType._pdf.value)
val uri = contentResolver.insert(MediaStore.Files.getContentUri("external"), contentValues)

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.girl)
val outputStream = contentResolver.openOutputStream(uri!!)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
outputStream?.close()
MimeType
enum class MimeType(val value: String) {
    _png("image/png"),
    _jpeg("image/jpeg"),
    _webp("image/webp"),
    _gif("image/gif"),
    _bmp("image/bmp"),
    _3gp("video/3gpp"),
    _apk("application/vnd.android.package-archive"),
    _asf("video/x-ms-asf"),
    _avi("video/x-msvideo"),
    _bin("application/octet-stream"),
    _c("text/plain"),
    _class("application/octet-stream"),
    _conf("text/plain"),
    _cpp("text/plain"),
    _doc("application/msword"),
    _docx("application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
    _xls("application/vnd.ms-excel"),
    _xlsx("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
    _exe("application/octet-stream"),
    _gtar("application/x-gtar"),
    _gz("application/x-gzip"),
    _h("text/plain"),
    _htm("text/html"),
    _html("text/html"),
    _jar("application/java-archive"),
    _java("text/plain"),
    _js("application/x-javascript"),
    _log("text/plain"),
    _m3u("audio/x-mpegurl"),
    _m4a("audio/mp4a-latm"),
    _m4b("audio/mp4a-latm"),
    _m4p("audio/mp4a-latm"),
    _m4u("video/vnd.mpegurl"),
    _m4v("video/x-m4v"),
    _mov("video/quicktime"),
    _mp2("audio/x-mpeg"),
    _mp3("audio/x-mpeg"),
    _mp4("video/mp4"),
    _mpc("application/vnd.mpohun.certificate"),
    _mpe("video/mpeg"),
    _mpeg("video/mpeg"),
    _mpg("video/mpeg"),
    _mpg4("video/mp4"),
    _mpga("audio/mpeg"),
    _msg("application/vnd.ms-outlook"),
    _ogg("audio/ogg"),
    _pdf("application/pdf"),
    _pps("application/vnd.ms-powerpoint"),
    _ppt("application/vnd.ms-powerpoint"),
    _pptx("application/vnd.openxmlformats-officedocument.presentationml.presentation"),
    _prop("text/plain"),
    _rc("text/plain"),
    _rmvb("audio/x-pn-realaudio"),
    _rtf("application/rtf"),
    _sh("text/plain"),
    _tar("application/x-tar"),
    _tgz("application/x-compressed"),
    _txt("text/plain"),
    _wav("audio/x-wav"),
    _wma("audio/x-ms-wma"),
    _wmv("audio/x-ms-wmv"),
    _wps("application/vnd.ms-works"),
    _xml("text/plain"),
    _z("application/x-compress"),
    _zip("application/x-zip-compressed"),
    _0("*/*");

    companion object {
        fun isImage(mimeType: String?): Boolean {
            return mimeType?.let {
                _webp.value == mimeType ||
                        _png.value == mimeType ||
                        _jpeg.value == mimeType ||
                        _bmp.value == mimeType ||
                        _gif.value == mimeType
            } ?: false
        }

        fun isGif(mimeType: String?): Boolean {
            return mimeType?.let {
                _gif.value == mimeType
            } ?: false
        }

        fun isApk(mimeType: String?) = mimeType?.let {
            _apk.value == mimeType
        } ?: false

        fun isVideo(mimeType: String?) = mimeType?.let {
            _m3u.value == mimeType || _avi.value == mimeType
        } ?: false
    }
}

3.分區儲存(Scope storage)

分區儲存是為了降低APP的權限,來避免外部儲存有過多的資料夾,後續如果要使用外部儲存 就只能使用 contentResolver 去實現,並且無法在新建自己想要的資料夾

4.總結

1.data 路徑開頭 > 內部
2.storage 路徑開頭 & API 帶有 external > 外部
3.只要路徑都有包含 packageName 都會隨著 APP 刪除一起刪掉
4.清除缓存 是清存 APP 運行中產生的臨時數據不會清理到檔案
5.清除數據 是清除所有 packageName 下的所有檔案

5.Developer Documents Data and File Storage

Open in Documents Data and File Storage

發表迴響