registerForActivityResult 함수는 intent를 이용하여 액티비티를 통해 result를 받아올때 자주 써봤을것입니다. 이것말고도 권환등을 요청했을때 해당 권한의 응답을 받을때또한 사용됩니다. 이처럼 registerForActivityResult는 응답을 필요로할때 사용됩니다. 이밖에도 다른용도로 사용될까요?

registerForActivityResult는 2가지의 형태가 있습니다. 이2개는 비슷합니다. ActivityResultRegistry를 커스텀해서 사용할꺼냐 아니면 ComponentActivity.java 에서 본적으로 만들어지는 mActivityResultRegistry를 사용할꺼냐로 달라집니다.

ActivityResultRegistry는 무었일까요?

ActivityResultRegistry는 등록된 호출에 대한 액티비티 결과 콜백을 저장하는 레지스트리입니다. 테스트를 위해 직접 onLaunch를 오버라이드하고 dispatchResult를 즉시 호출하여 실제 Activity.startActivityForResult 호출을 건너뛰는 것으로 테스트용 인스턴스를 생성할 수 있습니다. 테스트할 때는 ActivityResultCaller.registerForActivityResult를 호출할 때 명시적으로 레지스트리 인스턴스를 제공하여 테스트 인스턴스를 주입할 수 있어야 합니다.
이러한 ActivityResultRegistry의 register 함수를 이용하여 ActivityResultLauncher를 만듭니다.

이 레지스트리에 새로운 콜백을 등록합니다. 이는 보통 ActivityResultCaller.registerForActivityResult와 같은 상위 수준의 편의 메서드에 의해 호출됩니다.
매개변수:
key: 이 호출을 식별하는 고유한 문자열 키입니다.
lifecycleOwner: 이 호출을 수행하는 LifecycleOwner입니다.
contract: 호출의 입력/출력 유형을 지정하는 계약입니다.
callback: 액티비티 결과 콜백입니다.
반환값:
ActivityResultContract를 실행하는 데 사용할 수 있는 런처입니다.
이러한 함수들이 있지만 내부적으로 사용되기 때문에 주로 사용되는 registerForActivityResult를 봐봅시다.
registerForActivityResult함수는 ActivityResultLauncher를 만들고 ActivityResultLauncher 의 launch의 input과 callbackd은 해당 함수가 제네릭이기 때문에 매개변수로 받는 contract에 따라 달라집니다.

ActivityResultContracts는 Android에서 제공하는 표준 ActivityResultContract의 모음입니다.

유형 변환을 수행하지 않고 원시 Intent를 입력으로 사용하고 ActivityResult를 출력으로 사용하는 ActivityResultContract입니다.
유형 안전 계약을 사용할 수 없는 액티비티 API를 호출할 때 요청 코드를 관리할 필요가 없도록 androidx.activity.result.ActivityResultCaller.registerForActivityResult와 함께 사용할 수 있습니다.

Activity.startIntentSender를 호출하는 ActivityResultContract입니다. 이 ActivityResultContract는 IntentSenderRequest를 사용하며, IntentSenderRequest.Builder를 사용하여 구성해야 합니다. Activity.startIntentSenderForResult 호출 시 android.content.IntentSender.SendIntentException이 발생하면 androidx.activity.result.ActivityResultCallback은 Activity.RESULT_CANCELED resultCode를 가진 ActivityResult를 받게 되며, 해당 인텐트의 액션은 ACTION_INTENT_SENDER_REQUEST이며, 던져진 예외를 포함하는 EXTRA_SEND_INTENT_EXCEPTION이 추가되어 있습니다

권한들을 요청하기 위한 ActivityResultContract

권한을 요청하기 위한 ActivityResultContract

촬영하여 Bitmap으로 반환하는 ActivityResultContract입니다. 이를 통해 super.createIntent()에 의해 생성된 Intent에 추가적인 엑스트라를 전달하려면 createIntent를 재정의할 수 있습니다
여기서 의문점은 제네릭의 첫번째 자료형이 Void? 라는 것입니다. 이경우
activityResultLauncherForTakePicturePreview.launch(null)
이런식으로 null 값을 주면 됩니다.

사진을 찍어서 제공된 콘텐츠 URI에 저장하는 ActivityResultContract입니다. 주어진 URI에 이미지가 저장되면 true를 반환합니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다
이방법은 위 takePicturePreview 보다 좀더 고화질의 이미지를 저장하여 프로바이더를 통해서 해당 이미지를 가져오기 때문에 화질이 좀더 좋은 사진을 가져오기 적절합니다.

동영상을 촬영하여 제공된 콘텐츠 URI에 저장하는 ActivityResultContract입니다. 반환값은 썸네일입니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.
썸네일 비트맵은 드물게 반환되며 비디오가 실제로 성공적으로 촬영되었는지를 결정하는 좋은 신호가 되지 않습니다. CaptureVideo를 사용하세요

