React Native로 앱 개발 중 갤러리에서 이미지를 가져오는 기능이 필요했다.
보통 expo-image-picker나 react-native-image-picker를 사용하지만,
1. 나는 expo를 사용하지 않는다
2. react-native-image-picker는 SDK 33이하에서 사용 가능하다. (나는 SDK 34 사용)
따라서 두 라이브러리를 사용하지 않고 이미지를 가져오려면 코틀린 코드를 작성해야만 했다.
Kotlin은 사용해본 적 없었지만 이번 기회에 사용해보았다... (TMI를 말하자면, 다른 라이브러리 있나 찾을 시간에 진작에 코틀린으로 구현했으면 시간이 훨씬 단축됐을 거다...😢)
참고로 현재 게시물은 갤러리가 아닌 최근 항목에서 이미지를 가지고 오는 코드 관련 내용들을 서술한다.
0. AndroidManifest.xml에 권한 추가
파일 위치: 프로젝트 > android > app > src > main > AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 하단에 작성 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
1. Native Module 구현
MultiImagePickerModule.kt
파일 위치: 프로젝트 > android > app > src > main > java\com\패키지이름 > 폴더명 > MultiImagePickerModule.kt
package com.프로젝트이름.폴더명
import android.app.Activity
import android.content.Intent
import com.facebook.react.bridge.*
class MultiImagePickerModule(private val reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext), ActivityEventListener {
private var promise: Promise? = null
private val REQUEST_CODE = 23456
init {
reactContext.addActivityEventListener(this)
}
override fun getName() = "MultiImagePickerModule"
@ReactMethod
fun pickImages(promise: Promise) {
this.promise = promise
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "image/*"
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
currentActivity?.startActivityForResult(intent, REQUEST_CODE)
?: promise.reject("NO_ACTIVITY", "Activity is null")
}
override fun onActivityResult(activity: Activity?, requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode != REQUEST_CODE || promise == null) return
if (resultCode == Activity.RESULT_OK) {
val uriList = mutableListOf<String>()
data?.let {
if (it.clipData != null) {
for (i in 0 until it.clipData!!.itemCount) {
val uri = it.clipData!!.getItemAt(i).uri
uriList.add(uri.toString())
}
} else if (it.data != null) {
uriList.add(it.data!!.toString())
}
}
promise?.resolve(Arguments.fromList(uriList))
} else {
promise?.reject("CANCELLED", "User cancelled")
}
promise = null
}
override fun onNewIntent(intent: Intent?) {}
}
2. Package 등록
MultiImagePickerPackage.kt
파일 위치: 프로젝트 > android > app > src > main > java\com\패키지이름 > 폴더명 > MultiImagePickerPackage .kt
package com.프로젝트이름.폴더명
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.*
import com.facebook.react.uimanager.ViewManager
class MultiImagePickerPackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return listOf(MultiImagePickerModule(reactContext))
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = emptyList()
}
3. MainApplication.kt 연결
파일 위치: 프로젝트 > android > app > src > main > java\com\패키지이름 > 폴더명 > MainApplication.kt
//프로젝트 상단에 import도 해야함
import com.프로젝트명.폴더명.MultiImagePickerPackage
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// 여기에 추가
add(MultiImagePickerPackage())
}
...
4. JS에서 호출
// Native Module 호출 함수
import { NativeModules } from 'react-native';
export const pickImages = async (): Promise<string[]> => {
const { MultiImagePickerModule } = NativeModules;
if (!MultiImagePickerModule)
throw new Error('Native module not linked');
return await MultiImagePickerModule.pickImages();
};
// 사용 예
const onSelectImages = async () => {
try {
const uris = await pickImages(); //[] 반환
console.log('선택된 이미지 URI:', uris);
} catch (e) {
console.error('이미지 선택 실패:', e);
}
};
Native 코드를 수정했으므로 gradle 빌드를 다시 수행해야한다. 아래 글을 참고하면 된다.
https://it-amin.tistory.com/136
[React Native (RN)] Android Native 코드 수정 후 절차
React Native 구성React Native 앱은 두 부분으로 나뉜다.1. JavaScript 코드 Metro bundler로 런타임에 로딩Metro 서버를 통해 즉시 반영2. Native 코드 (Java/Kotlin, C++)Gradle로 컴파일 (.apk로 포함)JS코드처럼 바로 반
it-amin.tistory.com

위 코드를 작성 후 실행을 하면 최근 항목에서 사진들을 가지고 올 수 있다.
'Project > 사이드 프로젝트' 카테고리의 다른 글
| [React Native (RN)] Android 앱 배포하기 (0) | 2025.07.19 |
|---|---|
| [React Native(RN)] Stack Screen 헤더 스타일 설정과 오류 해결 (backgroundColor, fontSize, color, fontWeight, headerShadowVisible, options 오류 메시지) (0) | 2024.09.20 |
| [React Native (RN)] 기본 캘린더 화면 구현하기 (react-native-calendars, Typescript) (0) | 2024.08.27 |
| [React Native (RN)] 소셜 로그인 구현하기 (카카오, 안드로이드) (0) | 2024.08.14 |
| [React Native] Expo 프로젝트 생성 (최신 버전) (0) | 2024.07.23 |