오늘은 Activity간에 데이터를 주고받을 때 사용해야 하는 registerForActivityResult에 대해서 정리해 보도록 하겠습니다.
기존에는 사용하지 않던 API이어서 조금은 낯설지도 모르겠습니다.
1. 예전 구현방법
먼저, java로 작성한 예전구현 방법에 대해서 간단히 알아보고 가겠습니다.
이전 구현방법이 필요하지 않으시면 바로 2번의 새로바뀐 API구현 방법으로 가시면 됩니다.
A액티비티와 B액티비티간에 데이터를 주고 받는다고 가정해 보겠습니다.
먼저 A액티비티에서, launch는 아래와 같이 했었습니다.
startActivity가 아닌, startActivityForResult함수를 이용해서,
intent와 임의의 RequestCode를 정의해서 두번째 인자로 전달해 주었구요.
Intent mIntent = new Intent(this, SecondActivity.class);
startActivityForResult(mIntent, REQUEST_CODE_FOR_INTENT);
다음으로 callback인 onActivityResult를 정의하였습니다.
여기서 들어오는 인자인 requestCode가 Activity를 Launch할 때 썼던 코드가 맞고, resultCode가 RESULT_OK가 맞다면,
Intent타입인 data를 받아서 사용했었구요.
B액티비티에서는 종료후 A액티비티에 아래와 같이 데이터를 전송해 주는데요.
callBack의 데이터를 돌려주는 쪽에서의 launch는 아래와 같이 했었습니다.
setResult함수를 이용해서 launch해 주고요.
인자로 resultCode로 RESULT_OK와 intent데이터를 넣어주면 되었습니다.
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(MainActivity.TEST_INTENT, true);
setResult(RESULT_OK, intent);
이렇게 사용하고 있었는데요.
아래와 같이 사용하도록 바뀌었습니다.
2. 바뀐 registerForActivityResult API 구현방법
새롭게 바뀐 API는 Kotlin으로 작성하였는데요.
하나씩 보도록 하겠습니다.
2-1. ActivityResult를 받기위한 Callback등록
먼저 A액티비티에서 할일은,
registerForActivityResult 함수를 사용해서 Callback을 등록 하는 것 입니다.
인자로 들어가는 것은 ActivityResultContracts 클래스의 Static함수 인,
StartActivityForResult() 입니다.
콜백에서는 result로 받아온 값을 어떻게 사용하는지 정의해 주면 되는데요.
받아온 result 를 이용해서, resultCode와 data에 접근할 수 있는데요.
아래와 같이, resultCode를 이용해서 RESULT_OK인지 확인한 후,
result.data를 이용해서 다른 Activity에서 보내온 Intent Data를 사용하면 됩니다.
class MainActivity : AppCompatActivity() {
companion object { const val STRING_INTENT_KEY = "my_string_key" }
private val getResultText = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val returnString = result.data?.getStringExtra(STRING_INTENT_KEY)
Log.d(TAG, "onCreate: good To go: $mString")
}
}
override fun onCreate(savedInstanceState: Bundle?) { ...}
}
이제 위에서 정의한 것은 launch함수로 시작시켜주기만 하면 됩니다.
여기서는 btn을 클릭하면 실행하는 것으로 하겠습니다.
멤버함수인 launch를 사용하구요. 인자로 intent를 넣어주면 끝입니다.
button.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
getResultText.launch(intent)
}
2-2. B액티비티에서 setResult
이제 B액티비티에서 데이터를 실어서 A액티비티에 보내주기만 하면 됩니다.
이 부분은 이전 API와 변경된 것 없이,
setResult()함수에 인자로 resultCode와 intent데이터를 넣어주기만 하면 됩니다.
returnButton.setOnClickListener {
val intent = Intent(this, MainActivity::class.java).apply {
putExtra(MainActivity.STRING_INTENT_KEY, "Returning to Main Activity")
}
setResult(Activity.RESULT_OK, data)
if(!isFinishing) finish()
}
3. ActivityResultContracts
위에서는 A와 B액티비티간에 데이터를 주고 받을 때,
ActivityResultContracts 클래스의 StartActivityForResult를 사용했었는데요.
Activity간에 데이터를 주고 받는 다양한 케이스에 따라서, 다른 함수들을 사용해 주어야 합니다.
예를 들어,유저가 이미지등의 컨텐츠를 선택하고 uri를 받아오고자 한다면,
GetContent를 사용해 주어야 하구요.
이렇게 가져온 uri는 ContentsResolver클래스의 openInputStream을 통해서 데이터를 가져올 수 있습니다.
다양한 경우에 맞추어서 아래 Contracts클래스들을 사용하고, 데이터를 받아와서 사용하면 되겠습니다.
Contracts 클래스들 | 내용 |
StartActivityForResult | An ActivityResultContract that doesn't do any type conversion, taking raw Intent as an input and ActivityResult as an output. |
GetContent | An ActivityResultContract to prompt the user to pick a piece of content, receiving a content:// Uri for that content that allows you to use android.content.ContentResolver#openInputStream(Uri) to access the raw data. |
CreateDocument | An ActivityResultContract to prompt the user to select a path for creating a new document, returning the content: Uri of the item that was created. |
GetMultipleContents | An ActivityResultContract to prompt the user to pick one or more a pieces of content, receiving a content:// Uri for each piece of content that allows you to use android.content.ContentResolver#openInputStream(Uri) to access the raw data. |
OpenDocument | An ActivityResultContract to prompt the user to open a document, receiving its contents as a file:/http:/content: Uri. |
OpenDocumentTree | An ActivityResultContract to prompt the user to select a directory, returning the user selection as a Uri. |
OpenMultipleDocuments | An ActivityResultContract to prompt the user to open (possibly multiple) documents, receiving their contents as file:/http:/content: Uris. |
PickContact | An ActivityResultContract to request the user to pick a contact from the contacts app. |
RequestMultiplePermissions | An ActivityResultContract to request permissions |
RequestPermission | An ActivityResultContract to request a permission |
StartIntentSenderForResult | An ActivityResultContract that calls Activity#startIntentSender(IntentSender, Intent, int, int, int). |
TakePicture | An ActivityResultContract to take a picture saving it into the provided content-Uri. |
TakePicturePreview | An ActivityResultContract to take small a picture preview, returning it as a Bitmap. |
TakeVideo | An ActivityResultContract to take a video saving it into the provided content-Uri. |
위 리스트는 아래 링크에서도 확인해 볼 수 있습니다.
>> developer.android.com/reference/kotlin/androidx/activity/result/contract/ActivityResultContracts
이렇게 해서 액티비티간에 데이터를 주고 받는 방법에 대해서 정리해 보았구요.
관련된 내용은 이 글을 통해서 업데이트하도록 하겠습니다.
'Android 개발 > Android' 카테고리의 다른 글
Target Api 31 ( Android12 ) 에서 적용해야 하는 사항들 # Location Intent Filters exported mutability (0) | 2022.12.01 |
---|---|
Contentprovider 와 ContentResolver 이용한 CRUD # Mime-type Uri (1) | 2022.11.18 |
Android 리소스 정리시 사용하는 Naming Convention (0) | 2022.11.12 |
Android 에서 동적 권한 얻기 # State registerForActivityResult Runtime Permission (0) | 2022.10.24 |
카카오톡이나 페이스북에서 사용하는 HashKey 얻어오기 #Android (0) | 2021.05.07 |
targetSdkVersion 업데이트 Android10 Q API29 업데이트 강제사항 (0) | 2020.10.09 |
Full Screen Intent Notificaiton 에 관한 정리 # 풀스크린 인텐트 (0) | 2020.10.02 |
Android4를 지원하지 않는 라이브러리들 정리 # API21 이상 (1) | 2020.08.05 |
Android WebView 를 설정하고 로딩하는 방법을 정리해보자 (0) | 2020.03.19 |
Activity Manifest 설정에 대한 정리(launchMode, screenOrientation, configChanges 등) (0) | 2020.03.10 |
댓글