인텐트 및 인텐트 필터

Intent는 작업을 요청하는 데 사용할 수 있는 메시지 객체입니다. 다른 앱 구성요소에서 가져온 것입니다. 인텐트는 여러 가지 방식으로 구성 요소 간의 통신을 촉진하지만 세 가지 방법이 있습니다. 기본적인 사용 사례:

  • 활동 시작

    Activity는 앱의 단일 화면을 나타냅니다. 새로운 Intent를 전달하여 Activity의 인스턴스를 만듭니다. startActivity()에게. Intent 시작할 활동을 설명하고 필요한 모든 데이터를 전달합니다.

    활동이 완료될 때 활동에서 결과를 수신하려면 startActivityForResult()를 호출합니다. 활동이 결과를 수신합니다. 활동의 onActivityResult() 콜백에서 별도의 Intent 객체로 반환합니다. 자세한 내용은 활동 가이드를 참조하세요.

  • 서비스 시작

    Service는 백그라운드에서 작업을 실행하는 구성요소입니다. 애플리케이션을 구축할 수 있습니다. Android 5.0 (API 수준 21) 이상에서는 서비스를 시작할 수 있습니다. JobScheduler를 사용합니다. 자세한 내용은 JobScheduler 정보, 다음을 확인하세요. API-reference documentation입니다.

    Android 5.0 (API 수준 21) 이전 버전의 경우, 다음을 사용하여 서비스를 시작할 수 있습니다. Service 클래스의 메서드를 지원합니다. 서비스를 시작할 수 있습니다. 일회성 작업을 수행하여 Intent startService()에게 전송합니다. Intent 시작할 서비스를 설명하고 필요한 데이터를 전달합니다.

    서비스가 클라이언트-서버 인터페이스로 설계되었다면 IntentbindService()에 전달하여 다른 구성요소에서 삭제할 수 있습니다. 자세한 내용은 서비스 가이드를 참고하세요.

  • 브로드캐스트 전송

    브로드캐스트는 모든 앱이 수신할 수 있는 메시지입니다. 시스템은 다양한 시스템 이벤트를 위해 브로드캐스트합니다(예: 시스템이 부팅되거나 기기가 충전을 시작할 때). Intent를 전달하여 다른 앱에 브로드캐스트를 전달할 수 있습니다. 받는 사람: sendBroadcast() 또는 sendOrderedBroadcast()입니다.

이 페이지의 나머지에서는 인텐트의 작동 원리와 사용 방법을 설명합니다. 관련 정보는 다음을 참조하세요. 다른 앱과 상호작용콘텐츠 공유를 참조하세요.

인텐트 유형

인텐트에는 두 가지 유형이 있습니다.

  • 명시적 인텐트는 전체 ComponentName를 지정하여 어느 애플리케이션이 인텐트를 충족할지 지정합니다. 사용자는 일반적으로 명시적 인텐트를 사용하여 자신의 앱을 직접 빌드할 수 있습니다. 시작하려는 활동 또는 서비스의 클래스 이름을 알고 있기 때문입니다. 대상 예를 들어 사용자 작업에 응답하여 앱 내에서 새 활동을 시작하거나 백그라운드에서 파일을 다운로드하는 서비스가 필요합니다.
  • 암시적 인텐트는 특정 구성요소의 이름을 지정하지 않고 대신 일반 작업을 선언합니다. 다른 앱의 구성 요소가 작업을 처리할 수 있습니다. 예를 들어 사용자에게 지도에 있는 한 위치를 표시하고자 하는 경우, 암시적 인텐트를 사용하여 해당 기능을 갖춘 다른 앱이 지정된 위치를 지도에 표시하도록 요청할 수 있습니다.

그림 1은 액티비티를 시작할 때 인텐트를 사용하는 법을 나타낸 것입니다. 이 Intent 객체는 특정 활동 구성요소의 이름을 명시적으로 지정함 해당 구성요소를 즉시 시작합니다

그림 1. 암시적 인텐트의 특징 다른 활동을 시작하기 위해 시스템을 통해 전달됩니다. [1] 활동 AIntent를 작업 설명과 함께 실행하고 이를 startActivity()에 전달합니다. [2] Android 시스템에서 앱이 인텐트와 일치하는 인텐트 필터를 찾도록 합니다. 일치하는 항목이 발견되면 [3] 시스템에서 onCreate() 메서드를 호출하고 Intent에 전달하여 일치하는 활동 (활동 B)을 시작합니다.

암시적 인텐트를 사용하면 Android 시스템이 적절한 구성 요소를 찾아 이를 시작할 수 있음 다른 앱의 매니페스트 파일에 선언된 인텐트 필터와 인텐트의 내용을 비교하여 있습니다. 인텐트가 인텐트 필터와 일치하면 시스템은 해당 구성 요소를 시작하고 전달합니다. Intent 객체 여러 인텐트 필터가 호환되는 경우 시스템은 사용자가 사용할 앱을 선택할 수 있는 대화상자가 표시됩니다.

인텐트 필터는 앱의 매니페스트 파일에 있는 표현식으로, 인텐트에 의해 트리거될 수 있는 있습니다. 예를 들어 활동에 대한 인텐트 필터를 선언하면 다른 앱이 특정 종류의 인텐트로 활동을 직접 시작할 수 있도록 합니다. 마찬가지로 액티비티에 대한 인텐트 필터를 선언하지 않는 경우 명시적 인텐트로만 시작할 수 있습니다.

주의: 앱이 안전한지 확인하려면 명시적인 인텐트를 실행하고Service 서비스에 관해 인텐트 필터를 선언할 수 있습니다 암시적 인텐트를 사용하여 서비스를 시작하면 어떤 서비스가 인텐트에 응답할지 확신할 수 없고 어떤 서비스가 시작하는지 사용자가 알 수 없으므로 보안 위험이 있습니다. Android 5.0 (API 수준 21)부터 시스템은 bindService()를 호출하면 예외가 발생합니다. 있습니다.

