diff --git a/app/libs/sprite_dcg_sdk-2ca23e9-release.aar b/app/libs/sprite_dcg_sdk-2ca23e9-release.aar new file mode 100644 index 0000000..0f410fa Binary files /dev/null and b/app/libs/sprite_dcg_sdk-2ca23e9-release.aar differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f9cf2a1..c0f5076 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> (InstructState.None) + val instructState = _instructState.asStateFlow() + + lateinit var sn: String + private set + + val coroutineExceptionHandler = CoroutineExceptionHandler { _, exception -> + Timber.e(exception, "全局捕获协程异常:${exception.message}") + } + private val scope = + CoroutineScope(SupervisorJob() + Dispatchers.Main + coroutineExceptionHandler) + private var wakeTimeoutJob: Job? = null + + init { + val filter = IntentFilter() + filter.addAction(SysKeyAction.SPRITE_BUTTON_DOWN) + filter.addAction(SysKeyAction.SPRITE_BUTTON_UP) + filter.addAction(SysKeyAction.SPRITE_BUTTON_CLICK) + filter.addAction(SysKeyAction.SPRITE_BUTTON_LONG_PRESS) + filter.addAction(SysKeyAction.SPRITE_BUTTON_VERY_VERY_LONG_PRESS) + filter.addAction(SysKeyAction.TOUCH_BAR_LONG_PRESS) + context.registerReceiver(SysKeyReceiver(), filter) + + scope.launch { + instructState.collect { + Timber.d("语音指令状态 $it") + when (it) { + InstructState.None -> instructService?.unregisterListener(instructListener) + InstructState.WaitingInstructState -> { + instructService?.registerListener(instructListener) + startWakeTimeoutCountdown() + } + } + } + } + } + + val instructListener = object : IInstructListener.Stub() { + override fun onInstructReceived(p0: Int) { + Timber.d("接受到语音指令$p0") + if (p0 != IInstructService.INSTRUCT_QUIT) { + startWakeTimeoutCountdown() + } + when (p0) { + IInstructService.INSTRUCT_WAKEUP -> { + } + + IInstructService.INSTRUCT_VOLUME_UP -> { + systemFuncServiceTodo { service -> + setVolumeSpecified(service.volumeSpecified + 1) + } + } + + IInstructService.INSTRUCT_VOLUME_DOWN -> { + systemFuncServiceTodo { service -> + setVolumeSpecified(service.volumeSpecified - 1) + } + } + + IInstructService.INSTRUCT_LIGHT_UP -> { + systemFuncServiceTodo { service -> + setBrightnessSpecified(service.brightnessSpecified + 1) + } + } + + IInstructService.INSTRUCT_LIGHT_DOWN -> { + systemFuncServiceTodo { service -> + setBrightnessSpecified(service.brightnessSpecified - 1) + } + } + + IInstructService.INSTRUCT_TAKE_PHOTO -> { + + } + + IInstructService.INSTRUCT_START_AUDIO_RECORD -> { + + } + + IInstructService.INSTRUCT_STOP_AUDIO_RECORD -> { + + } + + IInstructService.INSTRUCT_START_VIDEO_RECORD -> { + + } + + IInstructService.INSTRUCT_STOP_VIDEO_RECORD -> { + + } + + IInstructService.INSTRUCT_QUIT -> { + _instructState.update { InstructState.None } + } + } + } + } + + /** + * [INSTRUCT_WAITE_TIME] 一段时间无新指令 退出等待状态 + */ + private fun startWakeTimeoutCountdown() { + wakeTimeoutJob?.cancel() + wakeTimeoutJob = scope.launch { + delay(INSTRUCT_WAITE_TIME) + _instructState.update { InstructState.None } + } + } + + fun playTTS(msg: String) { + ttsServiceTodo { + ttsService?.playTtsMsg(msg) + } + } + + suspend fun getSn() = suspendCancellableCoroutine { continuation -> + systemFuncServiceTodo { service -> + sn = service.sn + continuation.resume(sn) + } + } + + private inline fun ttsServiceTodo(crossinline todo: (ITTSService) -> Unit) { + if (ttsService == null) { + ServiceManager.getTTSService(context) { service -> + if (service == null) { + Timber.d("设备初始化TTS服务失败") + return@getTTSService + } + ttsService = service + todo.invoke(service) + } + } else { + todo.invoke(ttsService!!) + } + } + + private inline fun systemFuncServiceTodo(crossinline todo: (ISystemFuncService) -> Unit) { + if (systemFuncService == null) { + ServiceManager.getSystemFuncService(context) { service -> + if (service == null) { + Timber.d("设备初始化系统功能服务失败") + return@getSystemFuncService + } + systemFuncService = service + todo.invoke(service) + Timber.d(" ${service.sn}") + } + } else { + todo.invoke(systemFuncService!!) + } + } + + private inline fun instructServiceTodo(crossinline todo: (IInstructService) -> Unit) { + if (instructService == null) { + ServiceManager.getInstructService(context) { service -> + if (service == null) { + Timber.d("设备初始化语音指令服务失败") + return@getInstructService + } + instructService = service + todo.invoke(service) + } + } else { + todo.invoke(instructService!!) + } + } + + private fun setVolumeSpecified(volume: Int) { + systemFuncService?.volumeSpecified = volume.coerceIn(0, 15) + } + + private fun setBrightnessSpecified(brightness: Int) { + systemFuncService?.brightnessSpecified = brightness.coerceIn(0, 15) + } + + inner class SysKeyReceiver : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + val action = intent?.action ?: return + when (action) { + SysKeyAction.SPRITE_BUTTON_DOWN -> { + Timber.d("按下拍照键 SPRITE_BUTTON_DOWN") + } + + SysKeyAction.SPRITE_BUTTON_UP -> { + Timber.d("抬起拍照键 SPRITE_BUTTON_UP") + } + + SysKeyAction.SPRITE_BUTTON_CLICK -> { + Timber.d("点击拍照键 SPRITE_BUTTON_CLICK") + } + + SysKeyAction.SPRITE_BUTTON_LONG_PRESS -> { + Timber.d("长按拍照键 SPRITE_BUTTON_LONG_PRESS") + } + + SysKeyAction.SPRITE_BUTTON_VERY_VERY_LONG_PRESS -> { + Timber.d("超级长的长按拍照键 SPRITE_BUTTON_VERY_VERY_LONG_PRESS") + } + + SysKeyAction.TOUCH_BAR_LONG_PRESS -> { + Timber.d("长按触摸板 TOUCH_BAR_LONG_PRESS") + instructServiceTodo { + _instructState.update { InstructState.WaitingInstructState } + } + } + } + } + } + + sealed interface InstructState { + data object None : InstructState + data object WaitingInstructState : InstructState + } + +} + diff --git a/app/src/main/java/com/yuanxuan/rokid/keeplive/KeepLiveService.kt b/app/src/main/java/com/yuanxuan/rokid/keeplive/KeepLiveService.kt index 1e011ce..8dae168 100644 --- a/app/src/main/java/com/yuanxuan/rokid/keeplive/KeepLiveService.kt +++ b/app/src/main/java/com/yuanxuan/rokid/keeplive/KeepLiveService.kt @@ -20,7 +20,7 @@ class KeepLiveService : Service() { companion object { const val NOTIFICATION_CHANNEL_ID = "KeepLiveServiceChannel" const val NOTIFICATION_CHANNEL_NAME = NOTIFICATION_CHANNEL_ID - const val NOTIFICATION_ID = 101 // 使用一个唯一的ID + const val NOTIFICATION_ID = 101 const val WAKE_LOCK_TAG = "KeepLiveService:WakeLock" }