상세 컨텐츠

본문 제목

안드로이드 문서 저장 방식에 대한 기록

공부/안드로이드

by dofury 2023. 7. 13. 15:38

본문

728x90

안드로이드 앱을 개발 하는 과정에서

csv 파일을 저장할 필요가 있었다.

 

그래서 Manifest.xml 에서 권한을 등록하고 파일 관리자를 통해 저장을 했었다.

 

    fun writeToFile(moneyLogs: List<MoneyLog>, fileName: String,context: Context) {
        val header = listOf("UID", "Charge", "Sign", "Category", "Date", "Memo", "Budget", "Server")
        val csvData = moneyLogs.joinToString("\n") { "${it.uid},${it.charge},${it.sign},${it.category},${it.date},${it.memo},${it.budget},${it.server}" }
        val csvString = "${header.joinToString(",")}\n$csvData"
/*        val filePath: String =
            context.filesDir.path
                .toString() + "/$fileName"*/
        val fileDownload = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        val getDownload = fileDownload.path
        val filePath: String = "$getDownload/$fileName"

        try {
            File(filePath).printWriter().use { out ->
                out.write(csvString)
            }
        }catch (e: Exception){
            Toast.makeText(context,"파일을 저장할 수 없습니다",Toast.LENGTH_SHORT).show()
        }

    }

해당 코드를 사용해 CsvWrite에서 함수를 불러와 권한을 체크한 후 저장을 시도했으나

권한이 없다고만 뜨고, 권한없이 시도하니 권한이 없어서 오류메세지만 나왔었다.

 

이 부분을 찾아보니 안드로이드11이후 버전은 보안이 강화되어 공용저장소저장을 엄격하게 관리한다고 한다.

그래서 ACTION_CREATE_DOCUMENT 인텐트 사용해 파일을 생성하기로 하였다.

이렇게 하는 경우(사용자가 수동으로 직접 저장을 하므로)

안드로이드 시스템에 의해 자동으로 권한이 부여되기 때문에 권한 체크를 안해도 되는 것 같다.

 

또한 Android 11(API 레벨 30)부터 onActivityResult() 메소드 또한 더 이상 권장되지 않기 때문에

Activity Result API 사용해서 깔끔하게 구현하였다.

 

API 호출후 실행되는 저장 코드

 

    @RequiresApi(Build.VERSION_CODES.O)
    fun createFile(activity: AppCompatActivity,moneyLogs: List<MoneyLog>,uri: Uri) {
        activity.contentResolver.openOutputStream(uri).use { outputStream ->
            val writer = OutputStreamWriter(outputStream)
            val csvWriter = CSVWriter(writer)

            // Write Header
            val header = arrayOf("UID", "Charge", "Sign", "Category", "Date", "Memo", "Budget", "Server")
            csvWriter.writeNext(header)
/*            val csvData = moneyLogs.joinToString("\n") { "${it.uid},${it.charge},${it.sign},${it.category},${it.date},${it.memo},${it.budget},${it.server}" }
            val csvString = "${header.joinToString(",")}\n$csvData"*/
            // Write Data
            moneyLogs.forEach { item->
                val row = arrayOf(item.uid.toString(),item.charge.toString(),item.sign.toString(),item.category,item.date,item.memo,item.budget.toString(),item.server.toString())
                csvWriter.writeNext(row)
            }
            csvWriter.close()
        }

    }

Result API 코드

    private val createFileActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == AppCompatActivity.RESULT_OK) {
            result.data?.data?.also { uri ->
                FileWriter.createFile(mainActivity,MyApplication.db.allLogs,uri)
            }
        }
    }

인텐트 생성 후 API 호출

            val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
                addCategory(Intent.CATEGORY_OPENABLE)
                type = "application/csv"
                putExtra(Intent.EXTRA_TITLE, "moneyLogs.csv")
            }
            createFileActivityResultLauncher.launch(intent)

정상 작동 결과

 

728x90

관련글 더보기

댓글 영역