An
Intent, abstract description of an operation to be performed, is a messaging object you can use to request an action from another app component.
Intent는 컴포넌트 간에 작업을 요청하거나 데이터를 전달할 때 사용되는 메시지 객체이다.
Intent의 사용처는 크게 세가지로 나눌 수 있다.
startActivity로 새로운 Activity를 실행할 수 있다.
public abstract void startActivity (Intent intent)
또한 onActivityResult 콜백을 통해 실행한 Activity가 종료될 때 Intent를 수신할 수 있다.
startService를 통해 서비스를 실행 할 수 있다.
public abstract ComponentName startService (Intent service)
브로드 캐스트 메시지를 발신/수신할 수 있다.
public abstract void sendBroadcast (Intent intent)
안드로이드 시스템은 다양한 시스템 이벤트들을 브로드캐스트를 통해 전달한다.
수행할 작업
val intent = Intent(Intent.ACTION_VIEW)
작업에 사용될 Uri로 표현된 데이터
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.example.com"))
실행할 작업에 대한 추가 정보를 제공
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_LAUNCHER)
데이터의 명시적 유형(MIME type)을 지정
val intent = Intent(Intent.ACTION_SEND)
intent.type = "image/png"
작업을 실행할 컴포넌트 클래스 이름을 지정
val intent = Intent()
intent.component = ComponentName("com.example.app", "com.example.app.TargetActivity")
추가적인 정보에 대한 Bundle
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("userId", 1234)
Explicit intents specify which component of which application will satisfy the intent, by specifying a full ComponentName.
명시적 인텐트는 실행하고자 하는 클래스 이름을 알고 있어야하기 때문에 보통 앱 내에서 다른 컴포넌트를 실행하는데 쓰인다.
val downloadIntent = Intent(this, DownloadService::class.java).apply {
data = Uri.parse(fileUrl)
}
startService(downloadIntent)
Implicit intents do not name a specific component, but instead declare a general action to perform, which allows a component from another app to handle it.
암시적 인텐트는 컴포넌트 이름이 아닌 실행하고자 하는 액션을 선언한다.
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, textMessage)
type = "text/plain"
}
try {
startActivity(sendIntent)
} catch (e: ActivityNotFoundException) {
// Intent를 받아 수행할 앱을 찾을 수 없음
}
Intent의 액션에 적절한 앱을 찾지 못할 수도 있다.
Try-Catch가 아닌 적절한 앱이 존재하는지 다른 앱들을 조회하는 방법도 존재한다.
if (sendIntent.resolveActivity(packageManager) != null) {
startActivity(sendIntent)
}
하지만, 이 방식은 다른 앱들이 액션을 수행할 수 있는지 '조회' 하는 방식이기 때문에 별도의 제약이 따른다.
앱이 다른 앱에 접근하는 것이 보안상 많은 문제를 일으킬 수 있기에 안드로이드는 많은 제약 사항을 둔다. 그렇기에 앱에서 다른 앱의 패키지 정보, 액티비티, 서비스 등을 조회하려면 Android 11(API 30)부터는 AndroidManifest.xml에 명시적으로 선언해야 한다. 그리고 앞서 액션 수행이 가능한지 '조회'를 하기 위해서 queries를 사용한다.
<manifest ...>
<queries>
<!-- 특정 앱의 설치 여부 확인 -->
<package android:name="com.example.targetapp" />
<!-- 특정 인텐트를 처리할 수 있는 앱 목록 조회 -->
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/*" />
</intent>
</queries>
</manifest>
컴포넌트가 어떤 인텐트를 수신할 수 있는지 정의한다. 이를 통해 외부 앱이 해당 컴포넌트를 실행할 수 있다.
<!-- 이미지 공유 인텐트를 수신 -->
<activity android:name=".ReceiveShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>