이제 두 번째 Android 11 개발자 프리뷰를 사용할 수 있습니다. 테스트해 보고 의견을 공유하세요.

활동으로부터 결과 가져오기

다른 활동을 시작하는 것이 단방향일 필요는 없습니다. 다른 활동을 시작하고 다시 결과를 받을 수도 있습니다. 결과를 수신하려면 startActivityForResult()를 호출합니다(startActivity() 대신).

예를 들어 앱에서 카메라 앱을 시작하고 그 결과로 캡처된 사진을 수신할 수 있습니다. 또는, 사용자가 연락처를 선택할 수 있도록 피플 앱을 시작하고 그 결과로 연락처 세부정보를 수신할 수 있습니다.

물론, 응답하는 활동은 결과를 반환하도록 설계되어야 합니다. 그러면 활동은 또 다른 Intent 개체로 결과를 전송합니다. 활동은 onActivityResult() 콜백에서 결과를 수신합니다.

참고: startActivityForResult()를 호출할 때 명시적 인텐트 또는 암시적 인텐트를 사용할 수 있습니다. 활동 중 하나를 시작하여 결과를 수신할 때 원하는 결과를 수신하려면 명시적 인텐트를 사용해야 합니다.

활동 시작

결과에 관한 활동을 시작할 때 사용하는 Intent 개체에 특별한 사항은 없지만 startActivityForResult() 메서드에 추가로 정수 인수를 전달해야 합니다.

정수 인수는 요청을 식별하는 '요청 코드'입니다. 결과 Intent를 수신할 때, 콜백은 동일한 요청 코드를 제공하여 앱이 결과를 적절하게 식별하고 처리 방법을 결정할 수 있도록 합니다.

다음은 사용자가 연락처를 선택하는 활동을 시작하는 방법에 관한 예입니다.

Kotlin

    const val PICK_CONTACT_REQUEST = 1  // The request code
    ...
    private fun pickContact() {
        Intent(Intent.ACTION_PICK, Uri.parse("content://contacts")).also { pickContactIntent ->
            pickContactIntent.type = Phone.CONTENT_TYPE // Show user only contacts w/ phone numbers
            startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST)
        }
    }
    

자바

    static final int PICK_CONTACT_REQUEST = 1;  // The request code
    ...
    private void pickContact() {
        Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
        pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
        startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
    }
    

결과 수신

사용자가 후속 활동을 마치고 돌아오면 시스템은 활동의 onActivityResult() 메서드를 호출합니다. 이 메서드는 다음 세 가지 인수를 포함합니다.

  • startActivityForResult()에 전달한 요청 코드
  • 두 번째 활동이 지정한 결과 코드. 이 값은 작업이 성공한 경우 RESULT_OK이며, 사용자가 취소하거나 어떤 이유로 작업이 실패한 경우 RESULT_CANCELED입니다.
  • 결과 데이터를 전달하는 Intent

다음은 '연락처 선택' 인텐트의 결과를 처리하는 예입니다.

Kotlin

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        // Check which request we're responding to
        if (requestCode == PICK_CONTACT_REQUEST) {
            // Make sure the request was successful
            if (resultCode == Activity.RESULT_OK) {
                // The user picked a contact.
                // The Intent's data Uri identifies which contact was selected.

                // Do something with the contact here (bigger example below)
            }
        }
    }
    

자바

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Check which request we're responding to
        if (requestCode == PICK_CONTACT_REQUEST) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                // The user picked a contact.
                // The Intent's data Uri identifies which contact was selected.

                // Do something with the contact here (bigger example below)
            }
        }
    }
    

이 예에서 Android의 연락처 또는 피플 앱에서 반환된 결과 Intent는 사용자가 선택한 연락처를 식별할 수 있는 콘텐츠 Uri를 제공합니다.

