안드로이드 앱은 내부에 스트링, 이미지 등의 많은 리소스들을 갖고 있습니다. 이런 리소스 파일들은 프로젝트에서 /res/
경로에 위치합니다.
순수하게 .txt
등의 구조적인 경로의 파일들을 읽을 때에는 이런 방식으로 읽을 수 없습니다.(/res/raw/에 파일을 저장할 수 있지만 리소스 ID로 접근 가능하고, 파일 path로 직접 접근할 수 없습니다)
앱의 Apk 파일에 어떤 파일을 저장하고 앱에서 그 파일을 읽고 싶다면, Assets을 이용해야 합니다. 앱은 Assets에 파일들을 저장할 수 있으며 AssetManager를 통해서 이 파일들을 읽을 수 있습니다.
앞으로 프로젝트 내에서 Asset 폴더 및 파일을 어떻게 생성하는지 알아보고, AssetManager를 통해 파일에 접근하는 방법에 대해서 알아보겠습니다.
이 글에서 소개되는 코드는 모두 코틀린으로 작성되었습니다.
Assets 폴더 및 파일 생성
안드로이드 스튜디오 프로젝트에서 Asset 파일들은 /main/assets/
경로 아래에 있습니다.
기본적으로 assets 폴더는 프로젝트에 생성되지 않기 때문에 직접 만들어줘야 합니다.
아래 그림처럼 [File] -> [New] -> [Folder] -> [Assets Folder]
로 Assets 폴더를 생성할 수 있습니다.
폴더를 만들기 전에 Assets path를 변경하겠냐고 물어봅니다. 특별한 이유가 없다면 Finish 버튼을 눌러 기본 위치에 폴더를 생성합니다.
그럼 폴더는 /main/assets/
에 생성됩니다.
이제 이 폴더에 파일을 생성하면 됩니다. 저는 posts.json
이라는 파일을 만들었습니다.
└── main
├── AndroidManifest.xml
└── assets
└── posts.json
posts.json
에 다음과 같이 내용을 입력하였습니다.
{
"posts": [
{
"title": "how to get stroage size",
"url": "https://codechacha.com/ko/get-free-and-total-size-of-volumes-in-android/",
"draft": false
},
{
"title": "Android Q, Scoped Storage",
"url": "https://codechacha.com/ko/android-q-scoped-storage/",
"draft": false
},
{
"title": "How to parse JSON in android",
"url": "https://codechacha.com/ko/how-to-parse-json-in-android/",
"draft": true
}
]
}
Apk에 Assets 파일의 위치
AssetManager로 Asset을 불러오기 전에 Apk파일에 Asset 파일이 어디에 위치해 있는지 한번 확인해보고 넘어가겠습니다.
Apk를 분석해보면 Apk 가장 상위 경로에서 /assets/
폴더가 있고 그 아래에 /assets/posts.json
파일이 존재합니다.
AssetManager는 이 경로에서 파일들을 가져옵니다.
AssetManager로 Assets 파일 읽기
다음은 AssetManager로 json 파일을 읽는 코드입니다.
val assetManager = resources.assets
val inputStream= assetManager.open("posts.json")
val jsonString = inputStream.bufferedReader().use { it.readText() }
AssetManager는 App의 resources.assets로 가져올 수 있습니다.
그리고 AssetManager.open(file name)
은 인자로 전달된 이름에 해당하는 파일을 가져와 InputStream으로 리턴해줍니다.
AssetManager의 root 경로는 "/assets/"
이기 때문에, 인자로 전달되는 "posts.json"
의 경로는 "/assets/posts.json"
가 됩니다.
다음은 위의 코드로 가져온 json 파일의 스트링을 읽어 JSONObject로 파싱 하는 코드입니다.
val assetManager = resources.assets
val inputStream= assetManager.open("posts.json")
val jsonString = inputStream.bufferedReader().use { it.readText() }
val jObject = JSONObject(jsonString)
val jArray = jObject.getJSONArray("posts")
for (i in 0 until jArray.length()) {
val obj = jArray.getJSONObject(i)
val title = obj.getString("title")
val url = obj.getString("url")
val draft = obj.getBoolean("draft")
Log.d(TAG, "title($i): $title")
Log.d(TAG, "url($i): $url")
Log.d(TAG, "draft($i): $draft")
}
실행 결과는 다음과 같습니다.
MainActivity: title(0): how to get stroage size
MainActivity: url(0): https://codechacha.com/ko/get-free-and-total-size-of-volumes-in-android/
MainActivity: draft(0): false
MainActivity: title(1): Android Q, Scoped Storage
MainActivity: url(1): https://codechacha.com/ko/android-q-scoped-storage/
MainActivity: draft(1): false
MainActivity: title(2): How to parse JSON in android
MainActivity: url(2): https://codechacha.com/ko/how-to-parse-json-in-android/
MainActivity: draft(2): true
Asset 파일의 경로
위에서 설명했듯이 AssetManager의 기본 root path는 /assets/
입니다.
예를 들어, 프로젝트에서 아래처럼 파일을 생성하였습니다.
└── main
├── AndroidManifest.xml
└── assets
├── posts.json
└── xml
└── settings.xml
위의 두개의 파일은 다음 처럼 가져올 수 있습니다. settings.xml은 xml폴더에 있기 때문에 "xml/settings.xml"
를 인자로 전달해야 합니다.
val assetManager = resources.assets
val inputStream= assetManager.open("posts.json")
val inputStream= assetManager.open("xml/settings.xml")
정리
Assets은 이미지, String이 아닌 파일 등을 apk에 저장하고 앱에서 읽을 때 사용할 수 있습니다. Assets을 사용하려면 Assets 폴더를 만들고 파일을 저장해야 합니다. 그리고 AssetManager를 통해 파일을 읽어와야 합니다.
참고
Related Posts
- Android 14 - 사진/동영상 파일, 일부 접근 권한 소개
- Android - adb push, pull로 파일 복사, 다운로드
- Android 14 - 암시적 인텐트 변경사항 및 문제 해결
- Jetpack Compose - Row와 Column
- Android 13, AOSP 오픈소스 다운로드 및 빌드
- Android 13 - 세분화된 미디어 파일 권한
- Android 13에서 Notification 권한 요청, 알림 띄우기
- Android 13에서 'Access blocked: ComponentInfo' 에러 해결
- 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8.
- 안드로이드 - 코루틴과 Retrofit으로 비동기 통신 예제
- 안드로이드 - 코루틴으로 URL 이미지 불러오기
- Android - 진동, Vibrator, VibrationEffect 예제
- Some problems were found with the configuration of task 에러 수정
- Query method parameters should either be a type that can be converted into a database column or a List
- 우분투에서 Android 12 오픈소스 다운로드 및 빌드
- Android - ViewModel을 생성하는 방법
- Android - Transformations.map(), switchMap() 차이점
- Android - Transformations.distinctUntilChanged() 소개
- Android - TabLayout 구현 방법 (+ ViewPager2)
- Android - 휴대폰 전화번호 가져오는 방법
- Android 12 - Splash Screens 알아보기
- Android 12 - Incremental Install (Play as you Download) 소개
- Android - adb 명령어로 bugreport 로그 파일 추출
- Android - adb 명령어로 App 데이터 삭제
- Android - adb 명령어로 앱 비활성화, 활성화
- Android - adb 명령어로 특정 패키지의 PID 찾기
- Android - adb 명령어로 퍼미션 Grant 또는 Revoke
- Android - adb 명령어로 apk 설치, 삭제
- Android - adb 명령어로 특정 패키지의 프로세스 종료
- Android - adb 명령어로 screen capture 저장
- Android - adb 명령어로 System 앱 삭제, 설치
- Android - adb 명령어로 settings value 확인, 변경
- Android 12 - IntentFilter의 exported 명시적 선언
- Android - adb 명령어로 공장초기화(Factory reset)
- Android - adb logcat 명령어로 로그 출력