동영상을 촬영하여 제공된 콘텐츠 URI에 저장하는 ActivityResultContract입니다. 주어진 URI에 비디오가 저장되면 true를 반환합니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다

사용자에게 연락처 앱에서 연락처를 선택하도록 요청하는 ActivityResultContract입니다. 결과는 content: Uri입니다. 참고: ContactsContract

사용자에게 콘텐츠를 선택하도록 프롬프트하는 ActivityResultContract입니다. 선택된 콘텐츠에 대한 content:// Uri를 받아옵니다. 이를 통해 android.content.ContentResolver.openInputStream을 사용하여 원시 데이터에 액세스할 수 있습니다. 기본적으로 이는 Intent.CATEGORY_OPENABLE을 추가하여 스트림으로 표현할 수 있는 콘텐츠만 반환합니다. 입력은 필터링할 mime 타입입니다. 예를 들어, image/* 입니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다

사용자에게 하나 이상의 콘텐츠를 선택하도록 프롬프트하는 ActivityResultContract입니다. 각 콘텐츠에 대한 content:// Uri를 받아옵니다. 이를 통해 android.content.ContentResolver.openInputStream을 사용하여 원시 데이터에 액세스할 수 있습니다. 기본적으로 이는 Intent.CATEGORY_OPENABLE을 추가하여 스트림으로 표현할 수 있는 콘텐츠만 반환합니다. 입력은 필터링할 mime 타입입니다. 예를 들어, image/* 입니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.

사용자에게 문서를 열도록 프롬프트하는 ActivityResultContract입니다. 해당 문서의 내용을 file:/http:/content: Uri로 받습니다. 입력은 필터링할 mime 타입입니다. 예를 들어, image/* 입니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.
참고: DocumentsContract

사용자에게 디렉터리를 선택하도록 프롬프트하는 ActivityResultContract입니다. 사용자의 선택을 Uri로 반환하며, 앱은 반환된 디렉터리 내의 문서를 완전히 관리할 수 있습니다. 입력은 초기 시작 위치의 선택적인 Uri입니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.
참고: Intent.ACTION_OPEN_DOCUMENT_TREE, DocumentsContract.buildDocumentUriUsingTree, DocumentsContract.buildChildDocumentsUriUsingTree

사용자에게 디렉터리를 선택하도록 프롬프트하는 ActivityResultContract입니다. 사용자의 선택을 Uri로 반환하며, 앱은 반환된 디렉터리 내의 문서를 완전히 관리할 수 있습니다. 입력은 초기 시작 위치의 선택적인 Uri입니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.
참고: Intent.ACTION_OPEN_DOCUMENT_TREE, DocumentsContract.buildDocumentUriUsingTree, DocumentsContract.buildChildDocumentsUriUsingTree

사용자에게 주어진 mimeType의 새 문서를 생성할 경로를 선택하도록 프롬프트하는 ActivityResultContract입니다. 생성된 항목의 content: Uri를 반환합니다. 입력은 새 파일의 제안된 이름입니다. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.

사용 가능한 경우 MediaStore.ACTION_PICK_IMAGES를 통해 사진 선택기를 사용하고, 그렇지 않은 경우 ACTION_OPEN_DOCUMENT에 의존하는 ActivityResultContract입니다. 입력은 PickVisualMediaRequest입니다. 사용자가 미디어를 선택한 경우 Uri를 출력으로 반환하고, 사용자가 항목을 선택하지 않은 경우 null을 반환합니다. 사진 선택기에 의해 반환된 Uri는 쓰기 가능하지 않음을 염두에 두세요. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.

사용 가능한 경우 MediaStore.ACTION_PICK_IMAGES를 통해 사진 선택기를 사용하고, 그렇지 않은 경우 ACTION_OPEN_DOCUMENT에 의존하는 ActivityResultContract입니다. 생성자는 사용자가 사진 선택기를 통해 반환할 수 있는 선택 가능한 항목의 수를 제한하는 maxItems 매개변수를 하나 받습니다. 이 매개변수는 사진 선택기를 사용할 수 없는 기기에서는 지원되지 않음에 유의하세요. 입력은 PickVisualMediaRequest입니다. 출력은 선택된 미디어의 Uri 목록입니다. 사용자가 항목을 선택하지 않은 경우 비어 있을 수 있습니다. 사진 선택기에 의해 반환된 Uri는 쓰기 가능하지 않음을 염두에 두세요. 추가적인 엑스트라를 super.createIntent()에 의해 생성된 인텐트에 전달하려면 createIntent를 재정의할 수 있습니다.