Browse Source

上传ai测试代码

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
f09bc3d6a9
  1. 12
      .metadata
  2. 7
      android/app/src/debug/AndroidManifest.xml
  3. 5
      android/app/src/main/kotlin/com/yunqiinnovation/deep_voice/MainActivity.kt
  4. 7
      android/app/src/profile/AndroidManifest.xml
  5. 53
      lib/data/services/location_manager.dart
  6. 1
      local_plugins/agent_service/android/build.gradle.kts
  7. 15
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  8. 13
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/utils.kt
  9. 2
      local_plugins/amap_service/android/build.gradle
  10. 3
      local_plugins/amap_service/android/src/main/kotlin/com/yunqiinnovation/amap_service/NavigationServiceHelper.kt
  11. 11
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt
  12. 7
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPSubClient.kt
  13. 20
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt
  14. 33
      local_plugins/location_service/.gitignore
  15. 33
      local_plugins/location_service/.metadata
  16. 3
      local_plugins/location_service/CHANGELOG.md
  17. 1
      local_plugins/location_service/LICENSE
  18. 15
      local_plugins/location_service/README.md
  19. 4
      local_plugins/location_service/analysis_options.yaml
  20. 9
      local_plugins/location_service/android/.gitignore
  21. 70
      local_plugins/location_service/android/build.gradle
  22. 1
      local_plugins/location_service/android/settings.gradle
  23. 7
      local_plugins/location_service/android/src/main/AndroidManifest.xml
  24. 87
      local_plugins/location_service/android/src/main/kotlin/com/yunqiinnovation/location_service/LocationService.kt
  25. 32
      local_plugins/location_service/android/src/main/kotlin/com/yunqiinnovation/location_service/LocationServicePlugin.kt
  26. 38
      local_plugins/location_service/ios/.gitignore
  27. 29
      local_plugins/location_service/ios/location_service.podspec
  28. 32
      local_plugins/location_service/ios/location_service/Package.swift
  29. 19
      local_plugins/location_service/ios/location_service/Sources/location_service/LocationServicePlugin.swift
  30. 14
      local_plugins/location_service/ios/location_service/Sources/location_service/PrivacyInfo.xcprivacy
  31. 49
      local_plugins/location_service/lib/location_service.dart
  32. 72
      local_plugins/location_service/pubspec.yaml
  33. 2
      pubspec.yaml

12
.metadata

@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.
version:
revision: "ea121f8859e4b13e47a8f845e4586164519588bc"
revision: "5c1433509f997e9059d230942bdf83f1b88a179e"
channel: "stable"
project_type: app
@ -13,11 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
- platform: ios
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
create_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
base_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
- platform: android
create_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
base_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
# User provided section

7
android/app/src/debug/AndroidManifest.xml

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

5
android/app/src/main/kotlin/com/yunqiinnovation/deep_voice/MainActivity.kt

@ -0,0 +1,5 @@
package com.yunqiinnovation.deep_voice
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity()

7
android/app/src/profile/AndroidManifest.xml

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

53
lib/data/services/location_manager.dart

@ -0,0 +1,53 @@
import 'package:deep_voice/core/utils/logger.dart';
import 'package:get/get.dart';
import 'package:location_service/location_service.dart';
import 'package:music_service/music_service.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../core/utils/permission_util.dart';
import 'package:flutter/material.dart';
//音乐播放管理
class LocationManager extends GetxService {
static LocationManager get to => Get.find<LocationManager>();
// 音乐服务实例
final LocationService _musicService = LocationService();
/// 初始化
@override
void onInit() {
super.onInit();
requestNotificationPermission();
Logger.info('初始化权限请求');
}
Future<void> requestNotificationPermission() async {
final granted = await PermissionUtil.instance.requestPermission(
// context: context,
permissionType: Permission.notification,
permissionName: '通知',
explanationText: '需要通知权限来显示音乐播放状态。',
permanentDenialText: '您已永久拒绝通知权限,请前往设置开启权限。',
settingsButtonText: '去设置',
cancelButtonText: '取消',
);
if (!granted) {
Logger.warning('通知权限未被授予');
return;
}
Logger.info('通知权限已授予');
}
/// 释放资源
@override
void onClose() {
super.onClose();
}
//定位
Future<Map<String, double>> location() async {
return await _musicService.location();
}
}

