1616
1717package com.example.wear.snippets.alwayson
1818
19- import android.app.Notification
2019import android.app.NotificationChannel
2120import android.app.NotificationManager
2221import android.app.PendingIntent
23- import android.content.Context
2422import android.content.Intent
23+ import android.os.SystemClock
2524import android.util.Log
2625import androidx.core.app.NotificationCompat
2726import androidx.core.content.getSystemService
@@ -30,29 +29,19 @@ import androidx.wear.ongoing.OngoingActivity
3029import androidx.wear.ongoing.Status
3130import com.example.wear.R
3231
33- class AlwaysOnService : LifecycleService () {
32+ abstract class AlwaysOnServiceBase : LifecycleService () {
3433
3534 private val notificationManager by lazy { getSystemService<NotificationManager >() }
3635
3736 companion object {
3837 private const val TAG = " AlwaysOnService"
39- private const val NOTIFICATION_ID = 1001
40- private const val CHANNEL_ID = " always_on_service_channel"
38+ const val NOTIFICATION_ID = 1001
39+ const val CHANNEL_ID = " always_on_service_channel"
4140 private const val CHANNEL_NAME = " Always On Service"
41+
4242 @Volatile
4343 var isRunning = false
4444 private set
45-
46- fun startService (context : Context ) {
47- Log .d(TAG , " Starting AlwaysOnService" )
48- val intent = Intent (context, AlwaysOnService ::class .java)
49- context.startForegroundService(intent)
50- }
51-
52- fun stopService (context : Context ) {
53- Log .d(TAG , " Stopping AlwaysOnService" )
54- context.stopService(Intent (context, AlwaysOnService ::class .java))
55- }
5645 }
5746
5847 override fun onCreate () {
@@ -66,9 +55,7 @@ class AlwaysOnService : LifecycleService() {
6655 super .onStartCommand(intent, flags, startId)
6756 Log .d(TAG , " onStartCommand: Service started with startId: $startId " )
6857
69- // Create and start foreground notification
70- val notification = createNotification()
71- startForeground(NOTIFICATION_ID , notification)
58+ createNotification()
7259
7360 Log .d(TAG , " onStartCommand: Service is now running as foreground service" )
7461
@@ -93,8 +80,13 @@ class AlwaysOnService : LifecycleService() {
9380 Log .d(TAG , " createNotificationChannel: Notification channel created" )
9481 }
9582
96- // [START android_wear_ongoing_activity_create_notification]
97- private fun createNotification (): Notification {
83+ abstract fun createNotification ()
84+ }
85+
86+ class AlwaysOnService1 : AlwaysOnServiceBase () {
87+ override fun createNotification () {
88+ // Creates an ongoing activity that demonstrates how to link the touch intent to the always-on activity.
89+ // [START android_wear_ongoing_activity_create_notification]
9890 val activityIntent =
9991 Intent (this , AlwaysOnActivity ::class .java).apply {
10092 flags = Intent .FLAG_ACTIVITY_SINGLE_TOP
@@ -122,7 +114,6 @@ class AlwaysOnService : LifecycleService() {
122114 .setOngoing(true )
123115
124116 // [START_EXCLUDE]
125- // Create an Ongoing Activity
126117 val ongoingActivityStatus = Status .Builder ().addTemplate(" Stopwatch running" ).build()
127118 // [END_EXCLUDE]
128119
@@ -139,7 +130,120 @@ class AlwaysOnService : LifecycleService() {
139130
140131 ongoingActivity.apply (applicationContext)
141132
142- return notificationBuilder.build()
133+ val notification = notificationBuilder.build()
134+ // [END android_wear_ongoing_activity_create_notification]
135+
136+ startForeground(NOTIFICATION_ID , notification)
137+ }
138+ }
139+
140+ class AlwaysOnService2 : AlwaysOnServiceBase () {
141+ override fun createNotification () {
142+ // Creates an ongoing activity with a static status text
143+
144+ // [START android_wear_ongoing_activity_notification_builder]
145+ // Create a PendingIntent to pass to the notification builder
146+ val pendingIntent =
147+ PendingIntent .getActivity(
148+ this ,
149+ 0 ,
150+ Intent (this , AlwaysOnActivity ::class .java).apply {
151+ flags = Intent .FLAG_ACTIVITY_SINGLE_TOP
152+ },
153+ PendingIntent .FLAG_UPDATE_CURRENT or PendingIntent .FLAG_IMMUTABLE ,
154+ )
155+
156+ val notificationBuilder = NotificationCompat .Builder (this , CHANNEL_ID )
157+ .setContentTitle(" Always On Service" )
158+ .setContentText(" Service is running in background" )
159+ .setSmallIcon(R .drawable.animated_walk)
160+ // Category helps the system prioritize the ongoing activity
161+ .setCategory(NotificationCompat .CATEGORY_WORKOUT )
162+ .setContentIntent(pendingIntent)
163+ .setVisibility(NotificationCompat .VISIBILITY_PUBLIC )
164+ .setOngoing(true ) // Important!
165+ // [END android_wear_ongoing_activity_notification_builder]
166+
167+ // [START android_wear_ongoing_activity_builder]
168+ val ongoingActivity =
169+ OngoingActivity .Builder (applicationContext, NOTIFICATION_ID , notificationBuilder)
170+ // Sets the icon that appears on the watch face in active mode.
171+ .setAnimatedIcon(R .drawable.animated_walk)
172+ // Sets the icon that appears on the watch face in ambient mode.
173+ .setStaticIcon(R .drawable.ic_walk)
174+ // Sets the tap target to bring the user back to the app.
175+ .setTouchIntent(pendingIntent)
176+ .build()
177+ // [END android_wear_ongoing_activity_builder]
178+
179+ // [START android_wear_ongoing_activity_post_notification]
180+ // This call modifies notificationBuilder to include the ongoing activity data.
181+ ongoingActivity.apply (applicationContext)
182+
183+ // Post the notification.
184+ startForeground(NOTIFICATION_ID , notificationBuilder.build())
185+ // [END android_wear_ongoing_activity_post_notification]
186+ }
187+ }
188+
189+ class AlwaysOnService3 : AlwaysOnServiceBase () {
190+ override fun createNotification () {
191+ // Creates an ongoing activity that demonstrates dynamic status text (a timer)
192+ val activityIntent =
193+ Intent (this , AlwaysOnActivity ::class .java).apply {
194+ flags = Intent .FLAG_ACTIVITY_SINGLE_TOP
195+ }
196+
197+ val pendingIntent =
198+ PendingIntent .getActivity(
199+ this ,
200+ 0 ,
201+ activityIntent,
202+ PendingIntent .FLAG_UPDATE_CURRENT or PendingIntent .FLAG_IMMUTABLE ,
203+ )
204+
205+ val notificationBuilder = NotificationCompat .Builder (this , CHANNEL_ID )
206+ .setContentTitle(" Always On Service" )
207+ .setContentText(" Service is running in background" )
208+ .setSmallIcon(R .drawable.animated_walk)
209+ // Category helps the system prioritize the ongoing activity
210+ .setCategory(NotificationCompat .CATEGORY_WORKOUT )
211+ .setContentIntent(pendingIntent)
212+ .setVisibility(NotificationCompat .VISIBILITY_PUBLIC )
213+ .setOngoing(true ) // Important!
214+
215+ // [START android_wear_ongoing_activity_create_status]
216+ // Define a template with placeholders for the activity type and the timer.
217+ val statusTemplate = " #type# for #time#"
218+
219+ // Set the start time for a stopwatch.
220+ // Use SystemClock.elapsedRealtime() for time-based parts.
221+ val runStartTime = SystemClock .elapsedRealtime()
222+
223+ val ongoingActivityStatus = Status .Builder ()
224+ // Sets the template string.
225+ .addTemplate(statusTemplate)
226+ // Fills the #type# placeholder with a static text part.
227+ .addPart(" type" , Status .TextPart (" Run" ))
228+ // Fills the #time# placeholder with a stopwatch part.
229+ .addPart(" time" , Status .StopwatchPart (runStartTime))
230+ .build()
231+ // [END android_wear_ongoing_activity_create_status]
232+
233+ // [START android_wear_ongoing_activity_set_status]
234+ val ongoingActivity =
235+ OngoingActivity .Builder (applicationContext, NOTIFICATION_ID , notificationBuilder)
236+ // [START_EXCLUDE]
237+ .setAnimatedIcon(R .drawable.animated_walk)
238+ .setStaticIcon(R .drawable.ic_walk)
239+ .setTouchIntent(pendingIntent)
240+ // [END_EXCLUDE]
241+ // Add the status to the OngoingActivity.
242+ .setStatus(ongoingActivityStatus)
243+ .build()
244+ // [END android_wear_ongoing_activity_set_status]
245+
246+ ongoingActivity.apply (applicationContext)
247+ startForeground(NOTIFICATION_ID , notificationBuilder.build())
143248 }
144- // [END android_wear_ongoing_activity_create_notification]
145249}
0 commit comments