Skip to content

Commit 6aece6c

Browse files
committed
Restore deprecated snippets for now
1 parent a366c69 commit 6aece6c

1 file changed

Lines changed: 191 additions & 1 deletion

File tree

wear/src/main/java/com/example/wear/snippets/alwayson/AlwaysOnActivity.kt

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,196 @@
1616

1717
package com.example.wear.snippets.alwayson
1818

19+
import android.Manifest
20+
import android.content.Intent
21+
import android.content.pm.PackageManager
22+
import android.os.Build
23+
import android.os.Bundle
24+
import android.os.SystemClock
25+
import android.util.Log
1926
import androidx.activity.ComponentActivity
27+
import androidx.activity.compose.setContent
28+
import androidx.activity.result.contract.ActivityResultContracts
29+
import androidx.compose.foundation.layout.PaddingValues
30+
import androidx.compose.foundation.layout.Spacer
31+
import androidx.compose.foundation.layout.fillMaxSize
32+
import androidx.compose.foundation.layout.height
33+
import androidx.wear.compose.foundation.lazy.AutoCenteringParams
34+
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
35+
import androidx.wear.compose.foundation.lazy.items
36+
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
37+
import androidx.compose.runtime.Composable
38+
import androidx.compose.runtime.getValue
39+
import androidx.compose.runtime.mutableStateOf
40+
import androidx.compose.runtime.produceState
41+
import androidx.compose.runtime.saveable.rememberSaveable
42+
import androidx.compose.runtime.setValue
43+
import androidx.compose.ui.Alignment
44+
import androidx.compose.ui.Modifier
45+
import androidx.compose.ui.platform.LocalContext
46+
import androidx.compose.ui.tooling.preview.Preview
47+
import androidx.compose.ui.unit.dp
48+
import androidx.core.content.ContextCompat
49+
import androidx.wear.compose.material3.MaterialTheme
50+
import androidx.wear.compose.material3.SwitchButton
51+
import androidx.wear.compose.material3.Text
52+
import androidx.wear.compose.material3.dynamicColorScheme
53+
import androidx.wear.tooling.preview.devices.WearDevices
54+
import com.google.android.horologist.compose.ambient.AmbientAware
55+
import com.google.android.horologist.compose.ambient.AmbientState
56+
import kotlinx.coroutines.delay
2057