1
local_plugins/agent_service/android/build.gradle.kts

@ -49,4 +49,5 @@ dependencies {
add("compileOnly", project(":amap_service"))
add("compileOnly", project(":speech"))
add("compileOnly", project(":chat_api"))
add("compileOnly", project(":location_service"))
}

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

@ -9,6 +9,7 @@ import com.yunqiinnovation.chat_api.StreamCallback
import com.yunqiinnovation.chat_storage.ChatStorageHelper
import com.yunqiinnovation.music_service.MusicServiceStarter
import com.yunqiinnovation.amap_service.NavigationServiceHelper
import com.yunqiinnovation.location_service.LocationService
import android.util.Log
import kotlinx.coroutines.*
import java.util.Collections
@ -125,8 +126,8 @@ object AgentService : CoroutineScope {
this.chatApiService = ChatApiService(context)
this.chatStorageHelper = ChatStorageHelper(context)
this.audioPlayer = AudioPlayer(context)
//初始化定位服务
LocationService.initialize(appContext)
// 设置系统提示词
val customSystemPrompt = config["systemPrompt"] as? String
if (!customSystemPrompt.isNullOrBlank()) {
@ -621,8 +622,14 @@ object AgentService : CoroutineScope {
// 先添加系统提示词
if (systemPrompt.isNotEmpty()) {
messagesWithSystemPrompt.put(createSystemMessage(systemPrompt))
// Log.d(TAG, "系统提示词: ${systemPrompt}")
val location = LocationService.getCachedLocation()?: mapOf(
"user_location" to "定位未开启",
"user_lat" to "定位未开启",
"user_lng" to "定位未开启",
)
val _systemPrompt = Utils.fillTemplate(systemPrompt,location)
messagesWithSystemPrompt.put(createSystemMessage(_systemPrompt))
Log.d(TAG, "liwei--------- 系统提示词: ${_systemPrompt}")
}
// 再添加历史消息

13
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/utils.kt

@ -141,4 +141,15 @@ object Utils {
false
}
}
}
/**
* 替换字符串 变量
* */
fun fillTemplate(tpl: String, data: Map<String, String>): String {
var result = tpl
data.forEach { (k, v) ->
result = result.replace("{$k}", v)
}
return result
}
}

2
local_plugins/amap_service/android/build.gradle

@ -48,7 +48,7 @@ android {
}
dependencies {
implementation 'com.amap.api:navi-3dmap:latest.integration'
implementation('com.amap.api:navi-3dmap:latest.integration')
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.mockito:mockito-core:5.0.0")
}

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

@ -105,4 +105,7 @@ object NavigationServiceHelper {
}
}
}

11
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt

@ -308,7 +308,8 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
Log.e("ChatApiService", "消息列表为空")
throw IllegalArgumentException("消息列表不能为空")
}
// Log.e("ChatApiService", "AI解析工具列表: ${tools}")
val chatsFlow = try {
val chatCompletionRequest = ChatCompletionRequest(
model = ModelId(currentModel),
@ -352,13 +353,7 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
// 收集工具调用信息
delta.toolCalls?.forEach { toolCall ->
val id = toolCall.id ?: run {
Log.e("ChatApiService", "toolCall.id 为空,跳过本次处理")
return@forEach
}
Log.e("ChatApiService", "AI发起工具调用: ${toolCall.id} ${toolCall.index} ${toolCall.function?.name} ${toolCall.function?.arguments}")
val index = toolCall.index
// 创建或获取现有的工具调用信息
val toolCallInfo = toolCalls.getOrPut(index) { ToolCallInfo() }
// 安全处理工具调用ID
@ -386,6 +381,7 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
} catch (e: Exception) {
Log.e("ChatApiService", "处理工具调用参数异常: ${e.message}")
}
Log.e("ChatApiService", "AI发起工具调用:${toolCallInfo.name} ${toolCallInfo.arguments}")
}
} catch (e: Exception) {
Log.e("ChatApiService", "处理工具调用函数信息异常: ${e.message}")
@ -692,6 +688,7 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
description = description,
parameters = parameters
)
Log.e("ChatApiService", "AI携带工具:${name}:${parameters}")
tools.add(tool)
} catch (e: Exception) {

7
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPSubClient.kt

@ -101,7 +101,7 @@ class MCPSubClient(
retryCount = 0
currentReconnectDelay = initialReconnectDelay
// 启动心跳检测
// startHeartbeat()
startHeartbeat()
true
} catch (e: Exception) {
@ -129,7 +129,7 @@ class MCPSubClient(
"properties" to emptyMap<String, Any>(),
"required" to emptyList<String>()
)
Log.w(TAG, "解析工具数据: ${tool.name} ${parametersMap}")
val toolMap = mapOf(
"type" to "function",
"function" to mapOf(
@ -229,7 +229,7 @@ class MCPSubClient(
val required = mutableListOf<String>()
// 处理properties
inputSchema.properties?.let { propsJsonObject ->
inputSchema.properties.let { propsJsonObject ->
for ((key, value) in propsJsonObject) {
when (value) {
is JsonPrimitive -> {
@ -260,7 +260,6 @@ class MCPSubClient(
"properties" to properties,
"required" to required
)
return result
}

20
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt

@ -127,16 +127,16 @@ class SystemFunctionHandler(private val context: Context? = null) {
)
// 注册获取当前位置函数
client.registerLocalFunction(
name = "get_current_location",
description = "获取当前地理位置",
parameters = mapOf(
"type" to "object",
"properties" to emptyMap<String, Any>(),
"required" to emptyList<String>()
),
handler = GetCurrentLocationHandler(context)
)
// client.registerLocalFunction(
// name = "get_current_location",
// description = "获取当前地理位置",
// parameters = mapOf(
// "type" to "object",
// "properties" to emptyMap<String, Any>(),
// "required" to emptyList<String>()
// ),
// handler = GetCurrentLocationHandler(context)
// )
// 注册媒体播放功能
client.registerLocalFunction(

33
local_plugins/location_service/.gitignore

@ -0,0 +1,33 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
build/

33
local_plugins/location_service/.metadata

@ -0,0 +1,33 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "5c1433509f997e9059d230942bdf83f1b88a179e"
channel: "stable"
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
base_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
- platform: android
create_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
base_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
- platform: ios
create_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
base_revision: 5c1433509f997e9059d230942bdf83f1b88a179e
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

3
local_plugins/location_service/CHANGELOG.md

@ -0,0 +1,3 @@
## 0.0.1
* TODO: Describe initial release.

1
local_plugins/location_service/LICENSE

@ -0,0 +1 @@
TODO: Add your license here.

15
local_plugins/location_service/README.md

@ -0,0 +1,15 @@
# location_service
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/to/develop-plugins),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

4
local_plugins/location_service/analysis_options.yaml

@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

9
local_plugins/location_service/android/.gitignore

@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.cxx

70
local_plugins/location_service/android/build.gradle

@ -0,0 +1,70 @@
group = "com.yunqiinnovation.location_service"
version = "1.0-SNAPSHOT"
buildscript {
ext.kotlin_version = "2.1.0"
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.7.3")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
android {
namespace = "com.yunqiinnovation.location_service"
compileSdk = 35
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
}
sourceSets {
main.java.srcDirs += "src/main/kotlin"
test.java.srcDirs += "src/test/kotlin"
}
defaultConfig {
minSdk = 21
}
// ✅ dependencies 应该写在这里(android {} 外面)
dependencies {
implementation('com.amap.api:navi-3dmap:latest.integration')
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.mockito:mockito-core:5.0.0")
}
testOptions {
unitTests.all {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}

1
local_plugins/location_service/android/settings.gradle

@ -0,0 +1 @@
rootProject.name = 'location_service'

7
local_plugins/location_service/android/src/main/AndroidManifest.xml

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yunqiinnovation.location_service">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

87
local_plugins/location_service/android/src/main/kotlin/com/yunqiinnovation/location_service/LocationService.kt

@ -0,0 +1,87 @@
package com.yunqiinnovation.location_service
import android.content.Context
import android.location.Location
import android.util.Log
import com.amap.api.location.*
import io.flutter.plugin.common.MethodChannel
object LocationService {
private const val TAG = "LocationService"
private var locationClient: AMapLocationClient? = null
private var currentLocation: AMapLocation? = null
private var initialized = false
fun initialize(context: Context) {
if (initialized) return
Log.e(TAG, "liwei--------- 初始化高德定位服务 1")
try {
AMapLocationClient.updatePrivacyShow(context, true, true)
AMapLocationClient.updatePrivacyAgree(context, true)
Log.e(TAG, "liwei--------- 初始化高德定位服务 2")
locationClient = AMapLocationClient(context.applicationContext)
val option = AMapLocationClientOption().apply {
locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
isOnceLocation = false
interval = 5000L
}
Log.e(TAG, "liwei--------- 初始化高德定位服务 3")
locationClient?.setLocationOption(option)
Log.e(TAG, "liwei--------- 初始化高德定位服务 4")
locationClient?.setLocationListener { location ->
if (location != null && location.errorCode == 0) {
currentLocation = location
Log.d(TAG, "liwei---------定位更新: ${location.latitude}, ${location.longitude}")
} else {
Log.w(TAG, "liwei---------定位失败: ${location?.errorCode} - ${location?.errorInfo}")
}
}
Log.e(TAG, "liwei--------- 初始化高德定位服务 5")
locationClient?.startLocation()
Log.e(TAG, "liwei--------- 初始化高德定位服务 6")
initialized = true
} catch (e: Exception) {
Log.e(TAG, "高德定位初始化失败: ${e.message}", e)
}
}
fun getCachedLocation(): Map<String, String>? {
// // 定位成功,获取经纬度
// val latitude = location.latitude
// val longitude = location.longitude
//
// // 获取结构化地址
// val province = location.province // 省
// val city = location.city // 市
// val district = location.district // 区县
// val street = location.street // 街道
// val streetNum = location.streetNum // 门牌号
// val adCode = location.adCode // 行政区划代码
// val address = location.address // 详细地址拼接字符串
return currentLocation?.let {
mapOf(
"user_location" to it.address,
"user_lat" to it.latitude.toString(),
"user_lng" to it.longitude.toString(),
)
}
}
fun getCurrentLocation(result: MethodChannel.Result) {
val cached = getCachedLocation()
if (cached != null) {
result.success(cached)
} else {
result.error("NO_LOCATION", "当前位置还未获取", null)
}
}
fun stop() {
locationClient?.stopLocation()
locationClient?.onDestroy()
locationClient = null
currentLocation = null
initialized = false
}
}

32
local_plugins/location_service/android/src/main/kotlin/com/yunqiinnovation/location_service/LocationServicePlugin.kt

@ -0,0 +1,32 @@
package com.yunqiinnovation.location_service
import android.content.Context
import android.util.Log
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
/** LocationServicePlugin */
class LocationServicePlugin: FlutterPlugin, MethodCallHandler {
private val TAG = "LocationServicePlugin"
private lateinit var context: Context
private lateinit var channel : MethodChannel
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.yunqiinnovation.location_service")
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
Log.d(TAG, "Method call: ${call.method}")
when (call.method) {
"location" -> LocationService.getCurrentLocation(result)
else -> result.notImplemented()
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {}
}

38
local_plugins/location_service/ios/.gitignore

@ -0,0 +1,38 @@
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh

29
local_plugins/location_service/ios/location_service.podspec

@ -0,0 +1,29 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint location_service.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'location_service'
s.version = '0.0.1'
s.summary = 'A new Flutter project.'
s.description = <<-DESC
A new Flutter project.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'location_service/Sources/location_service/**/*'
s.dependency 'Flutter'
s.platform = :ios, '12.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
# If your plugin requires a privacy manifest, for example if it uses any
# required reason APIs, update the PrivacyInfo.xcprivacy file to describe your
# plugin's privacy impact, and then uncomment this line. For more information,
# see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
# s.resource_bundles = {'location_service_privacy' => ['location_service/Sources/location_service/PrivacyInfo.xcprivacy']}
end

32
local_plugins/location_service/ios/location_service/Package.swift

@ -0,0 +1,32 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "location_service",
platforms: [
.iOS("12.0")
],
products: [
.library(name: "location-service", targets: ["location_service"])
],
dependencies: [],
targets: [
.target(
name: "location_service",
dependencies: [],
resources: [
// If your plugin requires a privacy manifest, for example if it uses any required
// reason APIs, update the PrivacyInfo.xcprivacy file to describe your plugin's
// privacy impact, and then uncomment these lines. For more information, see
// https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
// .process("PrivacyInfo.xcprivacy"),
// If you have other resources that need to be bundled with your plugin, refer to
// the following instructions to add them:
// https://developer.apple.com/documentation/xcode/bundling-resources-with-a-swift-package
]
)
]
)

19
local_plugins/location_service/ios/location_service/Sources/location_service/LocationServicePlugin.swift

@ -0,0 +1,19 @@
import Flutter
import UIKit
public class LocationServicePlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "location_service", binaryMessenger: registrar.messenger())
let instance = LocationServicePlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getPlatformVersion":
result("iOS " + UIDevice.current.systemVersion)
default:
result(FlutterMethodNotImplemented)
}
}
}

14
local_plugins/location_service/ios/location_service/Sources/location_service/PrivacyInfo.xcprivacy

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>

49
local_plugins/location_service/lib/location_service.dart

@ -0,0 +1,49 @@
import 'package:flutter/services.dart';
class LocationService {
static final LocationService _instance = LocationService._internal();
/// 获取单例
factory LocationService() => _instance;
// 方法通道
final MethodChannel _methodChannel = MethodChannel(
'com.yunqiinnovation.location_service',
);
// 事件通道 - 简化为只使用数据和状态通道
late final EventChannel _dataEventChannel;
late final EventChannel _statusEventChannel;
// 事件流
late final Stream<dynamic> _dataStream;
late final Stream<dynamic> _statusStream;
// 获取事件流
Stream<dynamic> get onDataReceived => _dataStream;
// 状态流直接传递原始数据
Stream<dynamic> get onStatusUpdated => _statusStream;
// 内部构造函数
LocationService._internal() {
_dataEventChannel = const EventChannel(
'com.yunqiinnovation.music_service/data_events',
);
_statusEventChannel = const EventChannel(
'com.yunqiinnovation.music_service/status_events',
);
// 初始化事件流
_dataStream = _dataEventChannel.receiveBroadcastStream();
_statusStream = _statusEventChannel.receiveBroadcastStream();
}
Future<Map<String, double>> location() async {
final result = await _methodChannel.invokeMethod<Map>('location');
return {
'latitude': result?['longitude'] ?? 0.0,
'longitude': result?['longitude'] ?? 0.0,
};
}
}

72
local_plugins/location_service/pubspec.yaml

@ -0,0 +1,72 @@
name: location_service
description: "A new Flutter project."
version: 0.0.1
homepage:
environment:
sdk: ^3.8.1
flutter: '>=3.3.0'
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
# which should be registered in the plugin registry. This is required for
# using method channels.
# The Android 'package' specifies package in which the registered class is.
# This is required for using method channels on Android.
# The 'ffiPlugin' specifies that native code should be built and bundled.
# This is required for using `dart:ffi`.
# All these are used by the tooling to maintain consistency when
# adding or updating assets for this project.
plugin:
platforms:
android:
package: com.yunqiinnovation.location_service
pluginClass: LocationServicePlugin
ios:
pluginClass: LocationServicePlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/to/asset-from-package
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/to/font-from-package

2
pubspec.yaml

@ -91,6 +91,8 @@ dependencies:
path: local_plugins/music_service
amap_service:
path: local_plugins/amap_service
location_service:
path: local_plugins/location_service
realtime:
path: local_plugins/realtime

Loading…
Cancel
Save