Intent 객체 생성, 갤러리 액티비티 실행 정보 setting
private val OPEN_GALLERY = 1
private var imageView: ImageView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
profileModifyBinding = ActivityProfileModifyBinding.inflate(layoutInflater)
setContentView(profileModifyBinding.root)
imageView = profileModifyBinding.profilemodifyProfileIV
imageView?.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.setType("image/*")
// 갤러리 액티비티로부터 가져온 결과 데이터를 처리하기 위해
// StartActivityForResult() 함수를 통해 액티비티를 실행
startActivityForResult(intent,OPEN_GALLERY)
}
})
}
갤러리 액티비티로부터 결과 데이터를 처리
해당 함수의 인자는 3개입니다.
첫 번째 인자 RequestCode는 startActivityForResult() 함수의 두 번째 인자로 넘겨줬던 값과 동일한 값이 넘어온다.
두 번째 인자는 resultCode로 사진을 정상적으로 선택하였다면 RESULT_OK 값이 넘어오며 뒤로가기 버튼으로 작업을 취소한 경우 RESULT_CANCELED 값이 넘어온다.
세 번째 인자는 갤러리 액티비티로부터 넘어온 결과 데이터가 담겨있는 Intent 객체이다.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == OPEN_GALLERY)
{
if(resultCode == RESULT_OK)
{
var currentImageUri = data?.data
try{
currentImageUri?.let {
if(Build.VERSION.SDK_INT < 28) {
val bitmap = MediaStore.Images.Media.getBitmap(
this.contentResolver,
currentImageUri
)
imageView?.setImageBitmap(bitmap)
} else {
val source = ImageDecoder.createSource(this.contentResolver, currentImageUri)
val bitmap = ImageDecoder.decodeBitmap(source)
imageView?.setImageBitmap(bitmap)
}
}
}catch(Exception e)
{
e.printStackTrace()
}
}
else if(resultCode == RESULT_CANCELED)
{
Toast.makeText(this, "사진 선택 취소", Toast.LENGTH_LONG).show();
}
}
}
private var imageView: ImageView? = profileModifyBinding.profilemodifyProfileIV
private val filterActivityLauncher: ActivityResultLauncher<Intent> =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if(it.resultCode == RESULT_OK && it.data !=null) {
var currentImageUri = it.data?.data
try {
currentImageUri?.let {
if(Build.VERSION.SDK_INT < 28) {
val bitmap = MediaStore.Images.Media.getBitmap(
this.contentResolver,
currentImageUri
)
imageView?.setImageBitmap(bitmap)
} else {
val source = ImageDecoder.createSource(this.contentResolver, currentImageUri)
val bitmap = ImageDecoder.decodeBitmap(source)
imageView?.setImageBitmap(bitmap)
}
}
}catch(e:Exception) {
e.printStackTrace()
}
} else if(it.resultCode == RESULT_CANCELED){
Toast.makeText(this, "사진 선택 취소", Toast.LENGTH_LONG).show();
}else{
Log.d("ActivityResult","something wrong")
}
}
ActivityResultLauncher<I>
:
registerForActivityResult(ActivityResultContract<I, O> contract, ActivityResultCallback<O> callback){}
Register a request to start an activity for result, designated by the given contract.
returns : the launcher that can be used to start the activity or dispose of the prepared call.
callback 람다에서 intent와 result code 등을 접근해서 원래의 onActivityResult에서 데이터를 가져오듯이 로직을 구성하면 된다.
ActivityResultContract: the contract, specifying conversions to/from Intents
: 인턴트 변환 객체
ActivityResultCallback: the callback to be called on the main thread when activity result is available
imageView?.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.setType("image/*")
filterActivityLauncher.launch(intent)
}
})
ActivityResultContract<I, O>
I : Launcher를 실행할 때의 input 타입
O : callback으로부터 떨어지는 인수의 타입
class CustomContract : ActivityResultContract<Intent, Long>() {
// 인텐트 객체 만들기
override fun createIntent(context: Context, input: Intent): Intent {
return input
}
// intent으로부터 전달 받은 데이터를 뽑아 리턴
override fun parseResult(resultCode: Int, intent: Intent?): Long {
return intent?.getLongExtra("awesome_key", -1) ?: -1
}
}
launcher를 실행할 때 내부적으로 이전 권한 설정 검사를 하고, 이미 되어있다면 바로 callback을 실행
그렇지 않으면 그때야 권한을 묻는 액티비티를 띄워준다.
private fun requestCameraPermission() {
val permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) {
Toast.makeText(this, "무야호 $it", Toast.LENGTH_SHORT).show()
}
permissionLauncher.launch(android.Manifest.permission.CAMERA)
}
onCreate에서 해당 메서드를 호출해도 ok
private fun requestPermissions() {
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
Log.d("권한요청", "$it")
}.launch(PERMISSIONS_REQUESTED)
}
companion object {
private const val PERMISSION_CAMERA = android.Manifest.permission.CAMERA
private const val PERMISSION_READ_EXTERNAL_STORAGE = android.Manifest.permission.READ_EXTERNAL_STORAGE
private const val PERMISSION_WRITE_EXTERNAL_STORAGE = android.Manifest.permission.WRITE_EXTERNAL_STORAGE
private val PERMISSIONS_REQUESTED: Array<String> = arrayOf(
PERMISSION_CAMERA,
PERMISSION_READ_EXTERNAL_STORAGE,
PERMISSION_WRITE_EXTERNAL_STORAGE,
)
}
참고한 블로그
https://modelmaker.tistory.com/18
참고한 안드로이드 사이트 https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller?hl=ko#registerForActivityResult(androidx.activity.result.contract.ActivityResultContract%3CI,%20O%3E,%20androidx.activity.result.ActivityResultCallback%3CO%3E)