알림에서 활동 시작

알림에서 활동을 시작할 때는 사용자가 예상하는 탐색 환경을 유지해야 합니다. 뒤로 버튼을 탭하면 사용자가 앱의 일반적인 워크플로를 통해 홈 화면으로 돌아가야 하며, 최근 화면을 열면 활동이 별도의 작업으로 표시되어야 합니다. 이 탐색 환경을 유지하려면 새 작업에서 활동을 시작하세요.

알림의 탭 동작을 설정하는 기본 접근 방식은 기본 알림 만들기에 설명되어 있습니다. 이 페이지에서는 알림 작업이 새 태스크 및 백 스택을 생성하도록 PendingIntent을 설정하는 방법을 설명합니다. 이 작업은 시작하는 활동 유형에 따라 달라집니다.

  • 일반 활동: 앱의 일반 UX 흐름의 일부로 존재하는 활동입니다. 사용자가 알림에서 Activity로 이동하면 새 작업에 완전한 백 스택이 포함되어야 합니다. 그래야 사용자가 뒤로 버튼을 탭하여 앱 계층 구조를 위로 탐색할 수 있습니다.
  • 특수 활동: 사용자는 알림에서 시작된 경우에만 이 활동을 볼 수 있습니다. 이 활동은 알림 자체에 표시하기 어려운 정보를 제공하여 알림 UI를 확장합니다. 이 활동에는 백 스택이 필요하지 않습니다.

일반 활동 PendingIntent 설정

알림에서 일반 활동을 시작하려면 다음과 같이 새 백 스택을 만들도록 TaskStackBuilder를 사용하여 PendingIntent를 설정합니다.

앱의 활동 계층 구조 정의

앱 매니페스트 파일의 각 <activity> 요소에 android:parentActivityName 속성을 추가하여 활동의 자연스러운 계층 구조를 정의합니다. 아래 예시를 참조하세요.

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<!-- MainActivity is the parent for ResultActivity. -->
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity" />
    ...
</activity>

백 스택이 있는 PendingIntent 작성

활동의 백 스택을 포함하는 활동을 시작하려면 TaskStackBuilder 인스턴스를 만들고 addNextIntentWithParentStack()를 호출하여 시작하려는 활동의 Intent를 전달합니다.

앞서 설명한 대로 각 활동의 상위 활동을 정의하는 한 getPendingIntent()를 호출하여 전체 백 스택을 포함하는 PendingIntent를 수신할 수 있습니다.

// Create an Intent for the activity you want to start.
val resultIntent = Intent(this, ResultActivity::class.java)
// Create the TaskStackBuilder.
val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run {
    // Add the intent, which inflates the back stack.
    addNextIntentWithParentStack(resultIntent)
    // Get the PendingIntent containing the entire back stack.
    getPendingIntent(
        0,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
}

필요한 경우 TaskStackBuilder.editIntentAt()를 호출하여 스택의 Intent 객체에 인수를 추가할 수 있습니다. 이는 사용자가 백 스택의 활동으로 이동할 때 활동에 의미 있는 데이터가 표시되도록 하는 데 필요할 수 있습니다.

그런 다음 평소와 같이 PendingIntent을 알림에 전달할 수 있습니다.

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentIntent(resultPendingIntent)
    // ...
}
with(NotificationManagerCompat.from(this)) {
    notify(NOTIFICATION_ID, builder.build())
}

특수 활동 PendingIntent 설정

알림에서 시작되는 특수 활동에는 뒤로 스택이 필요하지 않으므로 getActivity()를 호출하여 PendingIntent를 만들 수 있습니다. 하지만 매니페스트에서 적절한 작업 옵션을 정의하세요.

  1. 매니페스트에서 <activity> 요소에 다음 속성을 추가합니다.

    android:taskAffinity=""
    코드에서 사용하는 FLAG_ACTIVITY_NEW_TASK 플래그와 함께 이 속성을 비워 두어 이 활동이 앱의 기본 작업으로 이동하지 않도록 합니다. 앱의 기본 어피니티가 있는 기존 작업은 영향을 받지 않습니다.
    android:excludeFromRecents="true"
    사용자가 실수로 다시 탐색하지 않도록 최근 화면에서 새 작업을 제외합니다.

    예를 들면 다음과 같습니다.

    <activity
    android:name=".ResultActivity"
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
    </activity>

  2. 알림을 만들고 발행합니다.

    1. Activity를 시작하는 Intent을 만듭니다.
    2. FLAG_ACTIVITY_NEW_TASK 및 FLAG_ACTIVITY_CLEAR_TASK 플래그를 사용하여 setFlags()를 호출하여 비어 있는 새 작업에서 시작하도록 Activity를 설정합니다.
    3. getActivity()를 호출하여 PendingIntent를 만듭니다.

    예를 들면 다음과 같습니다.

    val notifyIntent = Intent(this, ResultActivity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    val notifyPendingIntent = PendingIntent.getActivity(
        this, 0, notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

  3. 평소와 같이 PendingIntent를 알림에 전달합니다.

    val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
        setContentIntent(notifyPendingIntent)
        // ...
    }
    with(NotificationManagerCompat.from(this)) {
        notify(NOTIFICATION_ID, builder.build())
    }

다양한 작업 옵션과 백 스택의 작동 방식에 관한 자세한 내용은 작업 및 백 스택을 참고하세요.