인텐트 빌드

Intent 객체는 Android 시스템에서 사용하는 정보를 전달합니다. 어떤 구성요소 (예: 정확한 구성요소 이름 또는 구성요소)를 시작할지 결정합니다. (인텐트를 수신해야 하는 카테고리) 및 수신자 구성 요소가 사용하는 정보 (예: 취해야 할 조치 및 조치를 취할 데이터)에 대한 정보를 얻을 수 있습니다.

Intent에 포함된 기본 정보는 다음과 같습니다.

구성요소 이름
시작할 구성요소의 이름입니다.

이것은 선택사항이지만, 인텐트를 명시적으로 만드는 중요한 정보입니다. 즉, 이 인텐트는 구성 요소 이름으로 정의된 앱 구성 요소에만 전달되어야 합니다. 구성요소 이름이 없으면 인텐트는 암시적이며 시스템이 다른 인텐트 정보에 기초하여 인텐트를 수신할 구성 요소 결정 (예: 액션, 데이터, 카테고리(아래 설명 참고)) 특정 팀을 시작해야 하는 경우 구성 요소 이름을 지정해야 합니다.

참고: Service를 시작할 때는 항상 구성요소 이름을 지정합니다. 그렇지 않으면 어떤 서비스가 제공되는지 인텐트에 응답하고 사용자는 어느 서비스가 시작하는지 알 수 없습니다.

Intent의 이 필드는 ComponentName 객체로, 대상 구성요소의 정규화된 클래스 이름(앱의 패키지 이름 포함)을 사용하여 지정할 수 있습니다(예: com.example.ExampleActivity). 구성요소 이름은 setComponent(), setClass(), setClassName(), 또는 Intent 생성자.

조치
실행할 일반적인 작업 (예: 보기 또는 선택)을 지정하는 문자열입니다.

브로드캐스트 인텐트의 경우, 이것은 이미 실행되어 보고되고 있는 작업입니다. 이 작업은 대체로 나머지 인텐트의 구조를 결정합니다. 특히, 데이터와 엑스트라에 포함되는 정보가 결정됩니다.

앱 내의 인텐트에서 사용할 (또는 다른 것이 사용할) 작업을 직접 지정할 수 있습니다. 앱의 구성 요소를 호출하도록 하는 것이 일반적이지만 일반적으로 작업 상수를 지정합니다. Intent 클래스나 다른 프레임워크 클래스에 의해 정의됨 다음은 몇 가지 일반적인 작업은 다음과 같습니다.

