Android 실시간 업데이트
Pushwoosh는 pushwoosh-liveupdates 모듈(SDK 6.9.0 이상)을 통해 Android 실시간 업데이트를 지원합니다. 실시간 업데이트는 진행 중인 진행률 스타일 알림으로, 시스템이 잠금 화면, 알림 창, 상태 표시줄의 상태 칩에 표시하여 사용자가 앱을 열지 않고도 활동을 추적할 수 있도록 합니다.
전체 라이프사이클은 서버에서 주도합니다. 백엔드는 활동이 시작될 때 푸시를 보내고, 진행됨에 따라 더 많은 푸시를 보내며, 끝날 때 마지막 푸시를 보냅니다. SDK는 각각을 자동으로 렌더링합니다.
실시간 업데이트란 무엇인가요
Anchor link to실시간 업데이트는 Android 16 (API 36)에서 사용자가 시작한 시간 민감성 활동을 처음부터 끝까지 표시하는 방법으로 도입되었습니다. 이는 플랫폼의 진행률 중심 알림과 Notification.ProgressStyle API를 기반으로 합니다. 개념적으로 이는 iOS 실시간 활동의 Android 버전입니다.
이 페이지는 Pushwoosh 통합에 대해서만 다룹니다. 플랫폼 동작, 프로모션 규칙 및 디자인 지침에 대해서는 공식 Android 문서를 참조하세요:
실시간 업데이트는 언제 사용하나요
Anchor link to실시간 업데이트는 진행 중이고, 사용자가 시작했으며, 시간 민감성인 활동, 즉 사용자가 지금 당장 적극적으로 관심을 갖는 명확한 시작과 끝이 있는 활동을 위한 것입니다. Pushwoosh 고객을 위한 일반적인 시나리오는 다음과 같습니다:
- 음식 배달 — 주문 접수, 준비 중, 배달 중, 도착.
- 차량 호출 및 택시 — 기사 배정, 이동 중, 도착, 운행 중.
- 주문 및 배송 추적 — 활발하게 운송 중인 주문의 실시간 상태.
- 라이브 스포츠 및 미디어 — 경기가 진행됨에 따른 경기 점수 및 시간.
- 피트니스 — 경과 시간 및 진행 상황이 포함된 활성 운동 또는 달리기.
- 핀테크 — 여러 단계를 거치는 거래 또는 인증 흐름.
라이프사이클은 백엔드가 이미 알고 있는 실제 이벤트(주문 상태 변경, 배달원 이동)에 의해 주도되므로, 실시간 업데이트는 일반적으로 사람이 직접 보내는 것이 아니라 기존 이벤트 흐름에 연결된 하나의 API 호출입니다.
요구 사항
Anchor link to- Android 16 (API 36) 이상. 이전 버전의 기기에서는 모듈이 비활성 상태로 유지되며 모든 실시간 업데이트 API 호출은 안전한 no-op(아무 작업도 하지 않음)입니다.
- Pushwoosh Android SDK 6.9.0 이상.
pushwoosh-liveupdates 모듈 추가하기
Anchor link toapp/build.gradle에 의존성을 추가하세요:
dependencies { implementation 'com.pushwoosh:pushwoosh-liveupdates:<latest-version>'}<latest-version>을 Maven Central의 현재 버전으로 교체하세요.
모듈은 시작 시 자동으로 발견됩니다. 필요한 POST_PROMOTED_NOTIFICATIONS 권한을 선언하고, 자체 알림 채널을 등록하며, 기본 알림 경로보다 먼저 실시간 업데이트 푸시를 가로챕니다. 추가 초기화 코드는 없습니다 — SDK가 진행 중 및 프로모션 플래그를 설정하고, 큰 아이콘을 다운로드하고, 액션 버튼을 매핑하고, 알림을 게시합니다.
실시간 업데이트 보내기
Anchor link toandroid 콘텐츠 블록의 root_params 객체에 실시간 업데이트 필드를 추가하여 Messaging API v2를 통해 실시간 업데이트를 보냅니다. transactional 요청을 사용하세요 — 실시간 업데이트는 추적 중인 활동의 특정 사용자를 대상으로 합니다. schedule 필드는 필수이며, { "after": "0s" }는 즉시 보냅니다. 라이프사이클에는 pw_live_op에 설정된 세 가지 작업이 있습니다:
start— 활동에 대한 첫 번째 푸시. 진행 중인 알림을 게시합니다.update— 동일한 활동에 대한 후속 푸시. 조용히 제자리에서 새로 고칩니다.end— 마지막 푸시. 알림을 해제합니다.
동일한 활동에 속하는 모든 푸시는 동일한 pw_live_id를 공유해야 합니다. 이 ID는 업데이트를 함께 묶어주며, 앱에서 업데이트를 해제할 때도 사용됩니다.
각 푸시는 알림을 완전히 설명합니다 — 이전 푸시에서 아무것도 이어받지 않습니다. 세그먼트 및 큰 아이콘과 같이 유지하려는 모든 필드를 각 update와 함께 다시 보내세요. 생략된 필드는 없는 것으로 렌더링됩니다.
실시간 업데이트 매개변수
Anchor link to이 키들은 android 콘텐츠 블록의 root_params 객체 내에 들어갑니다. 제목, 본문, 큰 아이콘은 표준 Android 푸시 필드(title, body, custom_icon)를 사용합니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
pw_live_op | string | 라이프사이클 작업: start, update 또는 end. 필수. |
pw_live_id | string | 하나의 실시간 업데이트의 모든 푸시가 공유하는 안정적인 활동 ID. 필수. |
pw_live_progress | int | 합산된 세그먼트 길이에 대해 측정된 진행 값. |
pw_live_progress_indeterminate | bool | 구체적인 값 대신 불확정 애니메이션을 표시합니다. |
pw_live_segments | JSON string | 정렬된 진행 세그먼트, 각 {"color": "#RRGGBB", "length": N}. |
pw_live_extras | JSON string | 사용자 지정 스타일 제공자에게 전달되는 임의의 데이터. |
pw_live_when | long | 헤더 시간 앵커, epoch 밀리초 단위. |
pw_live_chronometer | bool | 헤더 시간을 실행 중인 타이머로 표시합니다. |
pw_live_chronometer_count_down | bool | 실행 중인 타이머가 위로 세는 대신 아래로 셉니다. |
pw_live_show_when | bool | 헤더 시간 열을 표시할지 여부. 기본값은 true입니다. |
네 가지 시간 필드는 다음과 같이 결합됩니다: pw_live_show_when이 false로 설정되면 시간이 숨겨집니다. 그렇지 않으면 pw_live_when이 앵커가 되고, pw_live_chronometer는 이를 라이브 카운터로 바꾸며, pw_live_chronometer_count_down은 그 카운터가 거꾸로 실행되게 합니다.
시작 푸시
Anchor link tocurl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "title": "Order #4521", "body": "We are preparing your order", "custom_icon": "https://example.com/restaurant.png", "root_params": { "pw_live_op": "start", "pw_live_id": "order_4521", "pw_live_progress": "1", "pw_live_segments": "[{\"color\":\"#34A853\",\"length\":3},{\"color\":\"#FBBC05\",\"length\":4},{\"color\":\"#4285F4\",\"length\":3}]", "pw_live_extras": "{\"eta\":\"18:40\"}" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'업데이트 푸시
Anchor link to활동이 진행될 때마다 동일한 pw_live_id로 update를 보내세요. 세그먼트와 아이콘을 반복하세요 — 이를 생략한 업데이트는 그것들 없이 렌더링됩니다.
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "title": "Order #4521", "body": "Your courier is on the way", "custom_icon": "https://example.com/restaurant.png", "root_params": { "pw_live_op": "update", "pw_live_id": "order_4521", "pw_live_progress": "7", "pw_live_segments": "[{\"color\":\"#34A853\",\"length\":3},{\"color\":\"#FBBC05\",\"length\":4},{\"color\":\"#4285F4\",\"length\":3}]" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'종료 푸시
Anchor link to마지막 푸시는 작업과 ID만 필요합니다.
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "root_params": { "pw_live_op": "end", "pw_live_id": "order_4521" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'모양 사용자 지정하기
Anchor link toSDK는 pw_live_progress, pw_live_progress_indeterminate, pw_live_segments로 만들어진 기본 진행률 스타일을 제공합니다. 진행률 표시줄을 완전히 제어하려면 LiveUpdateProgressStyleProvider를 구현하고 직접 Notification.ProgressStyle을 만드세요.
제공자는 유일한 사용자 지정 지점입니다. SDK는 여전히 채널 설정, 진행 중 및 프로모션 플래그, 큰 아이콘, 액션 버튼, 헤더 시간을 소유합니다 — 사용자 지정 제공자는 진행률 표시줄만 구성할 수 있으므로 프로모션 자격을 깨뜨릴 수 없습니다. 이는 상태 비저장(stateless)이어야 합니다: 반환된 스타일은 제공된 LiveUpdateState에서만 파생되어야 합니다. 예외가 발생하면 SDK는 기본 스타일로 대체되고 알림은 여전히 게시됩니다.
import android.app.Notification;import androidx.annotation.NonNull;import com.pushwoosh.liveupdates.LiveUpdateProgressStyleProvider;import com.pushwoosh.liveupdates.LiveUpdateSegment;import com.pushwoosh.liveupdates.LiveUpdateState;import java.util.List;
public class OrderStyleProvider implements LiveUpdateProgressStyleProvider { @NonNull @Override public Notification.ProgressStyle createStyle(@NonNull LiveUpdateState state) { Notification.ProgressStyle style = new Notification.ProgressStyle(); if (state.getProgress() != null) { style.setProgress(state.getProgress()); } style.setProgressIndeterminate(state.isProgressIndeterminate());
List<LiveUpdateSegment> segments = state.getSegments(); int boundary = 0; for (int i = 0; i < segments.size(); i++) { LiveUpdateSegment seg = segments.get(i); style.addProgressSegment( new Notification.ProgressStyle.Segment(seg.getLength()).setColor(seg.getColor())); boundary += seg.getLength(); if (i < segments.size() - 1) { style.addProgressPoint(new Notification.ProgressStyle.Point(boundary)); } } return style; }}import android.app.Notificationimport com.pushwoosh.liveupdates.LiveUpdateProgressStyleProviderimport com.pushwoosh.liveupdates.LiveUpdateState
class OrderStyleProvider : LiveUpdateProgressStyleProvider { override fun createStyle(state: LiveUpdateState): Notification.ProgressStyle { val style = Notification.ProgressStyle() state.progress?.let { style.setProgress(it) } style.setProgressIndeterminate(state.isProgressIndeterminate)
val segments = state.segments var boundary = 0 segments.forEachIndexed { i, seg -> style.addProgressSegment( Notification.ProgressStyle.Segment(seg.length).setColor(seg.color)) boundary += seg.length if (i < segments.size - 1) { style.addProgressPoint(Notification.ProgressStyle.Point(boundary)) } } return style }}AndroidManifest.xml에서 <meta-data> 태그로 제공자를 등록하세요. 클래스에는 public no-argument 생성자가 있어야 합니다.
<meta-data android:name="com.pushwoosh.LIVE_UPDATE_STYLE_PROVIDER" android:value="com.example.OrderStyleProvider" />LiveUpdateState.getExtras()를 사용하여 pw_live_extras에서 보낸 JSON을 읽고 스타일을 자신의 비즈니스 데이터에 맞게 조정하세요.
앱에서 실시간 업데이트 관리하기
Anchor link to서버가 모든 start, update, end를 주도하므로, 앱 측에서 실시간 업데이트를 게시하거나 새로 고치는 API는 없습니다. PushwooshLiveUpdates 퍼사드는 서버가 할 수 없는 것, 즉 업데이트를 로컬에서 해제하고 어떤 것이 화면에 표시되는지 확인하는 것만 다룹니다.
import com.pushwoosh.liveupdates.PushwooshLiveUpdates;
// 사용자가 앱 내에서 활동을 완료했을 때,// 서버의 마지막 "end" 푸시를 기다리지 않고 특정 실시간 업데이트를 해제합니다.PushwooshLiveUpdates.endLiveUpdate("order_4521");
// 현재 이 앱에서 표시 중인 활동 ID 목록을 가져옵니다.List<String> active = PushwooshLiveUpdates.getActiveIds();
// 예를 들어 로그아웃 시 이 앱이 표시하는 모든 것을 지웁니다.PushwooshLiveUpdates.endAllLiveUpdates();모든 메서드는 어떤 스레드에서든 안전하게 호출할 수 있으며, Android 16 미만 기기에서는 no-op(아무 작업도 하지 않음)입니다.