Messaging and People API를 사용하여 Android 앱에 채팅 관련 기능 추가

1. 시작하기 전에

메시지 앱을 만드는 것은 까다로운 작업입니다. 전반적인 사용자 경험이 주관적이기는 하지만 Android에서는 채팅 경험을 개선하고 간소화할 수 있는 Messaging and People API를 제공합니다.

이 Codelab에서는 이러한 API를 사용해 Android 기반 채팅 앱을 위한 뛰어난 생태계를 조성하는 방법을 알아봅니다. Jetpack Compose를 사용하는 비기능적이며 서비스가 충분하지 않은 채팅 앱인 JetChat 앱을 확장해 봅니다.

기본 요건

  • Android 개발에 관한 기본 지식
  • 알림 관련 기본 지식

빌드할 항목

다음 작업을 수행하는 확장된 JetChat 앱을 빌드합니다.

  • 알림 창의 예약된 대화 섹션에서 대화를 나타내는 알림을 표시합니다.
  • 이러한 알림에서 앱의 대화에 공유할 수 있는 공유 대상을 참조합니다.
  • 앱을 향상하는 시스템에서 제공하는 기본 경험을 활용하기 위해 이러한 객체 생성을 위한 권장사항을 적용합니다.

학습할 내용

  • 알림 창의 예약된 대화 섹션에서 대화 관련 알림을 표시하는 방법
  • Messaging and People API로 지원되는 다양한 경험을 이해하는 방법

필요한 항목

  • Git
  • Android 스튜디오
  • GitHub 계정

2. 설정

JetChat 앱을 기반으로 시작합니다. Messaging and People API를 효과적으로 소개하기 위해 시작 코드는 JetChat 앱을 확장합니다.

시작 코드 가져오기

이 Codelab에서 사용할 시작 코드를 가져오려면 다음 단계를 따르세요.

  1. 명령줄에서 다음 GitHub 저장소를 클론합니다.
git clone –branch starter-code \
https://github.com/android/people-messaging-codelab.git
  1. Android 스튜디오에서 프로젝트를 열고 a1bbb9d97659a043.png Run app을 클릭합니다. Emulator 창이 나타나고 앱이 표시됩니다.

확장된 JetChat 앱 살펴보기

  1. 앱의 메시지 #composers(Message #composers) 텍스트 상자에 메시지를 입력하고 Send(보내기)를 탭합니다.
  2. 앱에서 벗어나 다른 작업을 합니다. 몇 초 후에 채팅에 참여하고 있는 누군가의 응답이 포함된 푸시 알림을 받게 됩니다.

3. 대화 알림 만들기

Android 11에는 채팅 관련 알림이 대화에만 사용하도록 엄격히 제한된 알림 창의 지정된 섹션에 표시되도록 하는 API가 도입되었습니다.

상태 표시줄에서 아래로 스와이프하면 나타나는 알림 창

알림은 반드시 Notification.MessagingStyle 클래스여야 하며 오래 지속되는 공유 바로가기를 참조해야 합니다. 이 섹션에서는 대화 섹션에 대화를 나타내는 이러한 알림을 표시하기 위해 API 요구사항을 충족하는 방법을 알아봅니다.

NotificationCompat.MessagingStyle 클래스의 알림을 만들려면 다음 단계를 따르세요.

  1. Android 스튜디오의 Project 탭에서 app > java > com.example.compose.jetchat > conversation을 클릭한 다음 ConversationFragment를 더블클릭합니다.
  2. ConversationFragment.kt 파일에서 ConversationFragment 클래스를 찾은 다음 알림이 생성된 createNotification 함수의 Notification 코드 블록을 찾습니다.
  3. setContentText 메서드를 setStyle 메서드로 바꿉니다. 이 메서드는 알림 스타일을 NotificationCompat.MessagingStyle 클래스로 설정합니다. 이 도우미 클래스는 보낸 시간 및 보낸 사람과 같은 메시지와 관련된 추가 컨텍스트와 함께 setContextText 메서드로 설정된 메시지를 추가합니다.

