다른 앱이 내 활동을 시작하도록 허용

앱이 다른 앱에 유용할 수 있는 작업을 실행할 수 있다면 활동에서 적절한 인텐트 필터를 지정하여 작업 요청에 응답할 수 있도록 준비합니다.

예를 들어, 사용자의 친구들과 메시지 또는 사진을 공유할 수 있는 소셜 애플리케이션을 빌드했다면 앱에서 ACTION_SEND 인텐트를 지원하세요. 그러면 사용자가 다른 앱에서 '공유' 작업을 시작할 때 이 앱이 그림 1과 같이 선택기 대화상자(명확성 대화상자라고도 함)에 옵션으로 표시됩니다.

그림 1. 선택기 대화상자

이런 방식으로 다른 앱이 내 활동을 시작하도록 허용하려면 매니페스트 파일에 <activity> 요소에 대응하는 <intent-filter> 요소를 추가해야 합니다.

앱이 기기에 설치되면 시스템은 인텐트 필터를 식별하고 설치된 모든 앱에서 지원하는 인텐트의 내부 카탈로그에 정보를 추가합니다. 앱이 암시적 인텐트로 startActivity() 또는 startActivityForResult()를 호출하면 시스템은 인텐트에 응답할 수 있는 활동을 확인합니다.

인텐트 필터 추가

활동이 처리할 수 있는 인텐트를 제대로 정의하려면 추가하는 각 인텐트 필터를 활동이 허용하는 작업 유형 및 데이터 측면에서 최대한 구체적으로 지정합니다.

활동의 인텐트 필터가 Intent 객체의 다음 기준을 충족할 경우 시스템이 지정된 Intent를 이 활동에 보낼 수 있습니다.

작업
실행할 작업의 이름을 지정하는 문자열입니다. 일반적으로 플랫폼에서 정의하는 값 중 하나입니다(예: ACTION_SEND 또는 ACTION_VIEW).

<action> 요소를 사용하여 인텐트 필터에 지정합니다. 이 요소에서 지정하는 값은 이 페이지의 예와 같이 API 상수가 아닌 작업의 전체 문자열 이름이어야 합니다.

데이터
인텐트와 연결된 데이터의 설명입니다.

<data> 요소를 사용하여 인텐트 필터에 지정합니다. 이 요소에 하나 이상의 속성을 사용하여 MIME 유형, URI 접두사 또는 URI 스키마를 지정하거나 이 속성과 허용된 데이터 유형을 나타내는 다른 속성의 조합을 지정할 수 있습니다.

참고: Uri 데이터의 세부사항을 선언할 필요가 없는 경우(예: 활동이 URI 대신 다른 종류의 '추가' 데이터를 처리하는 경우) android:mimeType 속성만 지정하여 활동이 처리하는 데이터 유형(예: text/plain 또는 image/jpeg)을 선언합니다.

카테고리
인텐트를 처리하는 활동의 특징을 추가로 지정하며 일반적으로 사용자 동작 또는 활동이 시작된 위치와 관련이 있습니다. 시스템이 지원하는 카테고리는 여러 가지가 있지만, 대부분은 거의 사용되지 않습니다. 그러나, 기본적으로 모든 암시적 인텐트는 CATEGORY_DEFAULT로 정의됩니다.

<category> 요소를 사용하여 인텐트 필터에 지정합니다.

인텐트 필터에서 활동이 허용하는 기준을 선언할 수 있습니다. <intent-filter> 요소에 중첩된 해당 XML 요소를 사용하여 각 기준을 선언하면 됩니다.

예를 들어, 데이터 유형이 텍스트 또는 이미지일 때 ACTION_SEND 인텐트를 처리하는 인텐트 필터의 활동은 다음과 같습니다.

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

도움말: 선택기 대화상자의 아이콘을 활동의 기본 아이콘과 다르게 만들려면 <intent-filter> 요소에 android:icon을 추가하세요.

수신되는 인텐트는 각각 하나의 작업과 하나의 데이터 유형만 지정하지만, 각 <intent-filter><action>, <category>, <data> 요소의 인스턴스를 여러 개 선언해도 됩니다.

작업 및 데이터의 두 쌍이 상호 배타적으로 동작할 경우 별도의 인텐트 필터를 만들어 특정 데이터 유형과 페어링될 때 허용되는 작업이 무엇인지 지정합니다.