ACTION_VIEW
다음 정보가 있을 때 startActivity()가 있는 인텐트에서 이 작업을 사용합니다. 사용자에게 표시할 수 있는 활동(예: 갤러리 앱에서 볼 사진 또는 지도 앱에서 볼 수 있습니다.
ACTION_SEND
공유 인텐트라고도 하며 사용자가 할 수 있는 데이터가 있는 경우 startActivity()가 있는 인텐트에서 사용해야 합니다. 다른 앱(예: 이메일 앱 또는 소셜 공유 앱)을 통해 공유하는 행위

자세한 내용은 Intent 클래스 참조를 확인하세요. 일반 작업을 정의하는 상수입니다. 다른 작업은 Android 프레임워크의 다른 곳에서 정의됩니다. 예를 들어 시스템의 설정 앱에서 특정 화면을 여는 작업의 경우 Settings에서 정의됩니다.

setAction() 또는 Intent 생성자를 사용하여 인텐트의 작업을 지정할 수 있습니다.

작업을 직접 정의하는 경우 앱의 패키지 이름을 포함해야 합니다. 를 프리픽스로 사용하세요.

Kotlin

const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"

자바

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
데이터
작업을 수행할 데이터 및/또는 해당 데이터의 MIME 유형을 참조하는 URI(Uri 객체)입니다. 제공되는 데이터 유형은 일반적으로 인텐트의 작업에 따라 결정됩니다. 대상 예를 들어 작업이 ACTION_EDIT인 경우 데이터에 수정할 문서의 URI입니다.

인텐트를 생성할 때는 URI 외에 데이터 유형(데이터의 MIME 유형)을 지정하는 것이 중요한 경우가 많습니다. 예를 들어 이미지를 표시할 수 있는 활동은 아마도 URI 형식이 비슷할 수 있지만 오디오 파일을 재생할 수 있습니다. 데이터의 MIME 유형을 지정하면 Android에서 시스템이 인텐트를 수신하는 가장 적합한 구성 요소를 찾습니다. 그러나 때로는 MIME 유형을 URI에서 추론할 수 있습니다. 특히 데이터가 content: URI content: URI는 데이터가 기기에 있음을 나타냅니다. 제어 영역에 의해 제어되며 ContentProvider: 데이터 MIME 유형이 시스템에 표시되도록 합니다.

데이터 URI만 설정하려면 setData()를 호출합니다. MIME 유형만 설정하려면 setType()를 호출합니다. 필요한 경우 setDataAndType()를 사용하여 두 가지를 모두 명시적으로 설정할 수 있습니다.

주의: URI와 MIME 유형을 모두 설정하려면 setData()를 호출해서는 안 되며 서로의 값을 무효화하기 때문에 setType()입니다. 항상 setDataAndType()를 사용하여 둘 다 설정 URI 및 MIME 유형입니다.

카테고리
인텐트를 처리해야 하는 구성 요소의 종류에 관한 추가 정보를 담은 문자열입니다. 카테고리 설명은 원하는 수만큼 입력할 수 있습니다. 를 포함하지만 대부분의 인텐트에는 카테고리가 필요하지 않습니다. 다음은 몇 가지 일반적인 카테고리입니다.
CATEGORY_BROWSABLE
대상 활동이 웹브라우저에 의해 시작되어 데이터를 표시하도록 허용함 이미지 또는 이메일 메시지와 같은 링크로 참조됩니다.
CATEGORY_LAUNCHER
활동은 작업의 초기 활동이며 다음 위치에 나열됩니다. 시스템 애플리케이션 실행기입니다.

카테고리의 전체 목록은 Intent 클래스 설명을 참고하세요.

addCategory()로 카테고리를 지정할 수 있습니다.

위에 나열된 이러한 속성 (구성요소 이름, 작업, 데이터 및 카테고리)은 인텐트의 특성을 정의합니다 이러한 속성을 읽으면 Android 시스템은 시작할 앱 구성 요소를 결정할 수 있습니다. 그러나 인텐트는 영향을 미치지 않는 추가 정보를 앱 구성요소로 결정되는 방식을 정의합니다. 인텐트가 제공할 수 있는 기타 정보는 다음과 같습니다.

추가 항목
달성하는 데 필요한 추가 정보가 담긴 키-값 쌍 확인할 수 있습니다 몇몇 작업이 특정한 종류의 데이터 URI를 사용하는 것과 마찬가지로, 몇몇 작업은 특정한 엑스트라도 사용합니다.

다양한 putExtra() 메서드로 엑스트라 데이터를 추가할 수 있습니다. 각 메서드는 키 이름과 값, 이렇게 두 개의 매개변수를 취합니다. 모든 추가 데이터가 포함된 Bundle 객체를 만든 다음 putExtras()IntentBundle

예를 들어 ACTION_SEND으로 받는사람 수신자를 지정할 수 있습니다. EXTRA_EMAIL 키를 사용하고 제목EXTRA_SUBJECT 키.

Intent 클래스는 여러 EXTRA_* 상수를 지정합니다. 표준화된 데이터 유형을 사용할 수 있습니다 나름의 엑스트라 키를 선언해야 하는 경우(본인의 앱이 수신할 인텐트에 대하여), 앱의 패키지 이름을 접두어로 포함해야 합니다. 이는 다음 예시에서 확인할 수 있습니다.

Kotlin

const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"

자바

static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";

주의: Parcelable 또는 예상 인텐트를 전송할 때의 Serializable 데이터 수신할 수 있습니다. 앱이 Bundle 객체의 데이터에 액세스하려고 시도하지만 파슬링되거나 직렬화된 클래스에 액세스할 수 있는 경우 시스템은 RuntimeException입니다.

플래그
플래그는Intent 인텐트를 지정할 수 있습니다. 플래그는 Android 시스템에 활동을 시작하는 방법을 지시할 수도 있습니다 (예: 태스크 활동은 출시 후 처리 방법 (예: 해당 항목이 최근 활동).

자세한 내용은 setFlags() 메서드를 참고하세요.

명시적 인텐트 예시

명시적 인텐트는 다음과 같은 특정 앱 구성 요소를 실행하는 데 사용하는 인텐트입니다. 특정 활동 또는 서비스로 구성됩니다. 명시적 인텐트를 만들려면 Intent 객체의 구성요소 이름 - 모두 선택적으로 사용할 수 있습니다.

예를 들어 앱에서 이름이 DownloadService인 서비스를 빌드했다면 웹에서 파일을 다운로드하도록 설계된 경우 다음 코드로 파일을 시작할 수 있습니다.

Kotlin

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
val downloadIntent = Intent(this, DownloadService::class.java).apply {
    data = Uri.parse(fileUrl)
}
startService(downloadIntent)

자바

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

Intent(Context, Class) 생성자가 앱에 Context를 제공하고 Class 객체를 빌드합니다. 따라서 이 인텐트는 앱에서 DownloadService 클래스를 명시적으로 시작합니다.

서비스 빌드 및 시작에 관한 자세한 내용은 서비스 가이드를 참조하세요.

암시적 인텐트 예시

암시적 인텐트는 작업을 지정하여 기기에서 해당 작업을 수행할 수 있는 모든 앱을 호출할 수 있도록 합니다. 암시적 인텐트를 사용하면 본인의 앱은 작업을 수행할 수 없지만 다른 앱은 아마도 할 수 있을 때, 그리고 사용자가 어느 앱을 사용할지 선택하도록 하고자 할 때 유용합니다.

예를 들어 사용자가 다른 사람들과 공유했으면 하는 콘텐츠를 가지고 있는 경우 ACTION_SEND 작업이 있는 인텐트를 생성한 다음 공유할 콘텐츠를 지정하는 엑스트라를 추가하면 됩니다. 해당 인텐트로 startActivity()를 호출하면 사용자가 콘텐츠를 공유할 앱을 선택할 수 있습니다.

Kotlin

// Create the text message with a string.
val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, textMessage)
    type = "text/plain"
}

// Try to invoke the intent.
try {
    startActivity(sendIntent)
} catch (e: ActivityNotFoundException) {
    // Define what your app should do if no activity can handle the intent.
}

자바

// Create the text message with a string.
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Try to invoke the intent.
try {
    startActivity(sendIntent);
} catch (ActivityNotFoundException e) {
    // Define what your app should do if no activity can handle the intent.
}

startActivity()가 호출되면 시스템은 설치된 앱을 모두 살펴보고 이런 종류의 인텐트를 처리할 수 있는 앱이 어느 것인지 알아봅니다(ACTION_SEND 작업이 있는 인텐트이며 'text/plain' 데이터가 담긴 것). 처리할 수 있는 앱이 하나만 있는 경우, 해당 앱이 즉시 열리고 인텐트를 지정할 수 있습니다. 다른 앱에서 처리할 수 없는 경우 앱은 ActivityNotFoundException 드림 발생할 수 있습니다. 인텐트를 허용하는 활동이 여러 개인 경우 시스템은 는 그림 2와 같은 대화상자를 표시하여 사용자가 어느 앱을 사용할지 선택할 수 있도록 합니다.