ConversationFragment.kt

private fun createNotification(
   notificationId: Int,
   message: Message,
   person: Person,
   shortcut: ShortcutInfoCompat,
   time: Long
): Notification? {
    ...
    .setStyle(NotificationCompat.MessagingStyle(person).addMessage(
                      NotificationCompat.MessagingStyle.Message(
                          message.content,
                          time,
                          person
                      )
    )
    )
    ...
    .build()
}

앱 실행

  1. 앱을 실행합니다.
  2. 앱의 메시지 #composers(Message #composers) 텍스트 상자에 메시지를 입력하고 Send(보내기)를 탭합니다.
  3. 앱에서 벗어나 다른 작업을 합니다. 푸시 알림을 다시 받게 되지만 다른 스타일의 알림입니다. 여기에는 아바타와 메시지의 분명한 스타일이 포함됩니다. 하지만 알림이 해당 위치에 표시되기 전에 해야 할 작업이 더 있습니다.

4. 대화에 사용할 공유 대상 만들기

알림에서 공유 바로가기나 공유 대상을 참조해야 합니다. 공유 대상은 shortcuts.xml 파일에 정의되며 프로그래매틱 방식으로 정의된 바로가기를 처리하기 위한 진입점 역할을 합니다. 생성한 바로가기는 앱에 대화를 나타내며 대화에서 콘텐츠를 공유할 수 있습니다.

공유 대상 정의

  1. Project 탭에서 res 디렉터리를 마우스 오른쪽 버튼으로 클릭한 다음 New > Directory를 선택합니다.
  2. 텍스트 상자에 xml을 입력하고 Enter(macOS에서는 return 키) 키를 누릅니다.
  3. xml 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 File을 선택합니다.
  4. 텍스트 상자에 shortcuts.xml을 입력하고 Enter(macOS에서는 return 키) 키를 누릅니다.
  5. shortcuts.xml 파일에서 text/plain 유형의 데이터 공유를 처리하는 공유 대상을 선언합니다.

shortcuts.xml

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <share-target android:targetClass="com.example.compose.jetchat.NavActivity">
   <data android:mimeType="text/plain" />
   <category android:name="com.example.compose.jetchat.share.TEXT_SHARE_TARGET" />
 </share-target>
</shortcuts>
  1. Project 탭에서 manifests를 클릭한 다음 AndroidManifest.xml을 더블클릭합니다.
  2. AndroidManifest.xml 파일에서 shortcuts.xml 파일을 정의합니다.

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.compose.jetchat">

   <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.Jetchat.NoActionBar">
...
 <meta-data android:name="android.app.shortcuts"
            android:resource="@xml/shortcuts" />

    </application>
</manifest>
  1. AndroidManifest.xml 파일의 activity 구성요소에서 공유 논리가 포함된 인텐트 필터를 정의합니다.

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.compose.jetchat">

   ...
       <activity
           ...
           <intent-filter>
               <action android:name="android.intent.action.SEND" />
               <category android:name="android.intent.category.DEFAULT" />
               <data android:mimeType="text/plain" />
           </intent-filter>
...

바로가기 정의

모든 알림에 대해 관련 바로가기를 연결해야 합니다. 고유한 바로가기는 공유할 연락처 하나를 나타내므로 대화당 고유한 바로가기를 하나만 정의합니다.

바로가기를 생성하려면 다음 단계를 따르세요.

  1. Project 탭에서 app > java > com.example.compose.jetchat > conversation > util을 클릭하고 ConversationUtil을 더블클릭합니다.
  2. ConversationUtil.kt 파일에서 generateShortcut 함수를 추가합니다.

ConversationUtil.kt

