Android_app

[Android app] startActivityForResult () 사용 및 대체하기

하니_즐거운하루 2023. 4. 4. 19:11

:  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() 예제를 작성해 봤고 이구문을 대체하는 방법에 대해서도 알아봤습니다.

 

그럼 수고하세요.

반응형