[Android app] startActivityForResult () 사용 및 대체하기
: startActivityForResult () 함수는 자바에서는 deprecated 됐다고 경고가 나오네요.
사용법 간단히 알아보고 대체할 방법도 알아 보겠습니다.
일단 하고자 하는 기능은 블루투스 파워가 꺼져있을경우 켜달라고 요청하는 기능과
거부할경우 종료하는 기능입니다.
1> startActivityForResult (intent, requestCode) 함수 사용하기
// 1> intent 만들기
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
// 2> requestCode 넣기
class MainActivity : ComponentActivity() {
private val REQ_ENABLE_BT = 1
~~ 중략 ~~
}
// 3> startActivityForResult() 호출하기
startActivityForResult(enableBtIntent,REQ_ENABLE_BT)
▶ 위 코드의 startActivityForResult(..) 호출하면 아래의 거부/허용 창이 한개 올라옵니다.
▶ 허용을 누를경우 onActivityResult() 함수의 resultCode 로 RESULT_OK 가 들어 옵니다.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
REQ_ENABLE_BT -> {
if(resultCode == RESULT_OK)
Log.d(TAG,"BT enabled")
else {
Log.d(TAG, "BT disabled")
finish() // 거부를 누르면 프로그램 종료하기
}
}
}
}
▶ 추가로 블루투스 파워가 꺼져 있을경우만 호출되야 하니 아래코드처럼 조건이 추가되야 합니다.
btAdapter = (getSystemService(BLUETOOTH_SERVICE) as BluetoothManager).adapter
override fun onResume() {
~~ 중략 ~~
if(btAdapter!!.isEnabled == true){
~~ 중략 ~~
}else{
Log.d(TAG,"BT Power OFF")
// startActivityForResult() 코드 추가
}
}
2> startActivityForResult() 코드 대체하기
: Android Studio 에서 간단한 가이드를 아래 사진처럼 알려주네요.
: registerForActivityResult() 를 사용하라고 적혀 있고 , 첫번째 인자로 다음을 넣으라고 적혀 있네요.
androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult object
2-0> registerForActivityResult(..) 함수 정의 살펴보기
▶ 안드로이드 개발자 링크는 아래 링크 참조하세요.
▶ 두번째 인자 callback 만 작성하면 실행결과를 리턴 받을수 있습니다.
cbActivityResultLauncher = registerForActivityResult(androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult())
{
<-- 요기에 callback 내용 입력
}
너무 길죠.. import 구문추가후 간단히 줄이면
import androidx.activity.result.contract.ActivityResultContracts
cbActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult())
{
<-- 요기에 callback 내용 입력
}
2-1> registerforActivityResult 구문을 이용한 ActivityResultLauncher 변수 할당하기
class MainActivity : ComponentActivity() {
private lateinit var cbActivityResultLauncher: ActivityResultLauncher<Intent>
~~ 중략 ~~
override fun onCreate(savedInstanceState: Bundle?) {
~~ 중략 ~~
cbActivityResultLauncher = registerForActivityResult(androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult()){
// 1> it 사용 예제 (it : ActivityResult!)
if(it.resultCode == RESULT_OK)
Log.d(TAG,"Bluetooth enabled") <-- 허용 버튼 클릭시
else {
Log.d(TAG,"Bluetooth disabled") <-- 거부 버튼 클릭시
finish()
}
// 2> 변수 이름 사용 예제
result:ActivityResult ->
if(result.resultCode == RESULT_OK)
Log.d(TAG,"Bluetooth enabled")
else {
Log.d(TAG,"Bluetooth disabled")
finish()
}
}
}
2-2> ActivityResultLauncher 변수의 launch() 호출하기 (startActivityForResult() 대체구문)
override fun onResume() {
~~ 중략 ~~
Log.d(TAG,"BT Power OFF")
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
cbActivityResultLauncher.launch(enableBtIntent) <-- startActivityForResult() 대체 구문
}
3> 호출 순서
→ registerForActivityResult ()
→ cbActivityResultLauncher.launch(enableBtIntent)
→ 블루투스 켜기 요청창
→ ActivityResultCallback 구문 실행
<기타>
A> ActivityResultCallback 구문의 다양한 표현 방법을 적어봤습니다.
private lateinit var cbResult: ActivityResultCallback<ActivityResult>
launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult(),cbResult)
// 1> 익명 객체를 생성해 전달하기
cbResult = object:ActivityResultCallback<ActivityResult>{
override fun onActivityResult(result: ActivityResult?) {
if(result!!.resultCode == RESULT_OK)
Log.d(TAG,"Bluetooth enabled")
else {
Log.d(TAG,"Bluetooth disabled")
finish()
}
}
}
// 2> 람다식 적용버전
cbResult = ActivityResultCallback<ActivityResult> {
result ->
if(result.resultCode == RESULT_OK)
Log.d(TAG,"Bluetooth enabled")
else {
Log.d(TAG,"Bluetooth disabled")
finish()
}
}
// 3> it 적용버전
cbResult = ActivityResultCallback<ActivityResult> {
if(it.resultCode == RESULT_OK)
Log.d(TAG,"Bluetooth enabled")
else {
Log.d(TAG,"Bluetooth disabled")
finish()
}
}
// 4> cbResult 제거 버전
launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
if(it.resultCode == RESULT_OK)
Log.d(TAG,"Bluetooth enabled")
else {
Log.d(TAG,"Bluetooth disabled")
finish()
}
}
B> resultCode 변경시는 setResult(xxx) 사용하면 됩니다.
class ParentActivity : AppCompatActivity() {
~~ 중략 ~~
val intent = Intent(this,ChildActivity::class.java)
cbActivityResultLauncher.launch(intent)
~~ 중략 ~~
}
class ChildActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
~~ 중략 ~~
setResult(RESULT_OK)
~~ 중략 ~~
}
}
간단히 startActivityForResult() 예제를 작성해 봤고 이구문을 대체하는 방법에 대해서도 알아봤습니다.
그럼 수고하세요.