Flutter集成Android Auto后应用无法在Desktop Head Unit(DHU)中显示的问题求助
Flutter集成Android Auto后应用无法在Desktop Head Unit(DHU)中显示的问题求助
我现在遇到了一个Flutter集成Android Auto的棘手问题——应用安装成功且运行无崩溃,但完全出现在DHU的应用列表里,折腾了好几种方法都没解决,想请各位大佬帮忙排查下问题🥺
环境信息
- Flutter:稳定版通道
- Android Auto:Desktop Head Unit (DHU)
- Target SDK:34,minSdk:21
- AndroidX Car App Library:1.7.0
- 测试设备:连接DHU的模拟器/实体设备
预期实现目标
我想做的是一个结合Flutter和Android Auto的语音助手应用,核心需求:
- 通过
CarAppService在车机端显示基础的Android Auto界面 - Flutter端负责:语音处理、文字转语音、手机端UI展示
- 用
MethodChannel实现Android Auto和Flutter之间的双向通信 - 最低预期:应用能出现在DHU里,显示一个标题为「Voice Assistant」的简单列表页面
我已经编写的相关代码
1. AutoService.kt(车机服务类)
package com.example.mytwincar import androidx.car.app.CarAppService import androidx.car.app.Session import androidx.car.app.validation.HostValidator class AutoService : CarAppService() { override fun createHostValidator(): HostValidator { // 为了DHU测试,允许所有主机 return HostValidator.ALLOW_ALL_HOSTS_VALIDATOR } override fun onCreateSession(): Session { return AutoSession() } }
2. AutoSession.kt(会话管理)
package com.example.mytwincar import android.content.Intent import androidx.car.app.Screen import androidx.car.app.Session class AutoSession : Session() { override fun onCreateScreen(intent: Intent): Screen { return MainAutoScreen(carContext) } }
3. MainAutoScreen.kt(车机主界面)
package com.example.mytwincar import androidx.car.app.CarContext import androidx.car.app.Screen import androidx.car.app.model.ListTemplate import androidx.car.app.model.ItemList import androidx.car.app.model.Row class MainAutoScreen(carContext: CarContext) : Screen(carContext) { override fun onGetTemplate(): ListTemplate { return ListTemplate.Builder() .setTitle("Voice Assistant") .setSingleList( ItemList.Builder() .addItem( Row.Builder() .setTitle("Say: Talk to MyApp") .build() ).build() ) .build() } }
4. MainActivity.kt(Flutter主Activity)
package com.example.mytwincar import android.content.Intent import android.os.Bundle import io.flutter.embedding.android.FlutterActivity import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "voice_assistant_channel" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) handleAssistantIntent(intent) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) handleAssistantIntent(intent) } private fun handleAssistantIntent(intent: Intent?) { val query = intent?.getStringExtra("query") ?: return MethodChannel( flutterEngine!!.dartExecutor.binaryMessenger, CHANNEL ).invokeMethod("onVoiceQuery", query) } override fun configureFlutterEngine(flutterEngine: io.flutter.embedding.engine.FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel( flutterEngine.dartExecutor.binaryMessenger, CHANNEL ).setMethodCallHandler { call, result -> if (call.method == "launchAssistant") { launchGoogleAssistant() result.success(null) } } } private fun launchGoogleAssistant() { val intent = Intent(Intent.ACTION_VOICE_COMMAND) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK startActivity(intent) } }
5. Flutter端 voice_bridge.dart
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_tts/flutter_tts.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); VoiceBridge.init(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: VoiceScreen(), ); } } class VoiceScreen extends StatelessWidget { const VoiceScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Voice Assistant')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton.icon( icon: const Icon(Icons.mic), label: const Text("Use Google Assistant"), onPressed: VoiceBridge.launchAssistant, ), const SizedBox(height: 20), ElevatedButton.icon( icon: const Icon(Icons.stop), label: const Text("Stop Audio"), onPressed: VoiceBridge.stopSpeaking, ), ], ), ), ); } } class VoiceBridge { static const MethodChannel _channel = MethodChannel('voice_assistant_channel'); static final FlutterTts _flutterTts = FlutterTts(); static Future<void> init() async { _channel.setMethodCallHandler((call) async { if (call.method == 'onVoiceQuery') { String query = call.arguments as String; await _flutterTts.speak("You said: $query"); } }); } static Future<void> launchAssistant() async { try { await _channel.invokeMethod('launchAssistant'); } on PlatformException catch (e) { print("Failed to launch assistant: ${e.message}"); } } static Future<void> stopSpeaking() async { await _flutterTts.stop(); } }
6. AndroidManifest.xml 车机服务配置
<service android:name="com.example.mytwincar.AutoService" android:exported="true" android:permission="android.permission.BIND_CAR_SERVICE"> <intent-filter> <action android:name="androidx.car.app.CarAppService"/> </intent-filter> <meta-data android:name="androidx.car.app.category" android:value="navigation"/> </service>
7. Android build.gradle 依赖配置
dependencies { implementation("androidx.car.app:app:1.7.0") implementation("androidx.car.app:app-projected:1.7.0") }
当前问题
应用安装成功,运行过程中没有任何崩溃日志,但就是不会出现在DHU的应用列表里,完全找不到入口。
我已经尝试过的排查方法
- 清除Android Auto的缓存和存储
- 卸载重装应用
- 在Manifest中设置了
navigation分类 - 开启Android Auto的开发者模式
- 允许DHU安装未知来源应用
- 多次重启DHU和测试设备
- 反复核对包名、类名的拼写,确认没有错误
实在是找不到问题出在哪了,有没有大佬能帮我看看,到底是代码配置有遗漏,还是DHU的设置哪里没到位?万分感谢🙏