결과를 성공적으로 처리하기 위해서는 결과 Intent의 형식이 무엇인지 알아야 합니다. 결과를 반환하는 활동이 직접 정의한 활동 중 하나인 경우 그 형식을 이해하기가 쉽습니다. Android 플랫폼에 포함된 앱은 특정 결과 데이터를 기대할 수 있는 고유한 API를 제공합니다. 예를 들어, 피플 앱은 항상 선택된 연락처를 식별할 수 있는 콘텐츠 URI가 포함된 결과를 반환하고 카메라 앱은 추가로 "data"Bitmap을 반환합니다(사진 캡처에 관한 클래스 참조)

보너스: 연락처 데이터 읽기

위의 코드는 피플 앱에서 결과를 가져오는 방법을 보여주지만 실제로 결과에서 데이터를 읽는 방법은 콘텐츠 제공업체와 심도 있는 논의가 필요하기 때문에 여기에 구체적으로 설명하지 않습니다. 하지만 이러한 내용이 궁금할 경우, 다음 코드를 참조하여 결과 데이터 쿼리 후 선택된 연락처에서 전화번호를 가져오는 방법에 관해 알아보세요.

Kotlin

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        // Check which request it is that we're responding to
        if (requestCode == PICK_CONTACT_REQUEST) {
            // Make sure the request was successful
            if (resultCode == Activity.RESULT_OK) {
                // We only need the NUMBER column, because there will be only one row in the result
                val projection: Array<String> = arrayOf(Phone.NUMBER)

                // Get the URI that points to the selected contact
                data.data?.also { contactUri ->
                    // Perform the query on the contact to get the NUMBER column
                    // We don't need a selection or sort order (there's only one result for this URI)
                    // CAUTION: The query() method should be called from a separate thread to avoid
                    // blocking your app's UI thread. (For simplicity of the sample, this code doesn't
                    // do that.)
                    // Consider using <code><a href="/reference/android/content/CursorLoader.html">CursorLoader</a></code> to perform the query.
                    contentResolver.query(contactUri, projection, null, null, null)?.apply {
                        moveToFirst()

                        // Retrieve the phone number from the NUMBER column
                        val column: Int = getColumnIndex(Phone.NUMBER)
                        val number: String? = getString(column)

                        // Do something with the phone number...
                    }
                }
            }
        }
    }
    

자바

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent resultIntent) {
        // Check which request it is that we're responding to
        if (requestCode == PICK_CONTACT_REQUEST) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                // Get the URI that points to the selected contact
                Uri contactUri = resultIntent.getData();
                // We only need the NUMBER column, because there will be only one row in the result
                String[] projection = {Phone.NUMBER};

                // Perform the query on the contact to get the NUMBER column
                // We don't need a selection or sort order (there's only one result for the given URI)
                // CAUTION: The query() method should be called from a separate thread to avoid blocking
                // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
                // Consider using <code><a href="/reference/android/content/CursorLoader.html">CursorLoader</a></code> to perform the query.
                Cursor cursor = getContentResolver()
                        .query(contactUri, projection, null, null, null);
                cursor.moveToFirst();

                // Retrieve the phone number from the NUMBER column
                int column = cursor.getColumnIndex(Phone.NUMBER);
                String number = cursor.getString(column);

                // Do something with the phone number...
            }
        }
    }
    

참고: Android 2.3(API 레벨 9) 이전 버전에서는 Contacts Provider에 쿼리를 실행하려면 위에 보는 바와 같이 앱에서 READ_CONTACTS 권한을 선언해야 합니다(보안 및 권한 참조). 하지만 Android 2.3부터는 연락처 제공자가 결과를 반환할 때 앱이 연락처 제공자에서 결과를 읽을 수 있도록 연락처/피플 앱이 임시 권한을 부여합니다. 임시 권한은 요청된 특정 연락처에만 적용되므로 READ_CONTACTS 권한을 선언하지 않으면 인텐트의 Uri가 지정한 연락처 외 다른 연락처는 쿼리할 수 없습니다.

이 페이지의 주제에 관한 추가 정보는 다음 리소스를 참조하세요.