예를 들어, 활동에서 ACTION_SENDACTION_SENDTO 인텐트 모두 텍스트와 이미지를 모두 처리한다고 가정하겠습니다. 이런 경우 ACTION_SENDTO 인텐트는 Uri 데이터를 통해 send 또는 sendto URI 스키마를 사용하는 수신자 주소를 지정해야 하므로 두 작업 각각에 별도의 인텐트 필터를 정의해야 합니다. 예를 들면 다음과 같습니다.

<activity android:name="ShareActivity">
    <!-- Filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- Filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

참고: 암시적 인텐트를 수신하려면 인텐트 필터에 CATEGORY_DEFAULT 카테고리를 포함해야 합니다. startActivity()startActivityForResult() 메서드는 마치 모든 인텐트에서 CATEGORY_DEFAULT 카테고리를 선언한 것처럼 인텐트를 취급합니다. 인텐트 필터에서 이를 선언하지 않으면 암시적 인텐트는 활동으로 확인되지 않습니다.

소셜 공유 동작을 실행하는 ACTION_SEND 인텐트를 주고받는 방법에 관한 자세한 내용은 다른 앱에서 간단한 데이터 받기를 참고하세요. 또한, 간단한 데이터 공유파일 공유에서도 데이터 공유에 관한 유용한 정보를 찾을 수 있습니다.

내 활동에서 인텐트 처리

활동에서 사용할 작업을 결정하려면 활동을 시작하는 데 사용되는 Intent를 읽어보세요.

활동이 시작되면 getIntent()를 호출하여 활동을 시작한 Intent를 가져옵니다. 이 작업은 활동의 수명 주기 동안 언제든지 가능하지만, 일반적으로 onCreate() 또는 onStart()와 같은 초기 콜백 과정에서 실행합니다.

예를 들면 다음과 같습니다.

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main)

    val data: Uri? = intent?.data

    // Figure out what to do based on the intent type
    if (intent?.type?.startsWith("image/") == true) {
        // Handle intents with image data
    } else if (intent?.type == "text/plain") {
        // Handle intents with text
    }
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();

    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text
    }
}

결과 반환

내 활동을 호출한 활동으로 결과를 반환하려면 setResult()를 호출하여 결과 코드 및 결과 Intent를 지정하면 됩니다. 작업이 끝나고 사용자가 원래 활동으로 되돌아가야 한다면 finish()를 호출하여 활동을 종료 및 소멸합니다. 예를 들면 다음과 같습니다.

Kotlin

// Create intent to deliver some kind of result data
Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result ->
    setResult(Activity.RESULT_OK, result)
}
finish()

Java

// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();

결과 코드는 항상 결과와 함께 지정해야 합니다. 일반적으로 RESULT_OK 또는 RESULT_CANCELED입니다. 그런 다음, 필요한 경우 Intent를 사용하여 추가 데이터를 제공할 수 있습니다.

참고: 기본적으로 결과는 RESULT_CANCELED로 설정됩니다. 따라서, 사용자가 작업을 완료하기 전, 그리고 개발자가 결과를 설정하기 전에 사용자가 뒤로 버튼을 탭하면 원래의 활동은 '취소됨' 결과를 받습니다.

단순히 여러 결과 옵션 중 하나를 나타내는 정수만 반환하면 되는 경우 결과 코드를 0보다 큰 값으로 설정하면 됩니다. 결과 코드를 사용하여 정수를 전달하고 Intent를 포함할 필요가 없으면 setResult()를 호출하고 결과 코드만 전달할 수 있습니다.

Kotlin

setResult(RESULT_COLOR_RED)
finish()

Java

setResult(RESULT_COLOR_RED);
finish();

이런 경우, 가능한 결과는 몇 개에 불과할 것이므로 결과 코드는 로컬로 정의된 정수입니다(0보다 큼). 결과를 수신하는 활동은 공용 상수를 참조하여 결과 코드의 값을 판별하므로 이 방법은 자체 앱의 활동으로 결과를 반환하는 경우에 유용합니다.

참고: startActivity() 또는 startActivityForResult()로 활동이 시작되었는지 확인할 필요는 없습니다. 활동을 시작한 인텐트가 결과를 원할 경우 setResult()를 호출하기만 하면 됩니다. 원래 활동이 startActivityForResult()를 호출한 경우 시스템은 개발자가 setResult()에 제공하는 결과를 활동에 전송합니다. 그렇게 하지 않으면 결과는 무시됩니다.