다른 앱을 실행하는 방법에 관한 자세한 내용은 가이드에서 확인할 수 있습니다. 사용자를 다른 앱으로 이동합니다.

그림 2. 선택기 대화상자

앱 선택기 강제 적용

암시적 인텐트에 응답하는 앱이 둘 이상 있는 경우 사용자는 사용할 앱을 선택하고 해당 앱을 있습니다. 기본값을 선택하는 기능은 사용자가 특정 작업을 수행할 때 사용자가 웹페이지를 열 때와 같이 매번 같은 앱을 사용하고자 하나의 웹브라우저만 선호할 때가 많음).

그러나 인텐트에 응답할 수 있는 앱이 여러 개이고 사용자가 매번 다른 앱을 사용하기를 원할 수도 있는 경우라면 선택기 대화상자를 명시적으로 표시해야 합니다. 선택기 대화상자에 사용자가 작업에 사용할 앱을 선택할 수 있습니다 (사용자는 기본 앱을 선택할 수 없음). 합니다. 예를 들어 앱에서 ACTION_SEND 작업을 사용하면 사용자는 필요에 따라 다른 앱을 사용하여 공유하는 것이 좋습니다. 항상 선택기 대화상자를 사용해야 합니다(그림 2 참고).

선택기를 표시하려면 다음 예와 같이 createChooser()를 사용하여 Intent를 만들어 startActivity()에 전달합니다. 이 예에서는 createChooser() 메서드에 전달된 인텐트에 응답하는 앱의 목록이 포함된 대화상자를 표시하고 제공된 텍스트를 대화상자 제목입니다.

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
val title: String = resources.getString(R.string.chooser_title)
// Create intent to show the chooser dialog
val chooser: Intent = Intent.createChooser(sendIntent, title)

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(packageManager) != null) {
    startActivity(chooser)
}

자바

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

안전하지 않은 인텐트 실행 감지

앱은 인텐트를 실행하여 앱 내부의 구성요소 간에 이동하거나 다른 앱을 대신하여 작업을 실행할 수 있습니다. 플랫폼 보안을 개선하기 위해 Android 12(API 수준 31) 이상에서는 앱이 안전하지 않은 방식으로 인텐트를 실행하면 경고를 표시하는 디버깅 기능을 제공합니다. 예를 들어 앱이 전달되는 인텐트인 중첩된 인텐트의 안전하지 않은 실행 실행 다른 인텐트의 추가 항목으로 포함해야 합니다.

앱이 다음 두 작업을 모두 실행하면 시스템에서 안전하지 않은 인텐트 실행, StrictMode 위반 발생:

  1. 앱은 전달된 인텐트의 추가 항목에서 중첩된 인텐트를 분리합니다.
  2. 앱은 인텐트를 startActivity(), startService() 또는 bindService()로 전달하는 등 즉시 중첩된 인텐트를 사용하여 앱 구성요소를 시작합니다.

이 상황을 파악하고 앱을 변경하는 방법을 자세히 알아보려면 Android Nesting에 관한 블로그 게시물 읽기 인텐트 자세히 알아보세요.

안전하지 않은 인텐트 실행 확인

앱에서 안전하지 않은 인텐트 실행을 확인하려면 다음 코드 스니펫과 같이 VmPolicy를 구성할 때 detectUnsafeIntentLaunch()를 호출하세요. 앱에서 StrictMode 위반을 감지하면 잠재적으로 민감한 정보를 보호하기 위해 앱 실행을 중지하는 것이 좋습니다.

Kotlin

fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build())
}

자바

protected void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build());
}

더 책임감 있는 인텐트 사용

안전하지 않은 인텐트 실행 및 StrictMode 위반 가능성을 최소화하려면 다음 권장사항을 따르세요.

인텐트 내 필수 추가 항목만 복사하고 필요한 정리 및 검증을 실행합니다. 앱은 한 인텐트에서 새 구성요소를 실행하는 데 사용되는 다른 인텐트로 추가 항목을 복사할 수 있습니다. 이는 앱이 putExtras(Intent)putExtras(Bundle)를 호출할 때 발생합니다. 앱이 이러한 작업 중 하나를 실행하면 수신 구성요소에서 예상하는 추가 항목만 복사합니다. 복사본을 수신하는 다른 인텐트가 내보내지 않은 구성요소를 실행하는 경우 추가 항목을 정리하고 검증한 후 구성요소를 실행하는 인텐트에 복사합니다.

앱의 구성요소를 불필요하게 내보내지 마세요. 예를 들어 내부 중첩 인텐트를 사용하여 앱 구성요소를 실행하려는 경우 구성요소의 android:exported 속성을 false로 설정합니다.

중첩된 인텐트 대신 PendingIntent를 사용하세요. 이렇게 하면 다른 앱이 PendingIntent Intent가 포함된 경우 다른 앱은 다음을 사용하여 PendingIntent를 실행할 수 있습니다. 식별해야 합니다. 이 구성을 사용하면 다른 앱을 안전하게 실행할 수 있습니다. 내보내지 않은 구성요소를 비롯한 모든 구성요소를 사용할 수 있습니다.

그림 2의 다이어그램은 시스템이 (클라이언트)의 제어권을 전달하는 방법을 보여줍니다. 다른 (서비스) 앱으로 되돌린 후 내 앱으로 돌아옵니다.

  1. 여러분의 앱은 다른 앱의 활동을 호출하는 인텐트를 생성합니다. 이내 이 인텐트에 PendingIntent 객체를 추가로 추가합니다. 이 대기 중인 인텐트는 앱의 구성 요소를 호출합니다. 이 구성요소는 내보낼 수 없습니다.
  2. 다른 앱은 앱의 인텐트를 수신하자마자 중첩된 PendingIntent 객체.
  3. 다른 앱은 PendingIntent 객체에서 send() 메서드를 호출합니다.
  4. 제어권을 앱에 다시 전달한 후 시스템은 대기 중인 인텐트를 사용하여 인텐트를 처리할 수 있습니다.

