Browse Source

上传导航代码优化

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
f5c62b5613
  1. 8
      lib/data/services/navigation_manager.dart
  2. 16
      lib/modules/agent/controllers/agent_controller.dart
  3. 12
      lib/modules/agent/views/message_bubble.dart
  4. 2
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  5. 3
      local_plugins/amap_service/android/src/main/AndroidManifest.xml
  6. 9
      local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/AmapServicePlugin.kt
  7. 52
      local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationActivity.kt
  8. 48
      local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationService.kt
  9. 29
      local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationServiceHelper.kt
  10. 8
      local_plugins/amap_service/lib/amap_service.dart
  11. 55
      local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/SystemFunctionHandler.kt

8
lib/data/services/navigation_manager.dart

@ -31,7 +31,11 @@ class NavigationManager extends GetxService {
// await _amapervice.navigation(org, dis); // await _amapervice.navigation(org, dis);
} }
//导航 //导航
Future<void> open() async { Future<void> open(
await _amapervice.open(); String start,
String end,
String ntype,
) async {
await _amapervice.open(start, end, ntype);
} }
} }

16
lib/modules/agent/controllers/agent_controller.dart

@ -397,7 +397,7 @@ class AgentController extends GetxController {
if (meta != null && meta is String && meta.isNotEmpty) { if (meta != null && meta is String && meta.isNotEmpty) {
try { try {
metaResult = jsonDecode(meta); metaResult = jsonDecode(meta) as Map<String, dynamic>;
} catch (e) { } catch (e) {
Logger.e(TAG, '解析meta数据失败: $e'); Logger.e(TAG, '解析meta数据失败: $e');
} }
@ -422,6 +422,16 @@ class AgentController extends GetxController {
); );
} }
} }
if (metaResult.containsKey("card_navigation")) {
final start = metaResult["card_navigation"]["start"] as String;
final end = metaResult["card_navigation"]["end"] as String;
Logger.i(TAG, 'liwei-------- 打开导航页面: $start $end ');
Future.delayed(Duration(seconds: 2), () {
Logger.i(TAG, 'liwei-------- 打开导航页面: $start $end ');
// 2秒后执行的代码
openNavigation(start, end, "");
});
}
} }
} }
break; break;
@ -849,7 +859,7 @@ class AgentController extends GetxController {
} }
//去导航 //去导航
void openNavigation() { void openNavigation(String start, String end, String ntype) {
_navigationManager.open(); _navigationManager.open(start, end, ntype);
} }
} }

12
lib/modules/agent/views/message_bubble.dart