21-
class AlwaysOnActivity : ComponentActivity()
58+
private const val TAG = "AlwaysOnActivity"
59+
60+
class AlwaysOnActivity : ComponentActivity() {
61+
private val requestPermissionLauncher =
62+
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
63+
if (isGranted) {
64+
Log.d(TAG, "POST_NOTIFICATIONS permission granted")
65+
} else {
66+
Log.w(TAG, "POST_NOTIFICATIONS permission denied")
67+
}
68+
}
69+
70+
override fun onCreate(savedInstanceState: Bundle?) {
71+
super.onCreate(savedInstanceState)
72+
Log.d(TAG, "onCreate: Activity created")
73+
74+
setTheme(android.R.style.Theme_DeviceDefault)
75+
76+
// Check and request notification permission
77+
checkAndRequestNotificationPermission()
78+
79+
setContent { WearApp() }
80+
}
81+
82+
private fun checkAndRequestNotificationPermission() {
83+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
84+
when {
85+
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
86+
PackageManager.PERMISSION_GRANTED -> {
87+
Log.d(TAG, "POST_NOTIFICATIONS permission already granted")
88+
}
89+
shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS) -> {
90+
Log.d(TAG, "Should show permission rationale")
91+
// You could show a dialog here explaining why the permission is needed
92+
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
93+
}
94+
else -> {
95+
Log.d(TAG, "Requesting POST_NOTIFICATIONS permission")
96+
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
97+
}
98+
}
99+
}
100+
}
101+
}
102+
103+
@Composable
104+
// [START android_wear_ongoing_activity_elapsedtime]
105+
fun ElapsedTime(ambientState: AmbientState) {
106+
// [START_EXCLUDE]
107+
val startTimeMs = rememberSaveable { SystemClock.elapsedRealtime() }
108+
109+
val elapsedMs by
110+
produceState(initialValue = 0L, key1 = startTimeMs) {
111+
while (true) { // time doesn't stop!
112+
value = SystemClock.elapsedRealtime() - startTimeMs
113+
// In ambient mode, update every minute instead of every second
114+
val updateInterval = if (ambientState.isAmbient) 60_000L else 1_000L
115+
delay(updateInterval - (value % updateInterval))
116+
}
117+
}
118+
119+
val totalSeconds = elapsedMs / 1_000L
120+
val minutes = totalSeconds / 60
121+
val seconds = totalSeconds % 60
122+
123+
// [END_EXCLUDE]
124+
val timeText =
125+
if (ambientState.isAmbient) {
126+
// Show "mm:--" format in ambient mode
127+
"%02d:--".format(minutes)
128+
} else {
129+
// Show full "mm:ss" format in interactive mode
130+
"%02d:%02d".format(minutes, seconds)
131+
}
132+
133+
Text(text = timeText, style = MaterialTheme.typography.numeralMedium)
134+
}
135+
// [END android_wear_ongoing_activity_elapsedtime]
136+
137+
@Preview(
138+
device = WearDevices.LARGE_ROUND,
139+
backgroundColor = 0xff000000,
140+
showBackground = true,
141+
group = "Devices - Large Round",
142+
showSystemUi = true,
143+
)
144+
@Composable
145+
fun WearApp() {
146+
val context = LocalContext.current
147+
var runningService by rememberSaveable { mutableStateOf<Class<*>?>(null) }
148+
val listState = rememberScalingLazyListState()
149+
150+
MaterialTheme(
151+
colorScheme = dynamicColorScheme(LocalContext.current) ?: MaterialTheme.colorScheme
152+
) {
153+
AmbientAware { ambientState ->
154+
ScalingLazyColumn(
155+
modifier = Modifier.fillMaxSize(),
156+
state = listState,
157+
horizontalAlignment = Alignment.CenterHorizontally,
158+
autoCentering = AutoCenteringParams(itemIndex = 0)
159+
) {
160+
item {
161+
Text(text = "Elapsed Time", style = MaterialTheme.typography.titleLarge)
162+
}
163+
item {
164+
Spacer(modifier = Modifier.height(8.dp))
165+
}
166+
item {
167+
ElapsedTime(ambientState = ambientState)
168+
}
169+
item {
170+
Spacer(modifier = Modifier.height(8.dp))
171+
}
172+
173+
val services = listOf(
174+
AlwaysOnService1::class.java,
175+
AlwaysOnService2::class.java,
176+
AlwaysOnService3::class.java
177+
)
178+
179+
items(services.size) { index ->
180+
val serviceClass = services[index]
181+
val isRunning = runningService == serviceClass
182+
SwitchButton(
183+
checked = isRunning,
184+
onCheckedChange = { newState ->
185+
if (newState) {
186+
if (runningService != null) {
187+
Log.d(TAG, "Stopping ${runningService?.simpleName}")
188+
context.stopService(Intent(context, runningService))
189+
}
190+
Log.d(TAG, "Starting ${serviceClass.simpleName}")
191+
val intent = Intent(context, serviceClass)
192+
context.startForegroundService(intent)
193+
runningService = serviceClass
194+
} else {
195+
Log.d(TAG, "Stopping ${serviceClass.simpleName}")
196+
context.stopService(Intent(context, serviceClass))
197+
runningService = null
198+
}
199+
},
200+
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 4.dp),
201+
) {
202+
Text(
203+
text = "Ongoing Activity ${index + 1}",
204+
style = MaterialTheme.typography.bodySmall,
205+
)
206+
}
207+
}
208+
}
209+
}
210+
}
211+
}

0 commit comments

Comments
 (0)