04-16 05:02
Notice
Recent Posts
Recent Comments
04-16 05:02
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

pear

[android]Scoped Storage 본문

android/code

[android]Scoped Storage

pearlab 2023. 12. 13. 16:21

Legacy External Storage(OLD)

targetSdk API Level 29 이하

WRITE_EXTERNAL_STORAGE 권한이

구분 없이 외부저장소부터 대부분의 공간에 접근하고 쓰기가 가능했습니다.

val file = File(Environment.getExternalStorageDirectory(), "test.txt")

 

 

Scoped Storage(NEW)

targetSdk API Level 30이상
Media 유형

다른앱과 공유되는 영역의 미디어 파일은 모두 MediaStore를 이용하여 생성해야 합니다.

// Scoped Storage
val resolver = applicationContext.contentResolver
val audio = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val record = ContentValues().apply {
    put(MediaStore.Audio.Media.DISPLAY_NAME, "record.wav")
}
val uri = resolver.insert(audio, record)
content://media/external/audio/media/{id}

 

Storage Access Framework Example

GUI Action 없이 불가능

 ACTION_CREATE_DOCUMENT, ACTION_OPEN_DOCUMENT, ACTION_OPEN_DOCUMENT_TREE 인텐트 작업을 호출하고 문서 제공자에서 반환한 파일을 수신합니다.

val resolver = applicationContext.contentResolver
private val myCode: Int = 1000

private fun reqeustCreateDoc() {
        val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            putExtra(Intent.EXTRA_TITLE, "example.txt")
            type = "application/txt"
        }
        startActivityForResult(intent, myCode)
    }
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == myCode && resultCode == Activity.RESULT_OK && data != null) {
            Thread {
                val inUri = Uri.parse(".../text.txt")
                val outUri = (data.data) as Uri
                download(inUri, outUri)
            }.start()
        }
    }
    
    
    private fun download(sourceUri: Uri, destUri: Uri) {
        val connect = URL(sourceUri.toString()).openConnection()
        val inputStream = connect.getInputStream()
        val outputStream: FileOutputStream = contentResolver.openFileDescriptor(destUri, "w")?.use { pfd ->
            FileOutputStream(pfd.fileDescriptor)
        } ?: throw IllegalArgumentException()
        //[Todo]write
    }