안드로이드 앱은 컴포넌트 기반의 구조인데, 이를 완성시켜 주는 것이 인텐트이다.
컴포넌트를 실행하기 위해 시스템에 전달하는 메세지 객체로 기능을 수행하는 함수를 제공하지 않고 데이터를 담는 클래스이다.
-> 컴포넌트를 실행하기 위해 시스템에 넘기는 정보
즉, 실행하고자하는 컴포넌트 정보를 담은 인텐트를 구성해서 시스템에 넘기면 시스템에서 인텐트의 정보를 분석해 맞는 컴포넌트를 실행해주는 구조
명시적 / 암시적 인텐트 ?
인텐트에 의해 다른 컴포넌트를 실행할 때 인텐트에 어떤 정보를 담는지에 따라 크게 명시적 인텐트와 암시적 인텐트로 구분된다.
명시적 인텐트
실행하고자 하는 컴포넌트의 클래스명을 인테트에 담는 방법이다.
주로 같은 앱의 컴포넌트에 실행할 때 이용하는 방법이다.
// 명시적 인텐트 실행
// 생성자로 Context와 실행하고자 하는 Class를 준다
// 이처럼 클래스명을 직접 주는 것은 명시적 인텐트
val intent = Intent(this, SecondActivity::class.java)
// 해당 인텐트를 가지고 시스템에게 의뢰하기 위한 메서드
startActivity(intent)
//secondActivity에서 Activity를 끄고 돌아가기
btn.setOnClickListener{
finish()
}
위의 코드처럼 직접 클래스 명을 담는 것을 명시적 인텐트라고 한다.
자신의 앱의 클래스명은 확실히 알고 있으므로 명시적 인텐트를 사용하여 컴포넌트를 실행
++추가적으로 값을 넘기는 방법
val id = findViewById<EditText>(R.id.idEditText).text.toString()
val intent = Intent(this, HomeActivity::class.java)
intent.putExtra("dataFromSignInId",id)
putExtra로 "dataFromSignInId"라는 명으로 보내고 받을 수 있다.
val idData = intent.getStringExtra("dataFromSignInId")
val showId = findViewById<TextView>(R.id.takeIdTextView)
showId.text = idData
takeIdTextView라는 TextView에 위에 idEditText라는 EditText에서 입력한 값을 받을 수 있다.
암시적 인텐트
//다른 액티비티를 시작시키기 위해서는 인텐트 안에 작업과 데이터를 지정해야 한다.
//ex)
val call_intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:112"))
startActivity(call_intent)
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="다이얼 작업 시작하기"
android:id="@+id/buttonDialActivity"
android:onClick="doOnBtnClick" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="지도보기 작업 시작하기"
android:id="@+id/buttonMapActivity"
android:onClick="doOnBtnClick" />
fun doOnBtnClick(view: View) {
when (view.getId()) {
R.id.buttonDialActivity -> { // 114 전화번호로 다이얼 작업을 수행할 수 있도록 인텐트 설정
val call_intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:114"))
startActivity(call_intent)
}
R.id.buttonMapActivity -> { // 주어진 위도,경도 위치로 지도를 보여줄 수 있도록 인텐트 설정
val map_intent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:37.565350, 127.01445"))
startActivity(map_intent)
}
}
}
클래스명이 아닌 Intent Filter 정보를 활용한다.
주로 클래스명을 알 수 없는 외부 앱의 컴포넌트를 실행할 때 이용한다.
예를 들어 서로 다른 두 앱 연동 시 다른 앱의 컴포넌트 클래스명을 알 수도 없고, 코드에서 클래스명을 명시할 수도 없다. 그래서 클래스명 대신 Intent Filter 정보를 담아 실행하면 시스템에서 Intent Filter 정보를 해석해서 컴포넌트를 실행하는 것이 암시적 인텐트이다.
AndroidManifest.xml
<activity android:name=".DetailActivity" android:exported="false">
<intent-filter>
<action android:name="kr.co.lee.ACTION_VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>
MainActivity.kt
// 암시적 인텐트 실행
// intent의 action 프로퍼티의 값으로 Manifest.xml에서 정의한 intent-filter의 action 태그의 이름을 설정
val intent = Intent().apply {
action = "kr.co.lee.ACTION_VIEW"
}
// 인텐트를 실행하려고 시도
try {
startActivity(intent)
} catch(e: ActivityNotFoundException) {
// 인텐트를 다룰 액티비티가 없는 경우 앱이 무엇을 해야할지 정의
}
ref