티스토리 뷰
Intent
다른 컴포넌트 간 통신하는 역할을 한다.
실행하고자 하는 컴포넌트를 담은 인텐트를 생성하면, 안드로이드 시스템에서 인텐트 정보에 맞는 컴포넌트를 실행한다.
액티비티를 시작하거나, 서비스/브로드캐스트를 시작할 때 Intent에 클래스명을 넣어 사용한다.
명시적 인텐트
val intent = Intent(this, NotificationActivity::class.java)
startActivity(intent)
앱의 패키지명이나 클래스명을 인텐트의 인자로 넣는다.
일반적으로 앱 안의 구성 요소를 시작하고자 할 때 명시적 인텐트를 사용한다.
암시적 인텐트
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, textMessage)
type = "text/plain"
}
if (sendIntent.resolveActivity(packageManager) != null) {
startActivity(sendIntent)
}
특정 패키지명이나 클래스명을 지정하진 않고, 수행할 작업을 지정하는 인텐트를 말한다.
if (sendIntent.resolveActivity(packageManager) != null)
위 코드를 통해 암시적 인텐트에 담긴 정보들을 수행할 수 있는지 확인할 수 있다.
만약 수행할 작업이 없다면 null을 반환한다.
인텐트에 담을 수 있는 정보들
1. ComponentName
시작할 컴포넌트의 이름을 담을 수 있다.
ComponentName을 지정하면 인텐트를 명시적으로 만들어준다.
즉, ComponentName이 없으면 암시적 인텐트가 되어 다른 인텐트 정보를 기반으로 어떤 작업을 수행할지 결정된다.
앱 안의 컴포넌트를 시작해야 하는 경우 ComponentName을 꼭 지정해야 한다.
setComponent(), setClass(), setClassName(), Intent 생성자를 통해 지정한다.
2. action
수행할 작업을 나타내는 문자열이다.
예를 들어 ACTION_VIEW는 사용자에게 어떤 정보를 표시할 때 사용한다.
ACTION_SEND는 사용자가 이메일, sns 등 다른 앱을 통해 공유할 수 있는 데이터를 가지고 있을 때 사용한다.
setAction(), Intent 생성자를 통해 지정한다.
보통은 Intent 클래스 안의 action 상수를 지정하지만, 직접 지정할 수도 있다.
3. data
작업을 수행할 데이터를 지정하는 Uri 객체다.
Uri의 host, port, mimeType 등을 지정할 수 있다.
setData()를 통해 지정한다.
4. category
인텐트 안에 담긴 컴포넌트의 종류에 대한 문자열이다.
예를 들어 CATEGORY_BROWSABLE은 액티비티가 웹브라우저를 시작할 수 있도록 하고,
CATEGORY_LAUNCHER은 액티비티가 앱 시작 시 나타날 수 있도록 한다.
대부분의 인텐트에는 카테고리를 생략해도 된다.
addCategory()로 지정할 수 있다.
5. extra
///-------MainActivity.kt-------///
val intent = Intent(this, SubActivity::class.java).apply {
putExtra("string-key", "123")
putExtra("int-key", 123)
putExtra("boolean-key", false)
}
startActivity(intent)
///-------SubActivity.kt-------///
val str = intent.getStringExtra("string-key") // "123"
val i = intent.getIntExtra("int-key", 0) // 123
val b = intent.getBooleanExtra("boolean-key", true) // false
컴포넌트에 넘길 추가 데이터를 담은 키-값 쌍이다.
putExtra()를 통해 데이터를 담고, 이동한 컴포넌트에서는 get_Extra()를 통해 데이터를 받는다.
6. flag
인텐트에 대한 메타데이터와 같은 기능을 한다.
액티비티를 어떻게 시작할지, 시작한 후 어떻게 처리할지 등을 알려준다.
예를 들어 FLAG_ACTIVITY_NEW_TASK를 지정하면 새로운 task를 생성해 액티비티를 띄운다.
setFlags()를 통해 지정한다.
Manifest.xml ( intent-filter )
앱이 수신할 수 있는 암시적 인텐트가 어떤 것인지 알기 위해서는 manifest에 <intent-filter> 요소를 사용한다.
<intent-filter>에는 <action> <data> <category>가 들어갈 수 있고 방금 설명한 내용과 같다.
암시적 인텐트는 인텐트를 이 세 가지 요소와 비교하여 필터를 확인한다.
세 가지 요소 중 하나라도 다른 점이 있다면 인텐트를 컴포넌트에 전달하지 않는다.
* 인텐트 필터를 사용하면 다른 앱이 자신의 앱 컴포넌트를 시작할 위험이 있다.
자신의 앱만 컴포넌트를 시작할 수 있도록 하려면,
manifest 파일에서 해당하는 컴포넌트에 android:exported="false" 속성을 설정한다.
<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"/>
</intent-filter>
</activity>
예를 들어 데이터 유형이 text고, ACTION_SEND 인텐트를 수신하는 액티비티가 있는 경우 위와 같이 인텐트 필터를 설정한다.
]
*
액티비티1이 인텐트를 통해서 액티비티2로 이동하고, 액티비티2가 종료되었을 때 액티비티1에게 데이터를 보내는 기능이 있었다.
startActivityForResult() API를 통해 구현할 수 있는데, 이 기능은 deprecated 되었다.
대신 registerForActivityResult()를 사용하는 방법이 있는데 이는 다음에 꼭 포스팅 해야겠다.
참조
https://developer.android.com/guide/components/intents-filters?hl=ko
'app > android' 카테고리의 다른 글
[안드로이드/android] Bundle의 개념과 Intent의 차이점, savedInstanceState (0) | 2023.09.25 |
---|---|
[안드로이드/코틀린] BroadcastReceiver 개념, 구현 방법 알아보기 (0) | 2023.09.25 |
[안드로이드/코틀린] PendingIntent 개념 알아보기 (0) | 2023.09.25 |
[안드로이드/코틀린] fragment에서 context, activity를 얻는 방법 (0) | 2023.09.23 |
[안드로이드/코틀린] onBackPressed() deprecated 대체 방법, OnBackPressedCallback 알아보기 (0) | 2023.09.23 |