Android: fix digital assistant invocation with proxy activity and missing intent filters
This commit is contained in:
parent
b5c0a66fb7
commit
a3b467167f
@ -15,6 +15,7 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.SEND_SMS" />
|
<uses-permission android:name="android.permission.SEND_SMS" />
|
||||||
|
<uses-permission android:name="android.permission.BIND_VOICE_INTERACTION" />
|
||||||
<uses-feature
|
<uses-feature
|
||||||
android:name="android.hardware.camera"
|
android:name="android.hardware.camera"
|
||||||
android:required="false" />
|
android:required="false" />
|
||||||
@ -37,13 +38,56 @@
|
|||||||
android:name=".NodeForegroundService"
|
android:name=".NodeForegroundService"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:foregroundServiceType="dataSync|microphone|mediaProjection" />
|
android:foregroundServiceType="dataSync|microphone|mediaProjection" />
|
||||||
|
<service
|
||||||
|
android:name=".assistant.ClawdbotVoiceInteractionService"
|
||||||
|
android:exported="true"
|
||||||
|
android:permission="android.permission.BIND_VOICE_INTERACTION">
|
||||||
|
<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.ClawdbotVoiceInteractionSessionService"
|
||||||
|
android:exported="true"
|
||||||
|
android:permission="android.permission.BIND_VOICE_INTERACTION" />
|
||||||
|
<service
|
||||||
|
android:name=".assistant.ClawdbotRecognitionService"
|
||||||
|
android:exported="true"
|
||||||
|
android:permission="android.permission.BIND_RECOGNITION_SERVICE">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.speech.RecognitionService" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
<activity
|
||||||
|
android:name=".assistant.AssistProxyActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:taskAffinity="">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.ASSIST" />
|
||||||
|
<action android:name="android.intent.action.VOICE_ASSIST" />
|
||||||
|
<action android:name="android.intent.action.VOICE_COMMAND" />
|
||||||
|
<action android:name="android.intent.action.SEARCH_LONG_PRESS" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true">
|
android:exported="true"
|
||||||
|
android:launchMode="singleTop">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.clawdbot.android.ACTION_ASSISTANT" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.clawdbot.android.assistant
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import com.clawdbot.android.MainActivity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invisible proxy activity that handles all assistant invocation intents.
|
||||||
|
* Extracts any assist data and forwards to MainActivity, then finishes immediately.
|
||||||
|
*
|
||||||
|
* This is a Theme.NoDisplay activity that serves as the entry point for:
|
||||||
|
* - Long-press home button (ACTION_ASSIST)
|
||||||
|
* - Voice assistant triggers (VOICE_ASSIST, VOICE_COMMAND)
|
||||||
|
* - Search button long-press (SEARCH_LONG_PRESS)
|
||||||
|
*/
|
||||||
|
class AssistProxyActivity : Activity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
Log.d("AssistProxyActivity", "onCreate: action=${intent?.action}")
|
||||||
|
|
||||||
|
// Extract any assist data from the triggering intent
|
||||||
|
val assistBundle = intent?.extras
|
||||||
|
|
||||||
|
// Launch the real assistant UI (MainActivity)
|
||||||
|
val launchIntent = Intent(this, MainActivity::class.java).apply {
|
||||||
|
action = "com.clawdbot.android.ACTION_ASSISTANT"
|
||||||
|
if (assistBundle != null) {
|
||||||
|
putExtras(assistBundle)
|
||||||
|
}
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||||
|
}
|
||||||
|
|
||||||
|
startActivity(launchIntent)
|
||||||
|
|
||||||
|
// Finish immediately (this activity is invisible)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<voice-interaction-service
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:sessionService=".assistant.ClawdbotVoiceInteractionSessionService"
|
||||||
|
android:recognitionService=".assistant.ClawdbotRecognitionService"
|
||||||
|
android:settingsActivity=".MainActivity"
|
||||||
|
android:supportsAssist="true"
|
||||||
|
android:supportsLaunchVoiceAssistFromKeyguard="true"
|
||||||
|
android:supportsLocalInteraction="false" />
|
||||||
Loading…
Reference in New Issue
Block a user