@ -284,6 +284,8 @@ class MessageBubble extends GetView<AgentController> {
// 旅游 // 旅游
return _buildTravelContent(context, travellist); return _buildTravelContent(context, travellist);
} else if (meta!.keys.contains('card_navigation')) { } else if (meta!.keys.contains('card_navigation')) {
final start = meta!['card_navigation']['start'] as String;
final end = meta!['card_navigation']['end'] as String;
final destination = meta!['card_navigation']['destination'] as String; final destination = meta!['card_navigation']['destination'] as String;
final rawList = meta!['card_navigation']['items'] as List; final rawList = meta!['card_navigation']['items'] as List;
final list = rawList.map((e) => Map<String, dynamic>.from(e)).toList(); final list = rawList.map((e) => Map<String, dynamic>.from(e)).toList();
@ -293,7 +295,11 @@ class MessageBubble extends GetView<AgentController> {
print("导航实时数据 ${rawNavigation}"); print("导航实时数据 ${rawNavigation}");
// 导航 // 导航
return navigationCard(context, return navigationCard(context,
destination: destination, modes: list, navigation: navigation); start: start,
end: end,
destination: destination,
modes: list,
navigation: navigation);
} }
// if (message.contains('播放列表') || message.contains('音乐')) { // if (message.contains('播放列表') || message.contains('音乐')) {
@ -1205,6 +1211,8 @@ class MessageBubble extends GetView<AgentController> {
Widget navigationCard( Widget navigationCard(
BuildContext context, { BuildContext context, {
required String start,
required String end,
required String destination, required String destination,
required List<Map<String, dynamic>> modes, required List<Map<String, dynamic>> modes,
Map<String, dynamic>? navigation, Map<String, dynamic>? navigation,
@ -1313,7 +1321,7 @@ class MessageBubble extends GetView<AgentController> {
icon: const Icon(Icons.turn_left, icon: const Icon(Icons.turn_left,
color: Colors.white, size: 20), color: Colors.white, size: 20),
onPressed: () { onPressed: () {
controller.openNavigation(); controller.openNavigation(start, end, "");
}, },
), ),
) )

2
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -1186,7 +1186,7 @@ object AgentService : CoroutineScope {
// 如果 playlist 中有有效的歌曲,开始播放 // 如果 playlist 中有有效的歌曲,开始播放
if (!start.isNullOrEmpty() && !end.isNullOrEmpty()) { if (!start.isNullOrEmpty() && !end.isNullOrEmpty()) {
Log.i(TAG, "启动导航服务 ${start} ${end}") Log.i(TAG, "启动导航服务 ${start} ${end}")
NavigationServiceHelper.startNavigation(context, startpos = start, endpos = end) NavigationServiceHelper.startNavigation(context,"start", startpos = start, endpos = end)
} else { } else {
Log.i(TAG, "启动导航服务失败") Log.i(TAG, "启动导航服务失败")
} }

3
local_plugins/amap_service/android/src/main/AndroidManifest.xml

@ -41,6 +41,9 @@
<service android:name="com.amap.api.location.APSService"/> <service android:name="com.amap.api.location.APSService"/>
<activity <activity
android:name=".NavigationActivity" android:name=".NavigationActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity=""
android:theme="@style/Theme.AppCompat.Light.NoActionBar" android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:configChanges="orientation|keyboardHidden|screenSize|navigation"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />

9
local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/AmapServicePlugin.kt

@ -42,7 +42,7 @@ class AmapServicePlugin: FlutterPlugin, MethodCallHandler,EventChannel.StreamHan
val endpos = call.argument<String>("endpos") val endpos = call.argument<String>("endpos")
val ntype = call.argument<String>("ntype") val ntype = call.argument<String>("ntype")
if (startpos != null && endpos != null && ntype != null) { if (startpos != null && endpos != null && ntype != null) {
NavigationServiceHelper.startNavigation(context,startpos,endpos,ntype) NavigationServiceHelper.startNavigation(context,"start",startpos,endpos,ntype)
result.success(null) result.success(null)
} else { } else {
result.error("INVALID_ARGUMENT", "Missing 'song' map", null) result.error("INVALID_ARGUMENT", "Missing 'song' map", null)
@ -50,13 +50,16 @@ class AmapServicePlugin: FlutterPlugin, MethodCallHandler,EventChannel.StreamHan
} }
"open" -> { "open" -> {
try { try {
NavigationServiceHelper.openNavigationUI() val startpos = call.argument<String>("startpos")
val endpos = call.argument<String>("endpos")
val ntype = call.argument<String>("ntype")
NavigationServiceHelper.openNavigationUI(startpos,endpos,ntype)
}catch (e: Exception){ }catch (e: Exception){
result.error("INVALID_ARGUMENT", "Try Exception ", e) result.error("INVALID_ARGUMENT", "Try Exception ", e)
} }
} }
"stop" -> { "stop" -> {
NavigationServiceHelper.stopNavigation() NavigationServiceHelper.startNavigation(context,"stop")
result.success(null) result.success(null)
} }
else -> { else -> {

52
local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationActivity.kt

@ -1,11 +1,14 @@
package com.yunqiinnovation.amap_service package com.yunqiinnovation.amap_service
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.amap.api.navi.AMapNavi import com.amap.api.navi.AMapNavi
import com.amap.api.navi.AMapNaviListener import com.amap.api.navi.AMapNaviListener
import com.amap.api.navi.AMapNaviView import com.amap.api.navi.AMapNaviView
import com.amap.api.navi.AMapNaviViewListener import com.amap.api.navi.AMapNaviViewListener
import com.amap.api.navi.enums.PathPlanningStrategy
import com.amap.api.navi.model.AMapCalcRouteResult import com.amap.api.navi.model.AMapCalcRouteResult
import com.amap.api.navi.model.AMapLaneInfo import com.amap.api.navi.model.AMapLaneInfo
import com.amap.api.navi.model.AMapModelCross import com.amap.api.navi.model.AMapModelCross
@ -18,24 +21,35 @@ import com.amap.api.navi.model.AMapServiceAreaInfo
import com.amap.api.navi.model.AimLessModeCongestionInfo import com.amap.api.navi.model.AimLessModeCongestionInfo
import com.amap.api.navi.model.AimLessModeStat import com.amap.api.navi.model.AimLessModeStat
import com.amap.api.navi.model.NaviInfo import com.amap.api.navi.model.NaviInfo
import com.amap.api.navi.model.NaviLatLng
import com.yunqiinnovation.amap_service.NavigationService.Companion.sharedNavi
class NavigationActivity : AppCompatActivity(), AMapNaviListener, AMapNaviViewListener { class NavigationActivity : AppCompatActivity(), AMapNaviListener, AMapNaviViewListener {
private lateinit var naviView: AMapNaviView private lateinit var naviView: AMapNaviView
private var navi: AMapNavi? = null private var navi: AMapNavi? = null
private lateinit var context: Context
private var startpos:String = "";
private var endpos:String = "";
private var ntype:String = "";
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation) setContentView(R.layout.activity_navigation)
context = this
// 初始化导航视图 // 初始化导航视图
naviView = findViewById(R.id.navi_view) naviView = findViewById(R.id.navi_view)
naviView.onCreate(savedInstanceState) naviView.onCreate(savedInstanceState)
naviView.setAMapNaviViewListener(this) naviView.setAMapNaviViewListener(this)
startpos = intent.getStringExtra("startpos").toString()
endpos = intent.getStringExtra("endpos").toString()
ntype = intent.getStringExtra("ntype").toString()
Log.i("NavigationActivity", "onCreate $startpos $endpos $ntype")
navi = NavigationService.sharedNavi navi = NavigationService.sharedNavi
if (navi == null) { if (navi == null) {
finish() // 服务未启动,退出 navi = AMapNavi.getInstance(context).apply {
return setUseInnerVoice(true)
setBroadcastMode(1)
}
} }
navi?.addAMapNaviListener(this); navi?.addAMapNaviListener(this);
@ -53,9 +67,13 @@ class NavigationActivity : AppCompatActivity(), AMapNaviListener, AMapNaviViewLi
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() navi?.stopNavi()
naviView.onDestroy()
navi?.removeAMapNaviListener(this); navi?.removeAMapNaviListener(this);
AMapNavi.destroy()
NavigationServiceHelper.startNavigation(context,"stop")
naviView.onDestroy()
super.onDestroy()
Log.i("NavigationActivity", "liwei------------------- onDestroy!")
} }
override fun onInitNaviFailure() { override fun onInitNaviFailure() {
@ -63,6 +81,25 @@ class NavigationActivity : AppCompatActivity(), AMapNaviListener, AMapNaviViewLi
} }
override fun onInitNaviSuccess() { override fun onInitNaviSuccess() {
Log.i("NavigationActivity", "onInitNaviSuccess!")
// 起点
val startParts: List<String> = startpos.split(",")
val startLng = startParts[0].toDouble()
val startLat = startParts[1].toDouble()
// 终点
val endParts: List<String> = endpos.split(",")
val endLng = endParts[0].toDouble()
val endLat = endParts[1].toDouble()
val startList: MutableList<NaviLatLng> = ArrayList()
val endList: MutableList<NaviLatLng> = ArrayList()
startList.add(NaviLatLng(startLat, startLng))
endList.add(NaviLatLng(endLat, endLng))
val success = navi?.calculateDriveRoute(startList, endList, null, PathPlanningStrategy.DRIVING_MULTIPLE_ROUTES_DEFAULT);
if (!success!!) {
Log.e("NavigationActivity", "路径规划请求失败")
}
// TODO("Not yet implemented") // TODO("Not yet implemented")
} }
@ -167,6 +204,7 @@ class NavigationActivity : AppCompatActivity(), AMapNaviListener, AMapNaviViewLi
} }
override fun onCalculateRouteSuccess(p0: IntArray?) { override fun onCalculateRouteSuccess(p0: IntArray?) {
navi?.startNavi(1);
// TODO("Not yet implemented") // TODO("Not yet implemented")
} }
@ -212,7 +250,7 @@ class NavigationActivity : AppCompatActivity(), AMapNaviListener, AMapNaviViewLi
} }
override fun onNaviCancel() { override fun onNaviCancel() {
finish() finishAndRemoveTask()
// TODO("Not yet implemented") // TODO("Not yet implemented")
} }

