* feat: register as Android default digital assistant
* fix: assistant role request fallback + always-attempt click
* remove: assistant role request row from Settings
The system-level assistant registration stays (VoiceInteractionService
+ ROLE_ASSISTANT, set via system Settings -> Default apps), but the
in-app Settings row is dropped: RequestRoleActivity fails to resolve
the caller on a plain startActivity ('Package name cannot be null or
empty'), so the button was a dead end. Removes the row, the
AssistantRole helper, and the now-unused strings.
---------
Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
@@ -29,6 +29,28 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".assistant.AssistantService"
|
||||||
|
android:permission="android.permission.BIND_VOICE_INTERACTION"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.voice.VoiceInteractionService" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data
|
||||||
|
android:name="android.voice_interaction"
|
||||||
|
android:resource="@xml/voice_interaction_service" />
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".assistant.AssistantSessionService"
|
||||||
|
android:permission="android.permission.BIND_VOICE_INTERACTION"
|
||||||
|
android:exported="true" />
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".assistant.AssistantRecognitionService"
|
||||||
|
android:permission="android.permission.BIND_RECOGNITION_SERVICE"
|
||||||
|
android:exported="true" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".notification.ChatNotificationService"
|
android:name=".notification.ChatNotificationService"
|
||||||
android:foregroundServiceType="remoteMessaging"
|
android:foregroundServiceType="remoteMessaging"
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.m57.hermescontrol.assistant
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.speech.RecognitionService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub recognition service. The framework requires a recognition service to
|
||||||
|
* be declared in voice_interaction_service.xml for the assistant component to
|
||||||
|
* be valid (AOSP VoiceInteractionServiceInfo parse error otherwise), but v1
|
||||||
|
* has no speech input — long-press Home just opens the app.
|
||||||
|
*/
|
||||||
|
class AssistantRecognitionService : RecognitionService() {
|
||||||
|
override fun onStartListening(
|
||||||
|
intent: Intent,
|
||||||
|
callback: Callback,
|
||||||
|
) = Unit
|
||||||
|
|
||||||
|
override fun onStopListening(callback: Callback) = Unit
|
||||||
|
|
||||||
|
override fun onCancel(callback: Callback) = Unit
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.m57.hermescontrol.assistant
|
||||||
|
|
||||||
|
import android.service.voice.VoiceInteractionService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Top-level digital-assistant service. The system keeps this running while
|
||||||
|
* Hermes Mobile is the default assistant; the actual trigger handling lives
|
||||||
|
* in [AssistantSessionService] / [AssistantSession].
|
||||||
|
*/
|
||||||
|
class AssistantService : VoiceInteractionService()
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.m57.hermescontrol.assistant
|
||||||
|
|
||||||
|
import android.app.assist.AssistContent
|
||||||
|
import android.app.assist.AssistStructure
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.service.voice.VoiceInteractionSession
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import com.m57.hermescontrol.MainActivity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a single assistant invocation. There is no voice UI in v1 — every
|
||||||
|
* trigger (long-press Home / corner swipe) simply opens the app in the
|
||||||
|
* foreground, then closes the session.
|
||||||
|
*
|
||||||
|
* [onShow] fires for every invocation; [onHandleAssist] additionally receives
|
||||||
|
* the assist data. Both route to the same guarded launch so the app opens
|
||||||
|
* exactly once per session. The deprecated 3-arg [onHandleAssist] is kept so
|
||||||
|
* the launch works on every supported API level (the framework's
|
||||||
|
* [AssistState] default forwards to it below API 29).
|
||||||
|
*/
|
||||||
|
class AssistantSession(context: Context) : VoiceInteractionSession(context) {
|
||||||
|
private var launchHandled = false
|
||||||
|
|
||||||
|
override fun onShow(
|
||||||
|
args: Bundle?,
|
||||||
|
showFlags: Int,
|
||||||
|
) {
|
||||||
|
super.onShow(args, showFlags)
|
||||||
|
launchHermesAndFinish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
|
override fun onHandleAssist(
|
||||||
|
data: Bundle?,
|
||||||
|
structure: AssistStructure?,
|
||||||
|
content: AssistContent?,
|
||||||
|
) {
|
||||||
|
launchHermesAndFinish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
override fun onHandleAssist(state: AssistState) {
|
||||||
|
launchHermesAndFinish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchHermesAndFinish() {
|
||||||
|
if (launchHandled) return
|
||||||
|
launchHandled = true
|
||||||
|
|
||||||
|
val intent =
|
||||||
|
Intent(context, MainActivity::class.java)
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
|
context.startActivity(intent)
|
||||||
|
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.m57.hermescontrol.assistant
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.service.voice.VoiceInteractionSession
|
||||||
|
import android.service.voice.VoiceInteractionSessionService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns an [AssistantSession] each time the user invokes the assistant
|
||||||
|
* (long-press Home / corner swipe).
|
||||||
|
*/
|
||||||
|
class AssistantSessionService : VoiceInteractionSessionService() {
|
||||||
|
override fun onNewSession(args: Bundle?): VoiceInteractionSession = AssistantSession(this)
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Registers Hermes Mobile as a candidate for the Android digital-assistant
|
||||||
|
role (Settings > Apps > Default apps > Digital assistant app).
|
||||||
|
|
||||||
|
Both sessionService and recognitionService are REQUIRED by the framework
|
||||||
|
(VoiceInteractionServiceInfo rejects the service with a parse error if
|
||||||
|
either is missing). Recognition is a stub for now — no speech in v1.
|
||||||
|
-->
|
||||||
|
<voice-interaction-service
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:sessionService="com.m57.hermescontrol.assistant.AssistantSessionService"
|
||||||
|
android:recognitionService="com.m57.hermescontrol.assistant.AssistantRecognitionService"
|
||||||
|
android:supportsAssist="true" />
|
||||||
Reference in New Issue
Block a user