https://developer.android.com/training/ ... al-buttons
Моя проблема в том, что каждый раз, когда я нажимаю физическую кнопку, на моих Pixel Watch по умолчанию отображаются «Недавние приложения».
Я уже добавил некоторые информацию об отладке, но похоже, что события никогда не запускаются:
Код: Выделить всё
[Activity(Theme = "@style/Maui.MainTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
public override bool DispatchKeyEvent(KeyEvent? e)
{
if (e != null)
{
Android.Util.Log.Debug("InTime", $"KeyEvent received: Action={e.Action}, KeyCode={e.KeyCode}");
if (e.KeyCode == Keycode.Stem1 || e.KeyCode == Keycode.Stem2 || e.KeyCode == Keycode.Stem3)
{
if (e.Action == KeyEventActions.Down)
{
e.StartTracking();
return true;
}
if (e.Action == KeyEventActions.Up && !e.IsCanceled && !e.IsLongPress)
{
var viewModel = IPlatformApplication.Current?.Services.GetService();
if (e.KeyCode == Keycode.Stem1)
{
viewModel?.ToggleTimer();
}
else // Stem2 or Stem3
{
viewModel?.ResetTimer();
}
return true;
}
}
}
return base.DispatchKeyEvent(e);
}
public override bool OnKeyLongPress(Keycode keyCode, KeyEvent? e)
{
Android.Util.Log.Debug("InTime", $"Long Press received: KeyCode={keyCode}");
if (keyCode == Keycode.Stem1 || keyCode == Keycode.Stem2 || keyCode == Keycode.Stem3)
{
var viewModel = IPlatformApplication.Current?.Services.GetService();
viewModel?.ResetTimer();
return true;
}
return base.OnKeyLongPress(keyCode, e);
}
}
Android Watch: Google PixelWatch 4 под управлением Wear OS 6.1
Есть идеи, как это исправить или что мне нужно изменить?
Я написал в vibe «родное» приложение Kotlin (я не разработчик Kotlin), но тоже безуспешно:
Код: Выделить всё
package com.example.debugbuttons
import android.os.Bundle
import android.view.KeyEvent
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.wear.compose.material.*
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.foundation.lazy.items
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.input.WearableButtons
import com.example.debugbuttons.presentation.theme.DebugButtonsTheme
class MainActivity : ComponentActivity() {
private val pressedButtons = mutableStateMapOf()
// List of keycodes to check
private val buttonKeyCodes = listOf(
KeyEvent.KEYCODE_STEM_PRIMARY,
KeyEvent.KEYCODE_STEM_1,
KeyEvent.KEYCODE_STEM_2,
KeyEvent.KEYCODE_STEM_3,
KeyEvent.KEYCODE_BACK,
KeyEvent.KEYCODE_MENU
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
DebugButtonsTheme {
val availableButtons = remember { getAvailableButtons() }
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background),
contentAlignment = Alignment.Center
) {
ButtonList(
buttons = availableButtons,
pressedStates = pressedButtons
)
}
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (buttonKeyCodes.contains(keyCode)) {
pressedButtons[keyCode] = true
return true // Consume to show we detected it
}
return super.onKeyDown(keyCode, event)
}
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
if (buttonKeyCodes.contains(keyCode)) {
pressedButtons[keyCode] = false
return true
}
return super.onKeyUp(keyCode, event)
}
private fun getAvailableButtons(): List {
return buttonKeyCodes.mapNotNull { keyCode ->
val info = WearableButtons.getButtonInfo(this, keyCode)
if (info != null) {
ButtonData(
keyCode = keyCode,
name = getFriendlyName(keyCode),
zone = WearableButtons.getButtonLabel(this, keyCode)?.toString() ?: "Unknown Location"
)
} else {
null
}
}
}
private fun getFriendlyName(keyCode: Int): String {
return when (keyCode) {
KeyEvent.KEYCODE_STEM_PRIMARY -> "Stem Primary"
KeyEvent.KEYCODE_STEM_1 -> "Stem 1"
KeyEvent.KEYCODE_STEM_2 -> "Stem 2"
KeyEvent.KEYCODE_STEM_3 -> "Stem 3"
KeyEvent.KEYCODE_BACK -> "Back Button"
KeyEvent.KEYCODE_MENU -> "Menu Button"
else -> "Key $keyCode"
}
}
}
data class ButtonData(val keyCode: Int, val name: String, val zone: String)
@Composable
fun ButtonList(buttons: List, pressedStates: Map) {
val listState = rememberScalingLazyListState()
ScalingLazyColumn(
modifier = Modifier.fillMaxSize(),
state = listState,
horizontalAlignment = Alignment.CenterHorizontally,
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 20.dp)
) {
item {
ListHeader {
Text(
text = "Physical Buttons",
textAlign = TextAlign.Center,
style = MaterialTheme.typography.caption1,
color = MaterialTheme.colors.secondary
)
}
}
if (buttons.isEmpty()) {
item {
Text(
text = "No wearable buttons found via API",
textAlign = TextAlign.Center,
style = MaterialTheme.typography.body2
)
}
}
items(buttons) { button ->
val isPressed = pressedStates[button.keyCode] ?: false
Card(
onClick = { /* No-op */ },
backgroundPainter = CardDefaults.cardBackgroundPainter(
startBackgroundColor = if (isPressed) MaterialTheme.colors.primary else MaterialTheme.colors.surface,
endBackgroundColor = if (isPressed) MaterialTheme.colors.primaryVariant else MaterialTheme.colors.surface
),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 2.dp)
) {
Column {
Text(
text = button.name,
style = MaterialTheme.typography.body1.copy(
fontWeight = FontWeight.Bold,
color = if (isPressed) Color.Black else Color.White
)
)
Text(
text = "Location: ${button.zone}",
style = MaterialTheme.typography.caption2.copy(
color = if (isPressed) Color.DarkGray else Color.LightGray
)
)
}
}
}
}
}