그림 2. 중첩된 대기 중 사용 시 앱 간 통신 다이어그램 인텐트를 지정할 수 있습니다.

암시적 인텐트 수신

앱이 수신할 수 있는 암시적 인텐트를 알리려면 인텐트 필터를 하나 이상 선언합니다. <intent-filter>를 사용하여 각 앱 구성요소 요소가 매니페스트 파일에 있어야 합니다. 각 인텐트 필터는 인텐트의 작업에 따라 수락하는 인텐트의 유형을 지정합니다. 데이터, 카테고리 등이 있습니다 시스템은 앱 구성 요소에 암시적 인텐트를 전달합니다. 인텐트 필터 중 하나를 통과할 수 있습니다.

참고: 명시적 인텐트는 항상 자신의 대상에 전달되며, 이는 구성 요소가 어떤 인텐트 필터를 선언하든 무관합니다.

앱 구성요소는 수행할 수 있는 각 고유한 작업에 대해 별도의 필터를 선언해야 합니다. 예를 들어 이미지 갤러리 앱의 한 활동에 두 개의 필터(하나의 필터)가 있을 수 있습니다. 이미지를 볼 수 있고 이미지를 편집하기 위한 또 다른 필터가 있습니다. 활동이 시작되면 Intent를 검사하고 정보에 기반하여 동작 방식을 결정합니다. Intent에 있습니다 (편집기 컨트롤 표시 여부 등).

각 인텐트 필터는 <intent-filter>에 의해 정의됩니다. 앱 매니페스트 파일에 있는 해당 앱 구성요소에 중첩되며 (예: (으)로 <activity> 요소).

<intent-filter> 요소가 포함된 각 앱 구성요소에서 명시적으로 android:exported 이 속성은 앱 구성요소에 다른 앱이 액세스할 수 있는지 여부를 나타냅니다. 일부 인텐트 필터에 LAUNCHER 드림 속성을 true로 설정하는 것이 좋습니다. 그렇지 않으면 이 속성을 false로 설정하는 것이 더 안전합니다.

경고: 활동, 서비스, 방송이 앱의 수신기가 인텐트 필터를 사용하고 값을 명시적으로 설정하지 않음 android:exported의 경우 다음 기기에 앱을 설치할 수 없습니다. Android 12 이상을 실행합니다.

<intent-filter> 내부 하나 이상을 사용하여 허용할 인텐트 유형을 지정할 수 있습니다. 다음과 같습니다.

<action>
name 속성에서 허용된 인텐트 작업을 선언합니다. 이 값은 어떤 작업의 리터럴 문자열 값이어야 하며, 클래스 상수가 아닙니다.
<data>
다양한 형식을 지정하는 하나 이상의 속성을 사용하여 허용되는 데이터 유형을 선언합니다. 데이터 URI의 측면 (scheme, host, port, path) 및 MIME 유형을 지원합니다.
<category>
name 속성에서 허용된 인텐트 카테고리를 선언합니다. 값은 클래스 상수가 아니라 작업의 리터럴 문자열 값이어야 합니다.

참고: 암시적 인텐트를 수신하려면 다음을 실행합니다. 반드시 CATEGORY_DEFAULT 카테고리를 지정해야 합니다. 메서드 startActivity()startActivityForResult()는 모든 인텐트를 처리함 마치 CATEGORY_DEFAULT 카테고리를 선언한 것처럼 말이죠. 인텐트 필터에서 이 카테고리를 선언하지 않으면 어떤 암시적 인텐트도 확인할 수 있습니다.

예를 들어 다음은 데이터 유형이 텍스트인 경우 ACTION_SEND 인텐트:

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

두 개 이상의 <action>님, <data> 또는 <category>: 그렇게 하는 경우, 구성 요소가 모든 작업을 처리할 수 있는지 확인해야 합니다. 조합할 수 있습니다.

여러 가지 종류의 인텐트를 처리하고자 하되 특정 조합의 작업, 데이터, 카테고리 유형으로만 한정하고자 한다면 여러 가지 인텐트 필터를 생성해야 합니다.

암시적 인텐트는 인텐트를 각 인텐트와 비교하여 필터에 대해 테스트됩니다. 세 가지 요소로 구성됩니다. 인텐트가 구성 요소에 전달되려면 세 가지 테스트를 모두 통과해야 합니다. 그중 하나라도 일치하지 않으면 Android 시스템은 인텐트를 구성요소를 사용합니다. 그러나 구성 요소에 여러 개의 인텐트 필터가 있을 수 있으므로 구성요소의 필터 중 하나를 통과하지 않으면 다른 필터를 통과할 수 있습니다. 시스템이 인텐트를 확인하는 방법에 관한 자세한 내용은 아래 섹션에 나와 있습니다. 인텐트 확인에 대해.

주의: 인텐트 필터를 사용하는 것은 다른 앱이 시작되지 못하도록 하는 안전한 방법은 아닙니다. 구성할 수 있습니다. 인텐트 필터는 구성요소가 여러분의 앱 구성 요소를 시작할 가능성이 있는 경우, 다른 앱이 잠재적으로 명시적 인텐트를 사용하면 됩니다. 자체 앱만 구성요소 중 하나를 시작할 수 있는 것이 중요한 경우 매니페스트에서 인텐트 필터를 선언하지 않습니다. 대신 exported 속성 그 구성요소의 "false"로 변경합니다.

마찬가지로 실수로 다른 앱의 Service: 항상 명시적 인텐트를 사용하여 자체 서비스를 시작합니다.

