일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ActivityTestRule
- 안드로이드
- 안드로이드13
- Fragment 수동 추가
- Error:Execution failed for task ':app:mergeDebugResources'
- 안드로이드개발레벨업교과서
- recyclerview
- high order function
- ui test
- espresso
- 구분선
- 리사이클러뷰
- 코딜리티
- viewholder
- 스와이프
- 뷰변경 감지
- searchview
- LayoutManger
- 재사용
- IntentTestRule
- 고차함수
- 생명주기
- adapter
- 안드로이드스튜디오
- Fragment에서 Activity의 함수 사용하기
- 테마 아이콘
- fragment
- Android
- 코틀린
- binding adapter
- Today
- Total
룬아님의 취중코딩
(파일 다루기 2) Android Storage Access Framework를 이용한 파일 저장과 불러오기 본문
이번에는 파일 다루기 1에서 만들었던 JsonString을 SAF(Storage Access Framework)를 이용하여 저장하고 불러와보겠습니다.
https://developer.android.com/guide/topics/providers/document-provider#create
0. Manifest에 퍼미션 추가
....
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
1. 파일 만들기
private val WRITE_REQUEST_CODE: Int = 43
private fun createFile() {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/timetable"
putExtra(Intent.EXTRA_TITLE, System.currentTimeMillis().toString() + ".timetable")
}
startActivityForResult(intent, WRITE_REQUEST_CODE)
}
Intent.ACTION_CREATE_DOCUMENT을 사용하면 SAF를 이용하여 파일을 저장할 수 있습니다.
type은 나중에 파일을 불러올 때에도 사용되는 필터이니 만약 자신의 앱에서만 사용할 파일이라면 개별적인 타입을 지정하셔도 좋습니다.
저는 timetable이라는 타입을 사용하였습니다.
위의 코드를 보시면 파일은 만들고 있는데 안에 내용을 채워주는 코드가 없는 것을 확인할 수 있습니다.
그래서 request code를 이용하여 파일을 만든 이후에 내용을 채워주어야 합니다.
2. result를 이용하여 만든 파일에 값을 채워주기
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == WRITE_REQUEST_CODE) {
when (resultCode) {
Activity.RESULT_OK -> data?.data?.also {
writeInFile(it, Gson().toJson(Timetable()))
}
Activity.RESULT_CANCELED -> {
}
}
}
}
private fun writeInFile(@NonNull uri: Uri, @NonNull text: String) {
try {
val outputStream = contentResolver.openOutputStream(uri)
outputStream?.also {
val bw = BufferedWriter(OutputStreamWriter(it))
bw.write(text)
bw.flush()
bw.close()
}
} catch (e: IOException) {
e.printStackTrace()
}
}
result로 들어온 data에는 uri가 들어있습니다.
그 uri를 이용하여 특정 객체를 json형식의 string으로 변환하여 1번을 통해 만들어진 파일에 내용을 저장하였습니다.
이렇게 SAF를 이용한 저장은 마무리 되었습니다.
3. 이번에는 SAF를 이용하여 파일을 불러오겠습니다.
private val READ_REQUEST_CODE: Int = 42
private fun getSaveDataFromExternalStorage() {
val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/timetable"
}
startActivityForResult(intent, READ_REQUEST_CODE)
}
이번에는 Intent.ACTION_GET_DOCUMENT를 사용하여 파일을 가져오도록 합니다.
category에 Intent.CATEGORY_OPENABLE을 추가하면 열수있는 파일이 필터링되고
type을 추가하여 저장할 때 지정했던 타입의 파일만 가져올 수 있도록 지정해주었습니다.
4. result를 이용하여 데이터를 꺼내옵니다.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == WRITE_REQUEST_CODE) {
...
} else if (requestCode == READ_REQUEST_CODE) {
when (resultCode) {
Activity.RESULT_OK -> data?.data?.also {
try {
val timetableList = Gson().fromJson(readTextFromUri(it), TimetableList::class.java)
updateTimetable(timetableList)
} catch (e: JSONException) {
e.printStackTrace()
}
}
Activity.RESULT_CANCELED -> {
}
}
}
}
이번에도 Gson을 사용하여 가져온 String값을 객체로 변환하고 리스트를 갱신해주었습니다.
이것으로 SAF를 이용하여 파일을 저장하고 불러오는 것을 성공했습니다.
'개발 > 안드로이드 개발' 카테고리의 다른 글
BindingAdapter가 작동하지 않을 때 (0) | 2019.10.12 |
---|---|
(파일 다루기 3) URI로 real path 가져오기 (0) | 2019.10.11 |
(파일 다루기 1) Gson을 이용하여 커스텀 객체를 Json 객체로 변환하기 (0) | 2019.10.11 |
PreferenceFragment에서 PreferenceFragmentCompat으로 변경하기 (0) | 2019.10.02 |
Glide 커스텀 cache key로 cache 하기 (0) | 2019.09.30 |