본문 바로가기
Android/Features

[Android] StartIntentSenderForResult 를 사용하여 외부 앱과 상호작용하기

by startSW 2023. 10. 14.

이전에 registerForActivityResult 를 이용해서 다른 Activity 의 실행 결과를 전달 받는 방법에 대한 글을 작성했는데요.

https://swjsw.tistory.com/74

 

[Android] registerForActivityResult

안드로이드 앱을 개발하다보면 다른 Activity나 Intent를 시작하고 그 결과를 처리해야 하는 경우가 많이 있습니다. 이때 registerForActivityResult를 사용하면 간결한 코드로 결과 처리를 할 수 있습니다.

swjsw.tistory.com

 

이 글에서는 StartIntentSenderForResult 를 이용하는 방법을 알아보겠습니다.

 

안드로이드 앱 개발 중, 때로는 다른 앱이나 서비스와 상호작용해야 할 때가 있습니다.

이러한 상황에서 StartIntentSenderForResult가 유용하게 사용됩니다.

이 컨트랙트를 통해 IntentSender를 시작하고 결과를 처리할 수 있으며, 이를 통해 안전하게 외부 앱과 통신할 수 있습니다.

이 글에서는 StartIntentSenderForResult가 무엇이며 어떻게 사용하는지 설명하고, 실제 사용 사례를 예로 들어 설명하겠습니다.

 

StartIntentSenderForResult란?

StartIntentSenderForResult는 AndroidX 라이브러리의 일부로 제공되는 컨트랙트 중 하나입니다.

이 컨트랙트는 IntentSender를 사용하여 외부 앱이나 서비스와 상호작용하고 결과를 처리하는 데 사용됩니다.

 

IntentSender란?

IntentSender는 안드로이드에서 Intent를 수신하는 대상 앱 또는 서비스를 나타내는 객체입니다.

다른 앱으로부터 Intent를 받아 처리하거나, 다른 앱으로 Intent를 보내는 데 사용됩니다.

IntentSender를 사용하면 다른 앱과의 상호작용이 보안적으로 안전하게 이루어질 수 있습니다.

 

StartIntentSenderForResult 사용 방법

StartIntentSenderForResult를 사용하려면 다음 단계를 따릅니다.

 

1. ActivityResultLauncher 초기화

먼저, ActivityResultLauncher를 초기화하여 결과를 처리할 콜백을 설정합니다.

이 콜백은 StartIntentSenderForResult가 완료되면 호출됩니다.

val launcher = registerForActivityResult(
    ActivityResultContracts.StartIntentSenderForResult()
) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        // 결과가 성공적으로 반환됨
        // 원하는 동작 수행
    } else if (result.resultCode == Activity.RESULT_CANCELED) {
        // 사용자가 작업을 취소함
        // 필요한 경우 처리 코드 추가 (선택 사항)
    } else {
        // 작업이 실패하거나 다른 결과 코드인 경우 처리 (선택 사항)
    }
}

 

2. IntentSender 및 Intent 준비

결과를 받을 때 사용할 IntentSender와 결과를 처리하는 Intent를 설정합니다.

이 IntentSender와 Intent는 상호작용하려는 외부 앱 또는 서비스와 연결됩니다.

 

3. ActivityResultLauncher를 사용하여 IntentSender 시작

ActivityResultLauncher를 사용하여 앞서 설정한 IntentSender와 Intent를 시작합니다.

결과는 콜백 함수 내부에서 처리됩니다.

val intentSenderRequest = IntentSenderRequest.Builder(intentSender)
    .setFillInIntent(resultIntent)
    .build()
launcher.launch(intentSenderRequest)

 

4. 결과 처리

결과는 ActivityResultLauncher의 콜백 함수 내에서 처리됩니다.

resultCode를 확인하고 원하는 동작을 수행합니다.

결과 코드가 Activity.RESULT_OK인 경우에는 작업이 성공적으로 완료되었음을 나타내며, 사용자에 의해 취소되거나 실패한 경우에 대비하여 적절한 처리를 추가할 수 있습니다.

 

 

5. 실제 사용 사례 : Google Pay 결제 처리

import android.app.PendingIntent
import android.content.Intent
import android.content.IntentSender
import android.os.Bundle
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity

class PaymentActivity : AppCompatActivity() {
    // 가상의 결제 정보
    private val paymentAmount = 100.0
    private val paymentDescription = "Sample Payment"

    // ActivityResultLauncher 초기화
    private val launcher: ActivityResultLauncher<IntentSenderRequest> = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            // 결제가 성공적으로 완료됨
            // 원하는 동작 수행, 예: 주문 확인 화면으로 이동
            val data = result.data
            // 결과 데이터를 사용하여 원하는 작업 수행
        } else if (result.resultCode == Activity.RESULT_CANCELED) {
            // 결제가 사용자에 의해 취소됨
            // 처리 코드 추가 (선택 사항)
        } else {
            // 결제 실패 또는 다른 결과 코드 처리 (선택 사항)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_payment)

        // 결제 정보를 Intent로 설정
        val paymentIntent = Intent()
        paymentIntent.putExtra("amount", paymentAmount)
        paymentIntent.putExtra("description", paymentDescription)

        // PendingIntent로 Intent 묶기
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            paymentIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
        )

        // 결제 앱으로 IntentSender 생성
        val paymentAppIntent = Intent()
        paymentAppIntent.setClass(this, PaymentAppActivity::class.java)
        val intentSender = IntentSender.getActivities(this, 0, paymentAppIntent, pendingIntent.intentSender)

        // IntentSender를 사용하여 결제 앱으로 보내기
        try {
            val intentSenderRequest = IntentSenderRequest.Builder(intentSender)
                .build()
            launcher.launch(intentSenderRequest)
        } catch (e: IntentSender.SendIntentException) {
            e.printStackTrace()
        }
    }
}