diff --git a/android/android/app/src/main/AndroidManifest.xml b/android/android/app/src/main/AndroidManifest.xml index c104164..b8d0d85 100644 --- a/android/android/app/src/main/AndroidManifest.xml +++ b/android/android/app/src/main/AndroidManifest.xml @@ -17,6 +17,11 @@ + + = ArrayList(256) // Liste von 32-dim Frames private var melProcessedIdx: Int = 0 @@ -198,6 +207,21 @@ class OpenWakeWordModule(reactContext: ReactApplicationContext) : ReactContextBa running.set(true) record.startRecording() + // PARTIAL_WAKE_LOCK greifen damit die CPU nicht in Doze geht und + // die JS-Bridge die emit("WakeWordDetected")-Events live verarbeitet. + // 8h Cap als Sicherheit gegen forgotten-release. + try { + val pm = reactApplicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + "AriaCockpit:WakeWordRecord").apply { + setReferenceCounted(false) + acquire(8 * 60 * 60 * 1000L) + } + Log.i(TAG, "WakeLock acquired") + } catch (e: Exception) { + Log.w(TAG, "WakeLock acquire fehlgeschlagen: ${e.message}") + } + captureThread = Thread({ captureLoop() }, "OpenWakeWordCapture").apply { isDaemon = true start() @@ -232,6 +256,7 @@ class OpenWakeWordModule(reactContext: ReactApplicationContext) : ReactContextBa try { audioRecord?.release() } catch (_: Exception) {} audioRecord = null releaseAudioEffects() + releaseWakeLock() Log.i(TAG, "Lauschen gestoppt") promise.resolve(true) } @@ -245,10 +270,21 @@ class OpenWakeWordModule(reactContext: ReactApplicationContext) : ReactContextBa try { audioRecord?.release() } catch (_: Exception) {} audioRecord = null releaseAudioEffects() + releaseWakeLock() disposeSessions() promise.resolve(true) } + private fun releaseWakeLock() { + try { + wakeLock?.takeIf { it.isHeld }?.release() + if (wakeLock != null) Log.i(TAG, "WakeLock released") + } catch (e: Exception) { + Log.w(TAG, "WakeLock release fehlgeschlagen: ${e.message}") + } + wakeLock = null + } + @ReactMethod fun isAvailable(promise: Promise) { // Wake-Word ist immer verfuegbar (kein API-Key, alles on-device)