ACTION_CREATE_DOCUMENT를 이용해서 엑셀 파일을 만들고 FileOutPutStream에 전달하면
파일 또는 디렉토리를 찾을 수 없다고 뜨는 문제가 있어서 질문하러 왔습니다.
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
31
32
33
34
|
private fun exportToExcel(){
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/xlsx"
val excelFileName = NTPTime.date!!.replace(".","") + "_" +
NTPTime.time!!.replace(":", "") + ".xlsx"
putExtra(Intent.EXTRA_TITLE, excelFileName)
}
getFilePath.launch(intent)
}
val getFilePath: ActivityResultLauncher<Intent> = registerForActivityResult(
if(result.resultCode == RESULT_OK && result.data != null){
lifecycleScope.launch(Dispatchers.IO){
val workbook = createWorkbook()
createExcelFile(workbook, result.data?.data!!)
}
}
}
private fun createExcelFile(ourWorkbook: Workbook, fileUri: Uri) {
try {
val excelFile = File(fileUri.encodedPath)
val fileOut = FileOutputStream(excelFile) // 오류
ourWorkbook.write(fileOut)
fileOut.close()
} catch (e: FileNotFoundException) {
e.printStackTrace() // 파일 또는 디렉터리를 찾을 수 없음
} catch (e: IOException) {
e.printStackTrace()
}
}
|
cs |
createExcelFile에있는 FileOutputStream에 fileUri.toFile()을 하든, 그냥 path, fileUri.toString() 뭘 하든 다 오류 발생하고
excelFile에는 파일이 있습니다.
WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
권한 모두 준 상태입니다.
20개의 댓글
무분별한 사용은 차단될 수 있습니다.
tolabose
ide 테마 진짜 꿀밤마렵네 코드 보이긴하냐?
집에가게해줘
와씨;; 어둡게 했어서 몰랐네 ㅜㅜㅜ 다시 올릴께 ㅋㅋㅋㅋㅋㅋㅋ
슈카임
fileUri 존재함?
집에가게해줘
fileUri는 있어
슈카임
Encodedpath 이게 있어?
집에가게해줘
ㅇㅇ 있기는 한데
UriFile.toString() 값, path값, encodedPath값 다 적어볼께 잠깐만...
집에가게해줘
fileUri.toString(): content://com.android.externalstorage.documents/document/home%3A20240303_221343_%EC%B6%9C%ED%87%B4%EA%B7%BC%EC%9D%BC%EC%A7%80.xlsx
fileUri.path: /document/home:20240303_221343.xlsx
encodedPath: /document/home%3A20240303_221343_%EC%B6%9C%ED%87%B4%EA%B7%BC%EC%9D%BC%EC%A7%80.xlsx
이렇게 나옴
슈카임
/document/home:20240303_221343.xlsx
: 이게 가능한가?
집에가게해줘
씻고 잘 준비 하느라 늦게 봤네 미안..
나도 그건 이상하다 생각했는데 excelFile에 값 있길래 "아.. 안드로이드는 디렉토리랑 파일명 사이는 : 로 하나보네"하고 말았음
혹시 모르니 내일 저 부분만 수정해서 다시 해봐야겠다
집에가게해줘
갑자기 생긴 궁금증인데 fileUri값이 없다면 val excelFile = File(fileUri.encodedPath) 여기서 오류가 나지 않았을까?
슈카임
안날 수 있어
슈카임
Uri가 지원을하냐고 물어본거임
슈카임
근데 uri 인코딩한 패스가 필요한가? 걍 getpath 하면 안됨?
집에가게해줘
그냥 path했는데 안되길레 혹시나 싶어 해본거임 ㅋㅋㅋ 일단 그냥 path도 안되긴 함
슈카임
그 파일이름은 이미 존재하는거임?
집에가게해줘
존재함 ㅇㅇ
Intent.ACTION_CREATE_DOCUMENTATION 할 때 파일 생성 페이지가 뜨고
사용자가 어느 위치에 어느 파일명으로 만들껀지 선택하고 나면 바로 파일 생성됨
파일 생성이 되고 나면 getFilePath가 실행됨
힝거루
contentResolver.openOutputStream(Uri)를 사용해보기 바람
집에가게해줘
이걸로 안드로이드와 원만한 합의를 봤습니다.
먼저 ContentResolver를 이해하려면 ContentProvider(콘텐츠 공급자)를 알아야하는데
핵심 적인 부분만 얘기하자면
"콘텐츠 공급자는 데이터를 캡슐화하여 단일 ContentResolver 인터페이스를 통해 애플리케이션에 제공합니다." 입니다.
(https://developer.android.com/reference/android/content/ContentProvider)
리졸버는 애플리케이션 Content 모델에 대한 액세스를 제공해줍니다.
이 내용으로 보아 제가 생각하는 제 소스의 문제점은
ACTION_CREATE_DOCUMENT를 사용하면 안드로이드에서 제공하는 파일 생성 기능이 파일을 만들어주는데
이게 '내 애플리케이션'이 만든게 아니라 '안드로이드'에서 만든 것이므로 '내 애플리케이션'에서 접근할 수 없어
발생한 에러인거 같습니다.
같은 문제를 가지고 계신 분들이 있으실까봐 설명을 함께 적었는데 제가 이해한게 맞나요?
힝거루
본문에 사용한 File은 자바 API이기 때문에 안드로이드에서 제공하는 추상화된 경로로는 접근할 수 없음.
이전에는 Uri를 절대경로로 변환하는 방법이 존재했지만 Scoped Storage가 적용되면서 사실상 절대경로로 접근하는 방법은 없다고 생각하면 됨.
집에가게해줘
정확한 해설 ㄱㅅ