참고: 모든 활동에 관해 매니페스트 파일에서 인텐트 필터를 선언해야 합니다. 그러나 broadcast receiver의 필터는 다음을 호출하여 동적으로 등록할 수 있습니다. registerReceiver() 그런 다음 unregisterReceiver()를 사용하여 수신자를 등록 취소할 수 있습니다. 이렇게 하면 앱이 실행되는 동안에 정해진 기간 동안만 특정한 브로드캐스트에 대해 수신 대기할 수 있습니다.

필터 예시

다음은 인텐트 필터 동작의 몇 가지 예입니다. 소셜 공유 앱의 매니페스트 파일에서 가져올 수 있습니다.

<activity android:name="MainActivity" android:exported="true">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity" android:exported="false">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

첫 번째 활동인 MainActivity는 앱의 기본 진입점인 는 사용자가 런처 아이콘으로 앱을 처음 실행하면 열립니다.

  • ACTION_MAIN 작업 는 이것이 기본 진입점이며 어떠한 인텐트 데이터도 예상하지 않음을 나타냅니다.
  • CATEGORY_LAUNCHER 카테고리는 이 활동의 아이콘은 시스템의 앱 런처에 있어야 합니다. <activity> 요소가 icon로 아이콘을 지정하지 않으면 시스템은 <application> 요소의 아이콘을 사용합니다.

이들 두 가지가 짝을 이루어야 액티비티가 앱 시작 관리자에 나타날 수 있습니다.

두 번째 활동인 ShareActivity는 텍스트와 미디어 공유를 용이하게 하기 위한 것입니다. 있습니다. 사용자가 MainActivity에서 이 액티비티로 이동하여 진입할 수도 있지만, 두 가지 인텐트 필터 중 하나와 일치하는 암시적 인텐트를 발생시키는 다른 앱에서 ShareActivity에 직접 진입할 수도 있습니다.

참고: MIME 유형, application/vnd.google.panorama360+jpg는 이 작업은 Google 파노라마 API를 사용합니다.

인텐트를 다른 앱과 일치 인텐트 필터

다른 앱이 Android 13 (API 수준 33) 이상을 타겟팅하는 경우 앱의 인텐트가 앱의 작업 및 카테고리와 일치하는 경우에만 <intent-filter> 요소가 있어야 합니다. 시스템에서 일치하지 않으면 ActivityNotFoundException 전송 앱은 이 예외를 적용할 수 있습니다.

마찬가지로 Android 13 이상을 타겟팅하도록 앱을 업데이트하면 외부 앱에서 발생한 모든 인텐트는 앱에서 선언한 <intent-filter> 요소의 작업 및 카테고리와 일치하는 경우에만 앱의 내보낸 구성요소로 전달됩니다. 이 동작은 전송 앱의 타겟 SDK 버전에 관계없이 발생합니다.

다음과 같은 경우에는 인텐트 일치가 적용되지 않습니다.

  • 인텐트 필터를 선언하지 않는 구성요소에 전달된 인텐트
  • 동일한 앱 내에서 발생한 인텐트
  • 시스템에서 발생한 인텐트. 즉, '시스템 UID'(uid=1000)에서 전송되는 인텐트입니다. 시스템 앱에는 android:sharedUserIdandroid.uid.system으로 설정하는 앱과 system_server가 포함됩니다.
  • 루트에서 발생한 인텐트

인텐트 일치 자세히 알아보기

보류 인텐트 사용

PendingIntent 객체는 Intent 객체를 둘러싼 래퍼입니다. PendingIntent의 주요 용도 외국 애플리케이션에 권한을 부여하는 포함된 Intent를 앱 자체 프로세스를 만드는 것입니다

보류 인텐트의 주요 사용 사례는 다음과 같습니다.

Intent 객체가 특정 앱 구성요소의 유형 (Activity, Service 또는 BroadcastReceiver)이므로 PendingIntent도 다음과 같아야 합니다. 생성할 수 있습니다. 대기 중 인텐트를 사용하는 경우 앱은 startActivity()와 같은 호출로 인텐트를 실행합니다. 대신 원하는 구성요소 유형을 선언해야 합니다. 이때 각 생성자 메서드를 호출하여 PendingIntent합니다.

앱이 다른 앱에서 대기 중인 인텐트를 수신하지 않는 한 PendingIntent를 만드는 위의 메서드가 유일한 방법일 수 있습니다. 필요한 PendingIntent 메서드가 있습니다.

각 메서드는 현재 앱 Context를 가져와 래핑하려는 Intent 및 인텐트를 사용하는 방법 (예: 인텐트를 두 번 이상 사용할 수 있는지 여부)

대기 중인 인텐트 사용에 관한 자세한 내용은 각 인텐트에 관한 문서를 참조하세요. 알림App Widgets API 가이드를 참조하세요.

변경 가능 여부 지정

앱이 Android 12 이상을 타겟팅하는 경우 앱에서 만드는 각 PendingIntent 객체의 변경 가능 여부 선언적으로 주어진 PendingIntent 객체가 변경 가능하거나 변경 불가능한 경우 PendingIntent.FLAG_MUTABLE 또는 PendingIntent.FLAG_IMMUTABLE 플래그를 각각 지정합니다.

앱에서 PendingIntent 객체를 만들려고 시도하는 경우 변경 가능 여부 플래그를 설정하지 않으면 시스템에서 IllegalArgumentException 외 다음 메시지가 Logcat에 표시됩니다.

PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.

가능한 경우 변경 불가능한 대기 중인 인텐트 만들기

대부분의 경우 앱에서는 다음 코드 스니펫과 같이 변경 불가능한 PendingIntent 객체를 만들어야 합니다. PendingIntent 객체를 변경할 수 없으면 다른 앱은 인텐트를 수정하여 인텐트 호출의 결과를 조정할 수 없습니다.