48
local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationService.kt

@ -60,18 +60,27 @@ class NavigationService: Service(),AMapNaviListener {
} }
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
try { val command = intent.getStringExtra("command") ?: return START_NOT_STICKY
startpos = intent.getStringExtra("startpos").toString() when (command) {
endpos = intent.getStringExtra("endpos").toString() "start" ->{
naviType = intent.getStringExtra("naviType"); try {
Log.w(TAG, "开始导航 startpos:$startpos endpos:$endpos naviType:$naviType") startpos = intent.getStringExtra("startpos").toString()
if (startpos.isEmpty() || endpos.isEmpty()) { endpos = intent.getStringExtra("endpos").toString()
Log.e(TAG, "Missing start or end position") naviType = intent.getStringExtra("naviType");
Log.w(TAG, "开始导航 startpos:$startpos endpos:$endpos naviType:$naviType")
if (startpos.isEmpty() || endpos.isEmpty()) {
Log.e(TAG, "Missing start or end position")
return START_NOT_STICKY
}
initializeAMapNavi()
}catch (e: FileNotFoundException){
Log.w("NavigationService", "Custom voice bin not found: ${e.message}")
}
}
"stop" -> {
stopNavigation()
return START_NOT_STICKY return START_NOT_STICKY
} }
initializeAMapNavi()
}catch (e: FileNotFoundException){
Log.w("NavigationService", "Custom voice bin not found: ${e.message}")
} }
return START_STICKY return START_STICKY
} }
@ -148,6 +157,7 @@ class NavigationService: Service(),AMapNaviListener {
if (sharedNavi != null) { if (sharedNavi != null) {
sharedNavi?.stopNavi() sharedNavi?.stopNavi()
sharedNavi?.removeAMapNaviListener(this) sharedNavi?.removeAMapNaviListener(this)
sharedNavi = null
} }
isRunning.set(false) isRunning.set(false)
stopSelf() stopSelf()
@ -271,14 +281,14 @@ class NavigationService: Service(),AMapNaviListener {
String.format("%.1f 千米", remainingDistance / 1000.0) String.format("%.1f 千米", remainingDistance / 1000.0)
} }
val contentText = "$distanceText \n进入:$nextRoad" val contentText = "$distanceText \n进入:$nextRoad"
val directionBitmapBase64 = bitmapToBase64(directionBitmap) // val directionBitmapBase64 = bitmapToBase64(directionBitmap)
val naviInfoMap: Map<String, Any> = mapOf( // val naviInfoMap: Map<String, Any> = mapOf(
"currentRoad" to currentRoad, // "currentRoad" to currentRoad,
"nextRoad" to nextRoad, // "nextRoad" to nextRoad,
"distanceText" to distanceText, // "distanceText" to distanceText,
"directionIcon" to (directionBitmapBase64 ?: "") // "directionIcon" to (directionBitmapBase64 ?: "")
) // )
NavigationServiceHelper.sendEvent("amap_update",naviInfoMap) // NavigationServiceHelper.sendEvent("amap_update",naviInfoMap)
updateNotification(contentText, directionBitmap) updateNotification(contentText, directionBitmap)
Log.e(TAG, "onNaviInfoUpdate! $contentText") Log.e(TAG, "onNaviInfoUpdate! $contentText")
// TODO("Not yet implemented") // TODO("Not yet implemented")
@ -340,7 +350,7 @@ class NavigationService: Service(),AMapNaviListener {
override fun onCalculateRouteSuccess(p0: IntArray?) { override fun onCalculateRouteSuccess(p0: IntArray?) {
Log.e(TAG, "onCalculateRouteSuccess! $p0") Log.e(TAG, "onCalculateRouteSuccess! $p0")
sharedNavi?.startNavi(2); sharedNavi?.startNavi(1);
// TODO("Not yet implemented") // TODO("Not yet implemented")
} }

29
local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationServiceHelper.kt

@ -29,24 +29,27 @@ object NavigationServiceHelper {
context = appContext context = appContext
} }
//启动导航 //启动导航
fun startNavigation(context: Context, startpos: String? = null, endpos: String? = null, ntype: String? = null) { fun startNavigation(context: Context,command:String, startpos: String? = null, endpos: String? = null, ntype: String? = null) {
Log.i(TAG, "liwei------------------- startNavigation: $startpos $endpos $ntype") Log.i(TAG, "liwei------------------- startNavigation: $command $startpos $endpos $ntype")
val intent = Intent(context, NavigationService::class.java).apply { val intent = Intent(context, NavigationService::class.java).apply {
putExtra("command", command)
startpos?.let { putExtra("startpos", it) }
endpos?.let { putExtra("endpos", it) }
ntype?.let { putExtra("ntype", it) }
}
ContextCompat.startForegroundService(context, intent)
// context.startForegroundService(intent)
}
//打开导航页面
fun openNavigationUI(startpos: String? = null, endpos: String? = null, ntype: String? = null) {
Log.i(TAG, "liwei------------------- openNavigationUI: $startpos $endpos $ntype")
val intent = Intent(context, NavigationActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra("startpos", startpos) putExtra("startpos", startpos)
putExtra("endpos", endpos) putExtra("endpos", endpos)
putExtra("ntype", ntype) putExtra("ntype", ntype)
} }
context.startForegroundService(intent)
}
//停止导航
fun stopNavigation() {
val intent = Intent(context, NavigationService::class.java)
context.stopService(intent)
}
//打开导航页面
fun openNavigationUI() {
val intent = Intent(context, NavigationActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent) context.startActivity(intent)
} }