import android.content.Intent
import androidx.core.content.pm.ShortcutInfoCompat
import com.example.compose.jetchat.NavActivity

class ConversationUtil {

   companion object {
...
fun generateShortcut(context: Context, shortcutId: String): ShortcutInfoCompat {
   return ShortcutInfoCompat.Builder(context, shortcutId)
   .setCategories(setOf(CATEGORY_SHARE))
   .setLongLived(true)
   .setShortLabel(shortcutId)
   .setLongLabel(shortcutId)
   .setIntent(
       Intent(context, NavActivity::class.java)
           .setAction(Intent.ACTION_VIEW)
   )
   .build()
}

이 함수에는 대화에 필요한 setPersonsetLongLived 메서드가 포함됩니다. Person은 바로가기와 연결된 연락처이며 long-lived를 true 값으로 설정하면 이 바로가기가 시스템에서 캐시되고 UI의 다양한 표시 경로에 나타납니다.

알림의 바로가기 참조

알림의 공유 바로가기를 참조해야 합니다. 따라서 알림을 푸시하기 전에 바로가기를 만들어야 합니다.

단계는 다음과 같습니다.

  1. ConversationFragment.kt 파일에서 ConversationFragment 클래스를 찾습니다.
  2. notification 변수를 호출하기 전에 ConversationUtil.generateShortcut에서 생성된 바로가기를 참조하는 shortcut 변수를 만듭니다.
  3. notification 변수의 createNotification 메서드에서 매개변수로 nullshortcut 변수로 바꿉니다.

ConversationFragment.kt

private fun simulateResponseAsANotification() {
   ...
   if (message.author != "me") {
       ...
       val shortcut = ConversationUtil.generateShortcut(context!!, message.author)
       val notification = createNotification(notificationId, message, person, shortcut, time)
       ...
   }
}
  1. createNotification 메서드에서 NotificationCompat.Builder#setShortcutInfo 메서드를 추가한 다음 매개변수로 shortcut 변수를 전달합니다.

ConversationFragment.kt

private fun createNotification(
  notificatoinIf: Int,
  messagin: Message,
  person: Person,
  shortcut: ShortcutInfoCompat?,
  time: Long
): Notification {
...
return NotificationCompat.Builder(context!!,  ConversationUtil.CHANNEL_MESSAGES)
   ...
   .setShortcutInfo(shortcut)
   .build()
}

바로가기 게시

  • 바로가기를 게시하려면 notificationManager.notify 메서드 앞의 simulateResponseAsANotification 함수에서 pushDynamicShortcut 메서드를 호출합니다.

ConversationFragment.kt

import androidx.core.content.pm.ShortcutManagerCompat

...private fun simulateResponseAsANotification() {
   ...
   if (message.author != "me") {
       ...
       ShortcutManagerCompat.pushDynamicShortcut(context!!, shortcut)
       ...
   }
}

앱 실행

  1. 앱을 실행합니다.
  2. 앱의 메시지 #composers(Message #composers) 텍스트 상자에 메시지를 입력하고 Send(보내기)를 탭합니다.
  3. 앱에서 벗어납니다. 푸시 알림을 다시 받게 되지만 대화 관련 알림으로 더 확실하게 스타일이 지정됩니다. 아바타 아이콘이 더 분명해지고 앱 아이콘과 통합됩니다. 보낸 사람, 시간, 텍스트도 더 간소화됩니다.

5. 선택사항: 대화창 사용 설정

대화창은 Android 9에 도입되었으며 Android 11의 대화 컨텍스트에서 사용할 수 있도록 개선되고 용도가 변경되었습니다. 대화창은 대화에서 아바타 역할을 하는 원형 오버레이입니다. 앱 런처에 표시되어 확장된 대화창에서 대화에 쉽게 응답할 수 있도록 해줍니다. 구현하더라도 사용자의 환경설정에 따라 선택사항입니다.

대화창을 사용 설정하려면 다음 단계를 따르세요.

  1. AndroidManifest.xml 파일에서 allowEmbeddedresizeableActivity 속성을 추가한 다음 각 속성을 true 값으로 설정합니다.

AndroidManifest.xml

<activity
  ...
  android:allowEmbedded="true"
  android:resizeableActivity="true"
  ...
</activity>
  1. ConversationUtil.kt 파일의 ConversationUtil 클래스에서 대화창 메타데이터를 추가합니다.

ConversationUtil.kt

import androidx.core.app.NotificationCompat
import androidx.core.graphics.drawable.IconCompat

fun createBubbleMetadata(context: Context, icon: IconCompat): NotificationCompat.BubbleMetadata {
        // Create bubble intent
        val target = Intent(context, NavActivity::class.java)
        val bubbleIntent = PendingIntent.getActivity(context, REQUEST_BUBBLE, target, flagUpdateCurrent(mutable = true))

        // Create bubble metadata
        return NotificationCompat.BubbleMetadata.Builder(bubbleIntent, icon)
            .setDesiredHeight(400)
            .setSuppressNotification(true)
            .build()
    }
  1. ConversationFragment.kt 파일에서 알림에 대한 대화창 메타데이터를 만들고 참조합니다.

ConversationFragment.kt

private fun createNotification(
  notificatoinIf: Int,
  messagin: Message,
  person: Person,
  shortcut: ShortcutInfoCompat?,
  time: Long
): Notification {
...
// Reference the bubble metadata in the notification.
  return NotificationCompat.Builder(context!!,     ConversationUtil.CHANNEL_MESSAGES)
    ...
     .setBubbleMetadata(ConversationUtil.createBubbleMetadata(context!!, person.icon!!))
...
    .build()
}

앱 실행

  1. 앱을 실행합니다.
  2. 앱의 메시지 #composers(Message #composers) 텍스트 상자에 메시지를 입력하고 Send(보내기)를 탭합니다.
  3. 앱에서 벗어납니다. 몇 초 후에 채팅에서 대화창 형태의 알림을 받게 됩니다.
  4. 대화창을 탭합니다. 대화창에서 대화가 열립니다.

대화창

6. 선택사항: 링크 공유

공유 타겟을 선언하고 알림에서 참조했으며, ACTION 인텐트가 전송될 때 나타나는 상향식 구성요소인 Sharesheet에서 연락처를 표시할 수도 있습니다. 공유 대상은 Sharesheet 상단에 표시되며 대화에서 리치 콘텐츠를 공유할 수 있습니다.

Sharesheet를 호출하려면 다음 단계를 따르세요.

  1. 기기에서 Chrome을 열고 developer.android.com과 같이 원하는 웹페이지로 이동합니다.
  2. 필요한 경우 2fdbaccda71bc5f0.png More vert를 클릭합니다.
  3. 771b0be21764f6b6.png Share를 클릭합니다. Sharesheet가 화면 상단에 나타납니다.

Sharesheet

  1. 가능하면 468248e6b8a84bb3.png JetChat을 클릭합니다. URL이 채팅에서 공유됩니다.
  2. 468248e6b8a84bb3.png JetChat이 표시되지 않으면 145399af71577431.png More를 클릭하여 시스템 Sharesheet를 호출한 다음 ShareSheet를 위로 스와이프하고 468248e6b8a84bb3.png JetChat을 클릭합니다. URL이 채팅에 공유됩니다.

이 예는 간단한 예시일 뿐이며, 공유할 수 있는 훨씬 풍부한 콘텐츠 유형이 있습니다. 자세한 내용은 다른 앱에서 간단한 데이터 검색을 참조하세요.

7. 축하합니다

수고하셨습니다. 지금까지 Messaging and People API를 사용하여 Android 앱에 채팅 관련 기능을 추가하는 방법을 알아보았습니다. 즐거운 채팅 되세요.

자세히 알아보기