Kotlin

val pendingIntent = PendingIntent.getActivity(applicationContext,
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE)

자바

PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE);

그러나 특정 사용 사례에서는 대신 변경 가능한 PendingIntent 객체가 필요합니다.

  • 바로 답장 작업 지원 알림을 받을 수 있습니다. 이 바로 회신을 사용하려면 PendingIntent 객체의 클립 데이터를 변경해야 함 표시됩니다. 일반적으로 FILL_IN_CLIP_DATAfillIn() 메서드를 사용하여 축소하도록 요청합니다.
  • 다음 인스턴스를 사용하여 알림을 Android Auto 프레임워크와 연결합니다. CarAppExtender
  • 인스턴스를 사용하여 대화를 대화창에 배치 /PendingIntent 변경 가능한 PendingIntent 객체를 사용하면 시스템에서 FLAG_ACTIVITY_MULTIPLE_TASKFLAG_ACTIVITY_NEW_DOCUMENT와 같은 올바른 플래그를 적용할 수 있습니다.
  • 다음을 호출하여 기기 위치 정보 요청 requestLocationUpdates() 드림 API에 액세스할 수 있습니다 변경 가능한 PendingIntent 객체를 사용하면 시스템에서 위치 수명 주기 이벤트를 나타내는 인텐트 추가 항목. 이러한 이벤트에는 공급업체를 사용할 수 있게 됩니다.
  • AlarmManager를 사용하여 알람을 예약합니다. 변경 가능한 PendingIntent 객체를 사용하면 시스템에서 EXTRA_ALARM_COUNT 인텐트 추가 항목을 사용합니다. 이 추가 항목은 반복 알람이 울리는 횟수를 나타냅니다. 트리거되었습니다. 이 추가 항목을 포함함으로써 인텐트는 반복 알람이 여러 번 트리거되었는지 여부(예: 알림을 받습니다.

앱에서 변경 가능한 PendingIntent 객체를 만드는 경우 이 객체를 사용하는 것이 좋습니다. 명시적 인텐트를 사용하고 ComponentName 이렇게 하면 다른 앱이 PendingIntent를 호출하고 제어 기능을 앱에 다시 전달할 때마다 앱의 동일한 구성요소가 항상 시작됩니다.

대기 중인 인텐트 내에서 명시적 인텐트 사용

다른 앱이 내 앱의 대기 중인 인텐트를 사용하는 방법을 더 잘 정의하려면 항상 대기 중인 인텐트를 명시적 인텐트로 래핑합니다. 이 권장사항을 따르려면 다음 단계를 따르세요.

  1. 기본 인텐트의 작업, 패키지, 구성요소 필드 확인 설정되어 있는지 확인합니다.
  2. FLAG_IMMUTABLE 사용 를 추가하여 대기 중인 인텐트를 생성하도록 했습니다. 이 플래그 PendingIntent를 수신하는 앱이 속성을 사용할 수 있습니다. 앱의 minSdkVersion이 다음과 같은 경우 22 이하에서는 보안 및 호환성을 함께 제공할 수 있습니다. 다음 코드를 사용합니다.

    if (Build.VERSION.SDK_INT >= 23) {
      // Create a PendingIntent using FLAG_IMMUTABLE.
    } else {
      // Existing code that creates a PendingIntent.
    }

인텐트 확인

시스템이 액티비티를 시작하라는 암시적 인텐트를 수신하면, 시스템은 해당 인텐트에 대한 최선의 액티비티를 검색합니다. 이때 다음과 같은 세 가지 측면을 근거로 인텐트를 인텐트 필터에 비교합니다.

  • 액션
  • 데이터(URI와 데이터 유형 둘 다).
  • 카테고리.

다음 섹션에서는 인텐트가 적절한 구성요소에 매칭되는 방식을 설명합니다. 인텐트 필터 선언에 따라 인텐트 필터 선언을 지정합니다.

작업 테스트

허용된 인텐트 작업을 지정하기 위해 인텐트 필터는 0개 이상을 선언할 수 있습니다. <action> 요소.

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

이 필터를 통과하려면 Intent에 지정된 작업이 필요합니다. 필터에 나열된 작업 중 하나와 일치해야 합니다.

필터에 작업이 나열되지 않으면 일치시켜 모든 인텐트가 테스트에 실패합니다. 하지만 Intent 작업을 지정하지 않고, 필터가 실행되고 에 작업이 하나 이상 포함되어 있습니다.

카테고리 테스트

허용된 인텐트 카테고리를 지정하기 위해 인텐트 필터는 0개 이상을 선언할 수 있습니다. <category> 요소.

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

인텐트가 카테고리 테스트를 통과하려면 Intent의 모든 카테고리가 있어야 합니다. 필터의 카테고리와 일치해야 합니다. 반대의 경우는 필요하지 않습니다. 즉, 인텐트 필터는 IntentIntent이(가) 아직 통과합니다. 따라서 카테고리가 없는 인텐트는 필터에 선언된 카테고리와 관계없이 항상 이 테스트를 통과합니다.

참고: Android에서 CATEGORY_DEFAULT 카테고리를 자동으로 적용합니다. startActivity()startActivityForResult()에 전달된 모든 암시적 인텐트에 전달되었습니다. 활동이 암시적 인텐트를 수신하도록 하려면 다음과 같이 인텐트 필터에 "android.intent.category.DEFAULT" 카테고리를 포함합니다. 이전 <intent-filter> 예에 나온 것처럼 말입니다.

데이터 테스트

허용된 인텐트 데이터를 나타내기 위해 인텐트 필터는 0개 이상의 <data> 요소를 선언할 수 있습니다. 다음 예를 참고하세요.

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

<data> 요소는 URI 구조와 데이터 유형(MIME 미디어 유형)을 지정할 수 있습니다. URI의 각 부분은 속성: scheme, host, port, 및 path:

<scheme>://<host>:<port>/<path>

다음 예시는 이 특성에 사용 가능한 값을 보여줍니다.

content://com.example.project:200/folder/subfolder/etc

이 URI에서 구성표는 content, 호스트는 com.example.project, 포트는 200, 경로는 folder/subfolder/etc입니다.

이러한 각 속성은 <data> 요소에서 선택사항입니다. 그러나 선형 종속 항목이 있습니다.

  • 구성표가 지정되지 않으면 호스트가 무시됩니다.
  • 호스트가 지정되지 않으면 포트가 무시됩니다.
  • 구성표와 호스트가 둘 다 지정되지 않으면 경로가 무시됩니다.

인텐트 안의 URI가 필터의 URI 사양에 비교될 때, 필터에 포함된 URI의 부분과만 비교됩니다. 예를 들면 다음과 같습니다.

  • 필터가 구성표만 지정하는 경우, 해당 구성표가 있는 모든 URI가 일치합니다. 필터
  • 필터가 구성표와 권한은 지정하지만 경로는 지정하지 않는 경우, 모든 URI는 경로에 관계없이 필터를 통과합니다.
  • 필터가 구성표, 권한과 경로를 지정하는 경우 같은 구성표를 가진 URI만 인증하고 경로가 필터를 통과합니다.

참고: 경로 사양은 와일드 카드 별표 (*)를 사용하여 경로 이름을 부분적으로만 검색하도록 할 수 있습니다.

데이터 테스트는 인텐트 안의 URI와 MIME 유형 둘 모두를 필터 안에서 지정된 MIME 유형과 비교합니다. 규칙은 다음과 같습니다.

  1. URI도 MIME 유형도 포함하지 않는 인텐트는 필터가 URI 또는 MIME 유형을 지정하지 않는 경우에만 테스트하세요.
  2. URI는 포함되어 있지만 MIME 유형은 없는 인텐트입니다( URI)는 URI가 필터의 URI 형식과 일치하는 경우에만 테스트를 통과합니다. 마찬가지로 필터는 MIME 유형을 지정하지 않습니다.
  3. MIME 유형은 있지만 URI는 없는 인텐트가 테스트를 통과함 필터가 동일한 MIME 유형을 나열하고 URI 형식을 지정하지 않는 경우에만
  4. URI와 MIME 유형이 둘 다 들어 있는 인텐트(URI로부터는 명시적이지도 않고 추론할 수도 없음)는 해당 유형이 필터에 나열된 유형과 일치하는 경우에만 MIME 유형 부분의 테스트를 통과합니다. 테스트의 URI 부분을 통과합니다. URI가 필터의 URI와 일치하는지 또는 content:가 있는지 여부 또는 file: URI를 사용하고 필터가 URI를 지정하지 않습니다. 즉, 다음과 같은 경우 구성요소가 content:file: 데이터를 지원하는 것으로 간주됩니다. 필터는 MIME 유형 나열합니다.

참고: 인텐트가 URI 또는 MIME 유형을 지정하면 데이터 테스트는 <intent-filter><data> 요소가 없으면 실패합니다.

이 마지막 규칙인 규칙 (d)는 구성 요소가 파일 또는 콘텐츠 제공자로부터 로컬 데이터를 가져올 수 있다는 기대를 반영한 것입니다. 따라서 필터는 데이터 유형만 나열할 수 있으며 명시적으로 지정하지 않아도 됩니다. content:file: 스키마의 이름을 지정합니다. 다음 예는 <data> 요소가 호출되는 일반적인 사례를 보여줍니다. 구성요소가 콘텐츠에서 이미지 데이터를 가져올 수 있음을 Android에 알립니다. 다음과 같이 표시합니다.

<intent-filter>
    <data android:mimeType="image/*" />
    ...
</intent-filter>

데이터 유형은 지정하지만 URI는 지정하지 않는 필터가 가장 보편적일 것입니다. 그 이유는 대부분의 사용 가능한 데이터를 콘텐츠 제공자가 제공하기 때문입니다.

다른 보편적인 구성을 예로 들자면 구성표와 데이터 유형을 가진 필터가 있겠습니다. 대상 예: <data> 요소는 Android에 구성요소는 작업을 수행하기 위해 네트워크에서 동영상 데이터를 가져올 수 있습니다.

<intent-filter>
    <data android:scheme="http" android:mimeType="video/*" />
    ...
</intent-filter>

인텐트 일치

인텐트를 감지할 뿐만 아니라 인텐트 필터와 대조 요소군에 대한 정보를 얻을 수 있습니다. 구성 요소가 포함됩니다. 예를 들어 Home 앱이 앱 런처를 채웁니다. 특정 인텐트 필터를 지정하는 인텐트 필터가 있는 ACTION_MAIN 작업 및 CATEGORY_LAUNCHER 카테고리 인텐트의 작업과 카테고리가 일치하는 경우에만 일치가 성공합니다. IntentFilter 클래스에 대해 자세히 알아보세요.

애플리케이션은 홈 앱과 같은 방식으로 인텐트 매칭을 사용합니다. PackageManager에는 query...() 세트가 있습니다. 특정 인텐트를 허용할 수 있는 모든 구성 요소를 반환하는 메서드와 유사한 일련의 resolve...() 메서드를 사용하여 구성요소를 사용하여 인텐트에 응답합니다. 예를 들어 queryIntentActivities()는 실행할 수 있는 모든 활동의 목록을 반환합니다. 인텐트가 인수로 전달되고 queryIntentServices()가 유사한 서비스 목록을 반환합니다. 두 메서드 모두 구성요소를 활성화하지 않습니다. 해당 광고 항목에 대해 있습니다. 비슷한 방법도 있는데 queryBroadcastReceivers(): broadcast receiver용