안드로이드 탐구 : Intent

Skele·2025년 3월 27일
0

Intent

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는 컴포넌트 간에 작업을 요청하거나 데이터를 전달할 때 사용되는 메시지 객체이다.

Usage

Intent의 사용처는 크게 세가지로 나눌 수 있다.

Starting Activity

startActivity로 새로운 Activity를 실행할 수 있다.

public abstract void startActivity (Intent intent)

또한 onActivityResult 콜백을 통해 실행한 Activity가 종료될 때 Intent를 수신할 수 있다.

Starting Service

startService를 통해 서비스를 실행 할 수 있다.

public abstract ComponentName startService (Intent service)

Deliver Broadcast

브로드 캐스트 메시지를 발신/수신할 수 있다.

public abstract void sendBroadcast (Intent intent)

안드로이드 시스템은 다양한 시스템 이벤트들을 브로드캐스트를 통해 전달한다.

Structure

Primary Information

Action

수행할 작업

val intent = Intent(Intent.ACTION_VIEW)

Data

작업에 사용될 Uri로 표현된 데이터

val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.example.com"))

Secondary Attribute

Category

실행할 작업에 대한 추가 정보를 제공

val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_LAUNCHER)

Type

데이터의 명시적 유형(MIME type)을 지정

val intent = Intent(Intent.ACTION_SEND)
intent.type = "image/png"

Component

작업을 실행할 컴포넌트 클래스 이름을 지정

val intent = Intent()
intent.component = ComponentName("com.example.app", "com.example.app.TargetActivity")

Extras

추가적인 정보에 대한 Bundle

val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("userId", 1234)

Intent Types

Explicit Intent

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 Intent

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)
}

하지만, 이 방식은 다른 앱들이 액션을 수행할 수 있는지 '조회' 하는 방식이기 때문에 별도의 제약이 따른다.

Queries

앱이 다른 앱에 접근하는 것이 보안상 많은 문제를 일으킬 수 있기에 안드로이드는 많은 제약 사항을 둔다. 그렇기에 앱에서 다른 앱의 패키지 정보, 액티비티, 서비스 등을 조회하려면 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>

Intent-Filter

컴포넌트가 어떤 인텐트를 수신할 수 있는지 정의한다. 이를 통해 외부 앱이 해당 컴포넌트를 실행할 수 있다.

<!-- 이미지 공유 인텐트를 수신 -->
<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>
profile
Tireless And Restless Debugging In Source : TARDIS

0개의 댓글