Development record of developer who study hard everyday.

레이블이 안드로이드storage access framework인 게시물을 표시합니다. 모든 게시물 표시
레이블이 안드로이드storage access framework인 게시물을 표시합니다. 모든 게시물 표시
, , , , , ,

안드로이드 공유 저장소에 폴더(디렉토리) 만들기

 안드로이드 공유 저장소에 폴더(디렉토리) 만들기

안드로이드 개발 블로그

이전 글(공유 저장소에서 파일 다루기)에 이어서 이번엔 공유 저장소에서 디렉토리를 만드는 방법을 소개한다.

val fileIntent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)    //1
fileLauncher.launch(fileIntent)

1- Intent.ACTION_OPEN_DOCUMENT_TREE를 사용하여 Selector UI를 열어준다.

val fileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if(result.resultCode == RESULT_OK) {
Log.d(TAG, "result is RESULT_OK")

val uri = result.data?.data    //1
Log.d(TAG, "uri is $uri")

val takeFlags = (intent.flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION))    //2
if (uri != null) {
contentResolver.takePersistableUriPermission(uri, takeFlags)
val folderDoc = DocumentFile.fromTreeUri(this, uri)    //4
folderDoc?.createDirectory("BooDir")    //5
}
}
}

1- uri를 받는다

2- 해당 uri에서 허용할 권한을 명시해준다

3- 해당 권한에 대해 지속적인 권한을 얻는다.

4- DocumentFile 문서들을 쉽게 다루기 위한 추상 클래스

5- 폴더 만들기

앱은 사용자가 선택한 파일들을 디바이스가 꺼질 때까지 읽고 쓸 수 있다.

다시 말해, 디바이스가 종료되면 파일에 대한 권한을 잃어버리기 때문에 위 3번과 같은 방식으로 권한을 얻는 방법을 추천한다.



Share:
Read More
, , , , ,

안드로이드 공유 저장소에 파일 만들기

 안드로이드 공유 저장소에 파일 만들기

안드로이드 개발 블로그

회사에서 기존 프로젝트에 기능 추가하는 일을 하다가 파일을 다루는 경우가 생겼다.

다들 알다시피, 안드로이드 10부터 저장소 개념이 바뀌면서 공부해야할 것들이 있다.

이번에는 공유 저장소에서 파일을 읽어오는 경우가 있어서 제대로 한 번 파헤쳐 보았다.

공유저장소에 접근하여 파일을 다룰 때는 SAF(Storage Access Framework)를 사용한다.

그럼 하나씩 살펴보도록하자.

1. 공유저장소에 파일 쓰기

val fileName = "NewImage.jpg"    //1
val makeFileIntent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {    //2
addCategory(Intent.CATEGORY_OPENABLE)    //3
type = "image/jpg"    //1
putExtra(Intent.EXTRA_TITLE, fileName)    //4
}
makeFileLauncher.launch(makeFileIntent)    //5

1- 파일명을 정해준다

2- SAF에서 파일을 생성할 때는 Intent.ACTION_CREATE_DOCUMENT 인텐트를 사용한다.

3- UI에 열 수 있는 파일만 보고싶을 때는 Intent.CATEGORY_OPENABLE를 사용한다

4- 만들 파일의 타입을 정한다.

5- Selector UI를 열어서 파일을 만들 경로의 uri를 받는다.

val makeFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if(result.resultCode == RESULT_OK) {
val uri = result.data?.data
if(uri != null){
contentResolver.openFileDescriptor(uri, "w").use {    //1
FileOutputStream(it!!.fileDescriptor).use { outStream ->    //2
val imageInputStream = resources.openRawResource(R.raw.app_icon)    //3
while(true){
val data = imageInputStream.read()
if(data == -1) {
break
}
outStream.write(data)    //4
}
imageInputStream.close()    //5
}
}
}

}
}

1- Uri로 ParcelFileDescriptor를 쓰기모드 가져온다.

2- ParcelFileDescriptor로 FileOutputStream을 만든다.

3- raw 폴더에 있는 이미지를 읽어온다

4- FileOutputStream에 이미지를 쓴다.

5- 이미지를 다 write했기때문에 이미지를 읽어올 때 사용한 inputStream을 닫아준다.


2. 파일 삭제

val deleteIntent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "image/*"
}
deleteFileLauncher.launch(deleteIntent)

파일을 만들어줄 때처럼 인텐트를 만들어서 실행해준다.

val deleteFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if(result.resultCode == RESULT_OK) {
val uri = result.data?.data
uri?.let { deleteFile(uri) }
}
}

fun deleteFile(uri: Uri) {
DocumentsContract.deleteDocument(contentResolver, uri)
}

Selector UI에서 사용자가 선택한 경로를 uri로 받는다.

DocumentsContract.deleteDocument() 로 파일을 삭제한다.




Share:
Read More