8
local_plugins/amap_service/lib/amap_service.dart

@ -98,8 +98,12 @@ class AmapService {
await _methodChannel.invokeMethod('start'); await _methodChannel.invokeMethod('start');
} }
Future<void> open() async { Future<void> open(String start, String end, String ntype) async {
await _methodChannel.invokeMethod('open'); await _methodChannel.invokeMethod('open', {
'startpos': start,
"endpos": end,
"ntype": ntype,
});
} }
Future<void> stop() async { Future<void> stop() async {

55
local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/SystemFunctionHandler.kt

@ -29,6 +29,7 @@ import android.content.ContentUris
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import android.app.ActivityManager import android.app.ActivityManager
import android.app.Application import android.app.Application
import android.content.ComponentName
import android.os.Process import android.os.Process
/** /**
* 系统功能处理器 - 负责调用系统API执行各种功能以及注册系统功能 * 系统功能处理器 - 负责调用系统API执行各种功能以及注册系统功能
@ -77,7 +78,9 @@ class SystemFunctionHandler(private val context: Context) {
// 注册打开录音机功能 // 注册打开录音机功能
registerOpenRecorderFunction(client) registerOpenRecorderFunction(client)
// 注册关闭导航服务功能
registerStopNavigationFunction(client)
Log.d(TAG, "所有系统功能注册完成") Log.d(TAG, "所有系统功能注册完成")
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "注册系统功能失败: ${e.message}", e) Log.e(TAG, "注册系统功能失败: ${e.message}", e)
@ -443,7 +446,29 @@ class SystemFunctionHandler(private val context: Context) {
) )
Log.d(TAG, "已注册打开录音机功能") Log.d(TAG, "已注册打开录音机功能")
} }
/**
* 注册获取当前时间函数
*/
private fun registerStopNavigationFunction(client: MCPClient) {
client.registerLocalFunction(
"stop_navigation",
"结束当前导航服务",
JSONObject("""
{
"type": "object",
"properties": {},
"required": []
}
"""),
object : FunctionHandler {
override suspend fun handle(arguments: Map<String, Any>): String {
val result = stopNavigation()
return "{\"result\": \"${result.message}\"}"
}
}
)
Log.d(TAG, "已注册获取当前时间功能")
}
/** /**
* 控制媒体播放 * 控制媒体播放
* @param action 操作类型:"play", "pause", "previous", "next" * @param action 操作类型:"play", "pause", "previous", "next"
@ -1270,7 +1295,31 @@ class SystemFunctionHandler(private val context: Context) {
false false
} }
} }
/**
* 停止当前导航
* @return 操作结果
*/
fun stopNavigation():Result{
Log.d(TAG, "结束当前导航服务")
try {
// val intent = Intent()
// intent.component = ComponentName("com.example.plugin", "com.example.plugin.MyBackgroundService")
// stopService(intent)
return Result(
success = true,
message = "当前导航服务已结束"
)
} catch (e: Exception) {
Log.e(TAG, "结束当前导航服务失败: ${e.message}", e)
return Result(
success = false,
message = "结束当前导航服务失败: ${e.message}"
)
}
}
/** /**
* 操作结果数据类 * 操作结果数据类
*/ */

Loading…
Cancel
Save