feat(app-glasses): жесты RayNeo SDK (TempleAction) + отключение звуков трекпада
Перенос из pair-view (проверено на железе): RayNeoARSDK V0.1.3 (aar в libs/, MercurySDK.init в GlassesApp), MainActivity → BaseEventActivity, templeActionViewModel.state → команды (Click=пауза/плей, SlideForward/ Backward=±30с), dispatchTouchEvent→onTouchEvent + toggleSoundEffect(0..3, false) — системные щелчки трекпада отключены. Фиксы по ходу (железо): - applyMediaCommand(msg, onDone) — sendPlaybackPositionNow после seekTo (иначе телефон получал позицию ДО seek) - догонка seekTo через 1с на телефоне (первый seekTo в ogg неточен) - playbackPosition: isPlaying → playWhenReady — ложное playing=false при буферизации после seekTo паузило звук на телефоне (~5с «пропажи»); pauseIfPlaying тоже по playWhenReady Тесты: glasses 59+5, phone 71. Железо: клик пауза/плей ✓, свайпы ±30с ✓, звук при seek не пропадает ✓ (подтверждено пользователем)
This commit is contained in:
@@ -9,12 +9,10 @@ import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.Display
|
||||
import android.view.KeyEvent
|
||||
import android.view.MotionEvent
|
||||
import java.io.File
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -29,9 +27,19 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.rayneo.arsdk.android.ui.activity.BaseEventActivity
|
||||
import kotlinx.coroutines.launch
|
||||
import pw.binom.viewmate.glasses.gestures.actionName
|
||||
import pw.binom.viewmate.glasses.gestures.templeActionToCommand
|
||||
import pw.binom.viewmate.glasses.ui.GlassesMovieScreen
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
class MainActivity : BaseEventActivity() {
|
||||
private var resumeAfterScreenOn = false
|
||||
|
||||
private val screenReceiver = object : BroadcastReceiver() {
|
||||
@@ -62,6 +70,8 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
collectTempleActions()
|
||||
disableTrackpadSounds()
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
setContent {
|
||||
MaterialTheme {
|
||||
@@ -110,6 +120,47 @@ class MainActivity : ComponentActivity() {
|
||||
}, null)
|
||||
}
|
||||
|
||||
/** Жесты трекпада → команды просмотра (Click=пауза/плей, свайпы=±30с). */
|
||||
private fun collectTempleActions() {
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
templeActionViewModel.state.collect { action ->
|
||||
val cmd = templeActionToCommand(action)
|
||||
if (cmd != null) {
|
||||
log("gesture", "жест: ${actionName(action)} → ${cmd.command}")
|
||||
GlassesApp.instance.movieController.applyMediaCommand(cmd) {
|
||||
GlassesApp.instance.hostConnection.sendPlaybackPositionNow()
|
||||
}
|
||||
} else {
|
||||
log("gesture", "жест (резерв): ${actionName(action)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Звуки касания трекпада играет сам SDK (GestureDetectorWithSound, SoundPool:
|
||||
* mercury_system_single_tap/fling/double_click/long_press) — это и есть
|
||||
* системные щелчки очков. Отключаем все четыре типа (индексы 0..3),
|
||||
* чтобы клики/свайпы не щёлкали. Распознавание жестов не затрагивается.
|
||||
*/
|
||||
private fun disableTrackpadSounds() {
|
||||
for (soundType in 0..3) toggleSoundEffect(soundType, false)
|
||||
log("ui", "звуки трекпада SDK отключены (types 0..3)")
|
||||
}
|
||||
|
||||
/**
|
||||
* Жесты SDK детектятся ТОЛЬКО в onTouchEvent (единственный канал в aar:
|
||||
* BaseTouchActivity.onTouchEvent → TouchDispatcher.onMotionEvent). Поэтому
|
||||
* событие НЕ съедаем — прогоняем через onTouchEvent: жест распознаётся,
|
||||
* а в систему/UI событие не уходит (на очках нет таповых элементов).
|
||||
* dispatchKeyEvent глушит клавиши трекпада целиком.
|
||||
*/
|
||||
override fun dispatchTouchEvent(event: MotionEvent): Boolean = onTouchEvent(event)
|
||||
|
||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean = true
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
log("ui", "onPause")
|
||||
|
||||
Reference in New Issue
Block a user