feat: 添加README以及example项目,修复plugin的路径,新建basic_intl的本地依赖
421
README.md
@@ -1,16 +1,417 @@
|
|||||||
# app003
|
# AI Chat Assistant Flutter Plugin
|
||||||
|
|
||||||
A new Flutter project.
|
一个功能丰富的 AI 聊天助手 Flutter 插件,专为车载系统设计,支持语音识别、AI 对话、车控命令执行、语音合成等功能。
|
||||||
|
|
||||||
## Getting Started
|
## 📱 功能特性
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
- 🎤 **语音识别 (ASR)**: 支持实时语音转文字,自动停止检测
|
||||||
|
- 🤖 **AI 对话**: 基于 SSE (Server-Sent Events) 的流式 AI 对话
|
||||||
|
- 🚗 **车控命令**: 支持 20+ 种车辆控制命令(空调、车窗、车门、座椅加热等)
|
||||||
|
- 🔊 **语音合成 (TTS)**: 支持中英文语音播报
|
||||||
|
- 🎨 **精美 UI**: 浮动图标、波纹动画、渐变背景
|
||||||
|
- 📱 **多界面模式**: 支持全屏和部分屏幕聊天界面
|
||||||
|
- 🌐 **国际化**: 支持中英文切换
|
||||||
|
- 📊 **状态管理**: 基于 Provider 的状态管理
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
## 🏗️ 项目架构
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
### 📁 目录结构
|
||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
```
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
lib/
|
||||||
samples, guidance on mobile development, and a full API reference.
|
├── app.dart # 主应用入口
|
||||||
|
├── main.dart # 程序启动入口
|
||||||
|
├── enums/ # 枚举定义
|
||||||
|
│ ├── message_service_state.dart # 消息服务状态
|
||||||
|
│ ├── message_status.dart # 消息状态
|
||||||
|
│ └── vehicle_command_type.dart # 车控命令类型
|
||||||
|
├── models/ # 数据模型
|
||||||
|
│ ├── chat_message.dart # 聊天消息模型
|
||||||
|
│ ├── vehicle_cmd.dart # 车控命令模型
|
||||||
|
│ ├── vehicle_cmd_response.dart # 车控命令响应
|
||||||
|
│ └── vehicle_status_info.dart # 车辆状态信息
|
||||||
|
├── screens/ # 界面页面
|
||||||
|
│ ├── full_screen.dart # 全屏聊天界面
|
||||||
|
│ ├── main_screen.dart # 主界面
|
||||||
|
│ └── part_screen.dart # 部分屏聊天界面
|
||||||
|
├── services/ # 核心服务
|
||||||
|
│ ├── audio_recorder_service.dart # 音频录制服务
|
||||||
|
│ ├── chat_sse_service.dart # SSE 聊天服务
|
||||||
|
│ ├── classification_service.dart # 分类服务
|
||||||
|
│ ├── command_service.dart # 车控命令服务
|
||||||
|
│ ├── control_recognition_service.dart # 控制识别服务
|
||||||
|
│ ├── location_service.dart # 位置服务
|
||||||
|
│ ├── message_service.dart # 消息管理服务
|
||||||
|
│ ├── redis_service.dart # Redis 服务
|
||||||
|
│ ├── tts_service.dart # 语音合成服务
|
||||||
|
│ ├── vehicle_state_service.dart # 车辆状态服务
|
||||||
|
│ └── voice_recognition_service.dart # 语音识别服务
|
||||||
|
├── themes/ # 主题样式
|
||||||
|
│ └── AppTheme.dart # 应用主题定义
|
||||||
|
├── utils/ # 工具类
|
||||||
|
│ ├── common_util.dart # 通用工具
|
||||||
|
│ ├── tts_engine_manager.dart # TTS 引擎管理
|
||||||
|
│ └── tts_util.dart # TTS 工具
|
||||||
|
└── widgets/ # UI 组件
|
||||||
|
├── assistant_avatar.dart # AI 助手头像
|
||||||
|
├── chat_box.dart # 聊天框
|
||||||
|
├── chat_bubble.dart # 聊天气泡
|
||||||
|
├── chat_footer.dart # 聊天底部
|
||||||
|
├── chat_header.dart # 聊天头部
|
||||||
|
├── floating_icon.dart # 浮动图标
|
||||||
|
├── floating_icon_with_wave.dart # 带波纹的浮动图标
|
||||||
|
├── gradient_background.dart # 渐变背景
|
||||||
|
└── large_audio_wave.dart # 大音频波形
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🎯 核心架构设计
|
||||||
|
|
||||||
|
#### 1. 服务层架构 (Services Layer)
|
||||||
|
|
||||||
|
- **MessageService**: 核心消息管理服务,负责统一管理聊天消息、语音识别、AI 对话流程
|
||||||
|
- **ChatSseService**: SSE 流式通信服务,处理与 AI 后端的实时对话
|
||||||
|
- **CommandService**: 车控命令处理服务,提供车辆控制命令的回调机制
|
||||||
|
- **TTSService**: 语音合成服务,支持中英文语音播报
|
||||||
|
- **VoiceRecognitionService**: 语音识别服务,处理音频转文字
|
||||||
|
|
||||||
|
#### 2. UI 层架构 (UI Layer)
|
||||||
|
|
||||||
|
- **浮动图标模式**: 主界面显示可拖拽的 AI 助手浮动图标
|
||||||
|
- **部分屏幕模式**: 点击图标显示简化聊天界面
|
||||||
|
- **全屏模式**: 完整的聊天界面,支持历史记录、操作按钮等
|
||||||
|
|
||||||
|
#### 3. 状态管理 (State Management)
|
||||||
|
|
||||||
|
基于 Provider 模式的响应式状态管理:
|
||||||
|
- 消息状态管理
|
||||||
|
- 语音识别状态
|
||||||
|
- AI 对话状态
|
||||||
|
- 车控命令执行状态
|
||||||
|
|
||||||
|
## 🚗 支持的车控命令
|
||||||
|
|
||||||
|
| 命令类型 | 中文描述 | 英文描述 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| lock | 上锁车门 | lock |
|
||||||
|
| unlock | 解锁车门 | unlock |
|
||||||
|
| openWindow | 打开车窗 | open window |
|
||||||
|
| closeWindow | 关闭车窗 | close window |
|
||||||
|
| appointAC | 预约空调 | appoint AC |
|
||||||
|
| openAC | 打开空调 | open AC |
|
||||||
|
| closeAC | 关闭空调 | close AC |
|
||||||
|
| changeACTemp | 修改空调温度 | change AC temperature |
|
||||||
|
| coolSharply | 极速降温 | cool sharply |
|
||||||
|
| prepareCar | 一键备车 | prepare car |
|
||||||
|
| meltSnow | 一键融雪 | melt snow |
|
||||||
|
| openTrunk | 打开后备箱 | open trunk |
|
||||||
|
| closeTrunk | 关闭后备箱 | close trunk |
|
||||||
|
| honk | 鸣笛 | honk |
|
||||||
|
| locateCar | 定位车辆 | locate car |
|
||||||
|
| openWheelHeat | 开启方向盘加热 | open wheel heat |
|
||||||
|
| closeWheelHeat | 关闭方向盘加热 | close wheel heat |
|
||||||
|
| openMainSeatHeat | 开启主座椅加热 | open main seat heat |
|
||||||
|
| closeMainSeatHeat | 关闭主座椅加热 | close main seat heat |
|
||||||
|
| openMinorSeatHeat | 开启副座椅加热 | open minor seat heat |
|
||||||
|
| closeMinorSeatHeat | 关闭副座椅加热 | close minor seat heat |
|
||||||
|
|
||||||
|
## 🔧 技术栈
|
||||||
|
|
||||||
|
### 核心依赖
|
||||||
|
|
||||||
|
- **Flutter SDK**: ^3.6.2
|
||||||
|
- **Provider**: ^6.1.5 - 状态管理
|
||||||
|
- **HTTP**: ^1.4.0 - 网络请求
|
||||||
|
- **Record**: ^6.0.0 - 音频录制
|
||||||
|
- **AudioPlayers**: ^5.2.1 - 音频播放
|
||||||
|
- **Flutter TTS**: ^4.2.0 - 语音合成
|
||||||
|
- **Permission Handler**: ^12.0.0 - 权限管理
|
||||||
|
- **UUID**: ^3.0.5 - 唯一标识符生成
|
||||||
|
- **Flutter Markdown**: ^0.7.7+1 - Markdown 渲染
|
||||||
|
- **FlutterToast**: ^8.2.12 - 消息提示
|
||||||
|
- **Path Provider**: ^2.1.5 - 文件路径管理
|
||||||
|
|
||||||
|
### 自定义包
|
||||||
|
|
||||||
|
- **basic_intl**: 基础国际化支持包
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 1. 添加依赖
|
||||||
|
|
||||||
|
在您的 `pubspec.yaml` 文件中添加:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dependencies:
|
||||||
|
ai_chat_assistant:
|
||||||
|
path: path/to/ai_chat_assistant
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 权限配置
|
||||||
|
|
||||||
|
#### Android 权限 (android/app/src/main/AndroidManifest.xml)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 基础集成
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:ai_chat_assistant/app.dart';
|
||||||
|
import 'package:ai_chat_assistant/services/message_service.dart';
|
||||||
|
import 'package:ai_chat_assistant/enums/vehicle_command_type.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
// 请求麦克风权限
|
||||||
|
if (!await Permission.microphone.isGranted) {
|
||||||
|
await Permission.microphone.request();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 AI Chat Assistant,注册车控命令回调
|
||||||
|
ChatAssistantApp.initialize(
|
||||||
|
commandCallback: (VehicleCommandType type, Map<String, dynamic>? params) async {
|
||||||
|
// 处理车控命令的业务逻辑
|
||||||
|
print('收到车控命令: $type, 参数: $params');
|
||||||
|
|
||||||
|
// 返回执行结果
|
||||||
|
return (true, {'message': '命令已执行'});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
runApp(
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (_) => MessageService(),
|
||||||
|
child: const MyApp(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: 'My Car App',
|
||||||
|
home: const ChatAssistantApp(), // 直接使用 AI 助手
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 自定义集成
|
||||||
|
|
||||||
|
如果您想在现有应用中集成聊天助手,可以使用浮动图标:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:ai_chat_assistant/widgets/floating_icon.dart';
|
||||||
|
|
||||||
|
class MyHomePage extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
// 您的现有 UI
|
||||||
|
YourExistingWidget(),
|
||||||
|
|
||||||
|
// AI 助手浮动图标
|
||||||
|
const FloatingIcon(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📖 示例项目
|
||||||
|
|
||||||
|
项目包含完整的示例应用,位于 `example/` 目录下:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd example
|
||||||
|
flutter run
|
||||||
|
```
|
||||||
|
|
||||||
|
示例展示了:
|
||||||
|
- 基础集成方法
|
||||||
|
- 车控命令处理
|
||||||
|
- 自定义 UI 主题
|
||||||
|
- 权限管理
|
||||||
|
|
||||||
|
## 🎨 UI 组件
|
||||||
|
|
||||||
|
### 浮动图标 (FloatingIcon)
|
||||||
|
|
||||||
|
可拖拽的 AI 助手图标,支持:
|
||||||
|
- 拖拽定位
|
||||||
|
- 点击展开聊天界面
|
||||||
|
- 动态图标切换
|
||||||
|
- 波纹动画效果
|
||||||
|
|
||||||
|
### 聊天界面组件
|
||||||
|
|
||||||
|
- **ChatBubble**: 聊天气泡组件
|
||||||
|
- **ChatBox**: 聊天输入框
|
||||||
|
- **ChatHeader**: 聊天头部
|
||||||
|
- **ChatFooter**: 聊天底部操作栏
|
||||||
|
- **AssistantAvatar**: AI 助手头像
|
||||||
|
|
||||||
|
### 动画组件
|
||||||
|
|
||||||
|
- **FloatingIconWithWave**: 带波纹效果的浮动图标
|
||||||
|
- **LargeAudioWave**: 大音频波形动画
|
||||||
|
- **GradientBackground**: 渐变背景
|
||||||
|
|
||||||
|
## ⚙️ 配置选项
|
||||||
|
|
||||||
|
### 主题自定义
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 在 AppTheme.dart 中自定义主题
|
||||||
|
class AppTheme {
|
||||||
|
static ThemeData get lightTheme => ThemeData(
|
||||||
|
// 自定义浅色主题
|
||||||
|
);
|
||||||
|
|
||||||
|
static ThemeData get darkTheme => ThemeData(
|
||||||
|
// 自定义深色主题
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 资源文件
|
||||||
|
|
||||||
|
确保在 `pubspec.yaml` 中包含必要的资源:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
flutter:
|
||||||
|
assets:
|
||||||
|
- assets/images/
|
||||||
|
fonts:
|
||||||
|
- family: VWHead_Bold
|
||||||
|
fonts:
|
||||||
|
- asset: assets/fonts/VWHead-Bold.otf
|
||||||
|
- family: VWHead_Regular
|
||||||
|
fonts:
|
||||||
|
- asset: assets/fonts/VWHead-Regular.otf
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔌 Native 平台集成
|
||||||
|
|
||||||
|
### Android 平台
|
||||||
|
|
||||||
|
项目包含 Android 原生代码,支持:
|
||||||
|
- ASR (自动语音识别) 功能
|
||||||
|
- 原生音频处理
|
||||||
|
- 系统权限管理
|
||||||
|
|
||||||
|
### 插件架构
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
plugin:
|
||||||
|
platforms:
|
||||||
|
android:
|
||||||
|
package: com.example.ai_assistant_plugin
|
||||||
|
pluginClass: AiAssistantPlugin
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 API 文档
|
||||||
|
|
||||||
|
### MessageService
|
||||||
|
|
||||||
|
核心消息管理服务:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
class MessageService extends ChangeNotifier {
|
||||||
|
// 发送消息
|
||||||
|
Future<void> sendMessage(String text);
|
||||||
|
|
||||||
|
// 开始语音识别
|
||||||
|
Future<void> startVoiceRecognition();
|
||||||
|
|
||||||
|
// 停止语音识别
|
||||||
|
void stopVoiceRecognition();
|
||||||
|
|
||||||
|
// 获取聊天历史
|
||||||
|
List<ChatMessage> get messages;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### CommandService
|
||||||
|
|
||||||
|
车控命令服务:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
class CommandService {
|
||||||
|
// 注册命令回调
|
||||||
|
static void registerCallback(CommandCallback callback);
|
||||||
|
|
||||||
|
// 执行车控命令
|
||||||
|
static Future<(bool, Map<String, dynamic>?)> executeCommand(
|
||||||
|
VehicleCommandType type,
|
||||||
|
{Map<String, dynamic>? params}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐛 调试和故障排除
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
1. **麦克风权限问题**
|
||||||
|
- 确保在 AndroidManifest.xml 中添加了录音权限
|
||||||
|
- 在应用启动时请求权限
|
||||||
|
|
||||||
|
2. **网络连接问题**
|
||||||
|
- 检查网络权限配置
|
||||||
|
- 确认 SSE 服务端地址配置正确
|
||||||
|
|
||||||
|
3. **TTS 播放问题**
|
||||||
|
- 检查音频播放权限
|
||||||
|
- 确认设备支持 TTS 功能
|
||||||
|
|
||||||
|
### 日志调试
|
||||||
|
|
||||||
|
启用详细日志:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// 在 main.dart 中启用调试日志
|
||||||
|
void main() {
|
||||||
|
debugPrint('AI Chat Assistant 启动中...');
|
||||||
|
// ... 其他初始化代码
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 贡献指南
|
||||||
|
|
||||||
|
欢迎提交 Issue 和 Pull Request!
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
|
||||||
|
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||||||
|
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||||
|
5. 打开 Pull Request
|
||||||
|
|
||||||
|
## 📄 许可证
|
||||||
|
|
||||||
|
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
|
||||||
|
|
||||||
|
## 🔗 相关链接
|
||||||
|
|
||||||
|
- [Flutter 官方文档](https://flutter.dev/docs)
|
||||||
|
- [Provider 状态管理](https://pub.dev/packages/provider)
|
||||||
|
- [Flutter TTS](https://pub.dev/packages/flutter_tts)
|
||||||
|
- [Record 插件](https://pub.dev/packages/record)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**注意**: 本插件专为车载系统设计,某些功能可能需要特定的硬件环境支持。
|
||||||
|
|||||||
2
android/.gitignore
vendored
@@ -12,3 +12,5 @@ GeneratedPluginRegistrant.java
|
|||||||
key.properties
|
key.properties
|
||||||
**/*.keystore
|
**/*.keystore
|
||||||
**/*.jks
|
**/*.jks
|
||||||
|
/build/
|
||||||
|
/src/build/
|
||||||
|
|||||||
94
android/build.gradle
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
group 'com.example.ai_chat_assistant'
|
||||||
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
ext.kotlin_version = '2.1.20'
|
||||||
|
repositories {
|
||||||
|
maven { url rootProject.file("../ai_chat_assistant/android/mavenLocal") }
|
||||||
|
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:8.11.1'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven { url rootProject.file("../ai_chat_assistant/android/mavenLocal") }
|
||||||
|
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace 'com.example.ai_chat_assistant'
|
||||||
|
|
||||||
|
|
||||||
|
compileSdk 33
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "17"
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
test.java.srcDirs += 'src/test/kotlin'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 23
|
||||||
|
ndk {
|
||||||
|
abiFilters "armeabi-v7a", "arm64-v8a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
dataBinding true
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取配置文件
|
||||||
|
def localProperties = new Properties()
|
||||||
|
def localPropertiesFile = rootProject.file('local.properties')
|
||||||
|
if (localPropertiesFile.exists()) {
|
||||||
|
localPropertiesFile.withReader('UTF-8') {
|
||||||
|
localProperties.load(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取flutter sdk 路径
|
||||||
|
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||||
|
if (flutterRoot == null) {
|
||||||
|
throw new GradleException("Flutter SDK not found. Define location with flutter.")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
// flatDir {
|
||||||
|
// dirs("libs")
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// implementation 'com.alibaba.idst:nui-release:1.0.0'
|
||||||
|
// implementation 'com.alibaba:fastjson:1.2.83'
|
||||||
|
// compileOnly files("$flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar")
|
||||||
|
implementation(files("libs/fastjson-1.1.46.android.jar"))
|
||||||
|
implementation(files("libs/nui-release-1.0.0.aar"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.12-all.zip
|
distributionUrl=https\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.13-all.zip
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.alibaba.idst</groupId>
|
||||||
|
<artifactId>nui-release</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>aar</packaging>
|
||||||
|
</project>
|
||||||
1
android/settings.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = 'ai_assistant_plugin'
|
||||||
2
android/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
</manifest>
|
||||||
@@ -1,32 +1,32 @@
|
|||||||
package com.example.ai_chat_assistant;
|
package com.example.ai_assistant_plugin;
|
||||||
|
|
||||||
import android.media.AudioFormat;
|
|
||||||
import android.media.AudioRecord;
|
|
||||||
import android.media.MediaRecorder;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.HandlerThread;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity;
|
|
||||||
import io.flutter.embedding.engine.FlutterEngine;
|
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.alibaba.fastjson.JSONException;
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import com.alibaba.idst.nui.AsrResult;
|
|
||||||
import com.alibaba.idst.nui.Constants;
|
|
||||||
import com.alibaba.idst.nui.INativeNuiCallback;
|
|
||||||
import com.alibaba.idst.nui.INativeStreamInputTtsCallback;
|
|
||||||
import com.alibaba.idst.nui.KwsResult;
|
|
||||||
import com.alibaba.idst.nui.NativeNui;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class MainActivity extends FlutterActivity implements INativeNuiCallback {
|
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||||
private static final String TTS_CHANNEL = "com.example.ai_chat_assistant/tts";
|
import io.flutter.plugin.common.MethodCall;
|
||||||
private static final String ASR_CHANNEL = "com.example.ai_chat_assistant/asr";
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||||
|
import io.flutter.plugin.common.MethodChannel.Result;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerThread;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONException;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.idst.nui.Constants;
|
||||||
|
import com.alibaba.idst.nui.INativeStreamInputTtsCallback;
|
||||||
|
import com.alibaba.idst.nui.NativeNui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AiAssistantPlugin
|
||||||
|
*/
|
||||||
|
public class AiAssistantPlugin implements FlutterPlugin, MethodCallHandler {
|
||||||
|
|
||||||
|
private static final String CHANNEL = "com.example.ai_chat_assistant/ali_sdk";
|
||||||
private static final String TAG = "AliyunSDK";
|
private static final String TAG = "AliyunSDK";
|
||||||
private static final String APP_KEY = "bXFFc1V65iYbW6EF";
|
private static final String APP_KEY = "bXFFc1V65iYbW6EF";
|
||||||
private static final String ACCESS_KEY = "LTAI5t71JHxXRvt2mGuEVz9X";
|
private static final String ACCESS_KEY = "LTAI5t71JHxXRvt2mGuEVz9X";
|
||||||
@@ -37,6 +37,15 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
|||||||
private final NativeNui streamInputTtsInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
|
private final NativeNui streamInputTtsInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
|
||||||
private final NativeNui asrInstance = new NativeNui();
|
private final NativeNui asrInstance = new NativeNui();
|
||||||
|
|
||||||
|
/// The MethodChannel that will the communication between Flutter and native Android
|
||||||
|
///
|
||||||
|
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
|
||||||
|
/// when the Flutter Engine is detached from the Activity
|
||||||
|
private MethodChannel channel;
|
||||||
|
private Handler asrHandler;
|
||||||
|
private AsrCallBack asrCallBack;
|
||||||
|
private Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
private final AudioPlayer ttsAudioTrack = new AudioPlayer(new AudioPlayerCallback() {
|
private final AudioPlayer ttsAudioTrack = new AudioPlayer(new AudioPlayerCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void playStart() {
|
public void playStart() {
|
||||||
@@ -53,20 +62,35 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
private MethodChannel asrMethodChannel;
|
@Override
|
||||||
private final static int ASR_SAMPLE_RATE = 16000;
|
public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {
|
||||||
private final static int ASR_WAVE_FRAM_SIZE = 20 * 2 * 1 * ASR_SAMPLE_RATE / 1000; //20ms audio for 16k/16bit/mono
|
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL);
|
||||||
private AudioRecord asrAudioRecorder = null;
|
channel.setMethodCallHandler(this);
|
||||||
private boolean asrStopping = false;
|
HandlerThread asrHandlerThread = new HandlerThread("process_thread");
|
||||||
private Handler asrHandler;
|
asrHandlerThread.start();
|
||||||
private String asrText = "";
|
asrHandler = new Handler(asrHandlerThread.getLooper());
|
||||||
|
asrCallBack = new AsrCallBack(channel);
|
||||||
|
asrInstance.initialize(asrCallBack, genAsrInitParams(),
|
||||||
|
Constants.LogLevel.LOG_LEVEL_NONE, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configureFlutterEngine(FlutterEngine flutterEngine) {
|
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||||
super.configureFlutterEngine(flutterEngine);
|
channel.setMethodCallHandler(null);
|
||||||
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), TTS_CHANNEL)
|
ttsAudioTrack.stop();
|
||||||
.setMethodCallHandler((call, result) -> {
|
ttsAudioTrack.releaseAudioTrack();
|
||||||
Map<String, Object> args = (Map<String, Object>) call.arguments;
|
streamInputTtsInstance.stopStreamInputTts();
|
||||||
|
streamInputTtsInstance.release();
|
||||||
|
// asrInstance.release();
|
||||||
|
// if (asrCallBack != null) {
|
||||||
|
// asrCallBack.release();
|
||||||
|
// asrCallBack = null;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMethodCall(MethodCall call, @NonNull Result result) {
|
||||||
|
Map<String, Object> args = call.arguments();
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "startTts":
|
case "startTts":
|
||||||
Object isChinese = args.get("isChinese");
|
Object isChinese = args.get("isChinese");
|
||||||
@@ -89,14 +113,6 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
|||||||
case "stopTts":
|
case "stopTts":
|
||||||
stopTts();
|
stopTts();
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
result.notImplemented();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
asrMethodChannel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), ASR_CHANNEL);
|
|
||||||
asrMethodChannel.setMethodCallHandler((call, result) -> {
|
|
||||||
switch (call.method) {
|
|
||||||
case "startAsr":
|
case "startAsr":
|
||||||
startAsr();
|
startAsr();
|
||||||
break;
|
break;
|
||||||
@@ -107,84 +123,6 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
|||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
HandlerThread asrHandlerThread = new HandlerThread("process_thread");
|
|
||||||
asrHandlerThread.start();
|
|
||||||
asrHandler = new Handler(asrHandlerThread.getLooper());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
Log.i(TAG, "onStart");
|
|
||||||
super.onStart();
|
|
||||||
asrInstance.initialize(this, genAsrInitParams(),
|
|
||||||
Constants.LogLevel.LOG_LEVEL_NONE, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
Log.i(TAG, "onStop");
|
|
||||||
super.onStop();
|
|
||||||
|
|
||||||
asrInstance.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
ttsAudioTrack.stop();
|
|
||||||
ttsAudioTrack.releaseAudioTrack();
|
|
||||||
streamInputTtsInstance.stopStreamInputTts();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean startTts(boolean isChinese) {
|
|
||||||
int ret = streamInputTtsInstance.startStreamInputTts(new INativeStreamInputTtsCallback() {
|
|
||||||
@Override
|
|
||||||
public void onStreamInputTtsEventCallback(INativeStreamInputTtsCallback.StreamInputTtsEvent event, String task_id, String session_id, int ret_code, String error_msg, String timestamp, String all_response) {
|
|
||||||
Log.i(TAG, "stream input tts event(" + event + ") session id(" + session_id + ") task id(" + task_id + ") retCode(" + ret_code + ") errMsg(" + error_msg + ")");
|
|
||||||
if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTED) {
|
|
||||||
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTED");
|
|
||||||
ttsAudioTrack.play();
|
|
||||||
Log.i(TAG, "start play");
|
|
||||||
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SENTENCE_SYNTHESIS) {
|
|
||||||
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SENTENCE_SYNTHESIS:" + timestamp);
|
|
||||||
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE || event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_TASK_FAILED) {
|
|
||||||
/*
|
|
||||||
* 提示: STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE事件表示TTS已经合成完并通过回调传回了所有音频数据, 而不是表示播放器已经播放完了所有音频数据。
|
|
||||||
*/
|
|
||||||
Log.i(TAG, "play end");
|
|
||||||
|
|
||||||
// 表示推送完数据, 当播放器播放结束则会有playOver回调
|
|
||||||
ttsAudioTrack.isFinishSend(true);
|
|
||||||
|
|
||||||
if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_TASK_FAILED) {
|
|
||||||
Log.e(TAG, "STREAM_INPUT_TTS_EVENT_TASK_FAILED: " + "error_code(" + ret_code + ") error_message(" + error_msg + ")");
|
|
||||||
}
|
|
||||||
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SENTENCE_BEGIN) {
|
|
||||||
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SENTENCE_BEGIN:" + all_response);
|
|
||||||
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SENTENCE_END) {
|
|
||||||
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SENTENCE_END:" + all_response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStreamInputTtsDataCallback(byte[] data) {
|
|
||||||
if (data.length > 0) {
|
|
||||||
ttsAudioTrack.setAudioData(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, genTtsTicket(), genTtsParameters(isChinese), "", Constants.LogLevel.toInt(Constants.LogLevel.LOG_LEVEL_NONE), false);
|
|
||||||
if (Constants.NuiResultCode.SUCCESS != ret) {
|
|
||||||
Log.i(TAG, "start tts failed " + ret);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendTts(String text) {
|
private void sendTts(String text) {
|
||||||
@@ -201,7 +139,6 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startAsr() {
|
private void startAsr() {
|
||||||
asrText = "";
|
|
||||||
asrHandler.post(() -> {
|
asrHandler.post(() -> {
|
||||||
String setParamsString = genAsrParams();
|
String setParamsString = genAsrParams();
|
||||||
Log.i(TAG, "nui set params " + setParamsString);
|
Log.i(TAG, "nui set params " + setParamsString);
|
||||||
@@ -213,105 +150,12 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
|||||||
|
|
||||||
private void stopAsr() {
|
private void stopAsr() {
|
||||||
asrHandler.post(() -> {
|
asrHandler.post(() -> {
|
||||||
asrStopping = true;
|
|
||||||
long ret = asrInstance.stopDialog();
|
long ret = asrInstance.stopDialog();
|
||||||
runOnUiThread(() -> asrMethodChannel.invokeMethod("onAsrStop", null));
|
handler.post(() -> channel.invokeMethod("onAsrStop", null));
|
||||||
Log.i(TAG, "cancel dialog " + ret + " end");
|
Log.i(TAG, "cancel dialog " + ret + " end");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNuiEventCallback(Constants.NuiEvent event, final int resultCode,
|
|
||||||
final int arg2, KwsResult kwsResult,
|
|
||||||
AsrResult asrResult) {
|
|
||||||
Log.i(TAG, "event=" + event + " resultCode=" + resultCode);
|
|
||||||
if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_STARTED) {
|
|
||||||
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_COMPLETE) {
|
|
||||||
asrStopping = false;
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) {
|
|
||||||
JSONObject jsonObject = JSON.parseObject(asrResult.allResponse);
|
|
||||||
JSONObject payload = jsonObject.getJSONObject("payload");
|
|
||||||
String result = payload.getString("result");
|
|
||||||
if (asrMethodChannel != null && result != null && !result.isBlank()) {
|
|
||||||
runOnUiThread(() -> asrMethodChannel.invokeMethod("onAsrResult", asrText + result));
|
|
||||||
}
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_SENTENCE_END) {
|
|
||||||
JSONObject jsonObject = JSON.parseObject(asrResult.allResponse);
|
|
||||||
JSONObject payload = jsonObject.getJSONObject("payload");
|
|
||||||
String result = payload.getString("result");
|
|
||||||
if (asrMethodChannel != null && result != null && !result.isBlank()) {
|
|
||||||
asrText += result;
|
|
||||||
runOnUiThread(() -> asrMethodChannel.invokeMethod("onAsrResult", asrText));
|
|
||||||
}
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_VAD_START) {
|
|
||||||
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_VAD_END) {
|
|
||||||
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_ASR_ERROR) {
|
|
||||||
asrStopping = false;
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_MIC_ERROR) {
|
|
||||||
asrStopping = false;
|
|
||||||
} else if (event == Constants.NuiEvent.EVENT_DIALOG_EX) { /* unused */
|
|
||||||
Log.i(TAG, "dialog extra message = " + asrResult.asrResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//当调用NativeNui的start后,会一定时间反复回调该接口,底层会提供buffer并告知这次需要数据的长度
|
|
||||||
//返回值告知底层读了多少数据,应该尽量保证return的长度等于需要的长度,如果返回<=0,则表示出错
|
|
||||||
@Override
|
|
||||||
public int onNuiNeedAudioData(byte[] buffer, int len) {
|
|
||||||
if (asrAudioRecorder == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (asrAudioRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
|
|
||||||
Log.e(TAG, "audio recorder not init");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return asrAudioRecorder.read(buffer, 0, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
//当录音状态发送变化的时候调用
|
|
||||||
@Override
|
|
||||||
public void onNuiAudioStateChanged(Constants.AudioState state) {
|
|
||||||
Log.i(TAG, "onNuiAudioStateChanged");
|
|
||||||
if (state == Constants.AudioState.STATE_OPEN) {
|
|
||||||
Log.i(TAG, "audio recorder start");
|
|
||||||
asrAudioRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,
|
|
||||||
ASR_SAMPLE_RATE,
|
|
||||||
AudioFormat.CHANNEL_IN_MONO,
|
|
||||||
AudioFormat.ENCODING_PCM_16BIT,
|
|
||||||
ASR_WAVE_FRAM_SIZE * 4);
|
|
||||||
asrAudioRecorder.startRecording();
|
|
||||||
Log.i(TAG, "audio recorder start done");
|
|
||||||
} else if (state == Constants.AudioState.STATE_CLOSE) {
|
|
||||||
Log.i(TAG, "audio recorder close");
|
|
||||||
if (asrAudioRecorder != null) {
|
|
||||||
asrAudioRecorder.release();
|
|
||||||
}
|
|
||||||
} else if (state == Constants.AudioState.STATE_PAUSE) {
|
|
||||||
Log.i(TAG, "audio recorder pause");
|
|
||||||
if (asrAudioRecorder != null) {
|
|
||||||
asrAudioRecorder.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNuiAudioRMSChanged(float val) {
|
|
||||||
// Log.i(TAG, "onNuiAudioRMSChanged vol " + val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNuiVprEventCallback(Constants.NuiVprEvent event) {
|
|
||||||
Log.i(TAG, "onNuiVprEventCallback event " + event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNuiLogTrackCallback(Constants.LogLevel level, String log) {
|
|
||||||
Log.i(TAG, "onNuiLogTrackCallback log level:" + level + ", message -> " + log);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String genTtsTicket() {
|
private String genTtsTicket() {
|
||||||
String str = "";
|
String str = "";
|
||||||
try {
|
try {
|
||||||
@@ -433,4 +277,51 @@ public class MainActivity extends FlutterActivity implements INativeNuiCallback
|
|||||||
Log.i(TAG, "dialog params: " + params);
|
Log.i(TAG, "dialog params: " + params);
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean startTts(boolean isChinese) {
|
||||||
|
int ret = streamInputTtsInstance.startStreamInputTts(new INativeStreamInputTtsCallback() {
|
||||||
|
@Override
|
||||||
|
public void onStreamInputTtsEventCallback(INativeStreamInputTtsCallback.StreamInputTtsEvent event, String task_id, String session_id, int ret_code, String error_msg, String timestamp, String all_response) {
|
||||||
|
Log.i(TAG, "stream input tts event(" + event + ") session id(" + session_id + ") task id(" + task_id + ") retCode(" + ret_code + ") errMsg(" + error_msg + ")");
|
||||||
|
if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTED) {
|
||||||
|
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTED");
|
||||||
|
ttsAudioTrack.play();
|
||||||
|
Log.i(TAG, "start play");
|
||||||
|
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SENTENCE_SYNTHESIS) {
|
||||||
|
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SENTENCE_SYNTHESIS:" + timestamp);
|
||||||
|
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE || event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_TASK_FAILED) {
|
||||||
|
/*
|
||||||
|
* 提示: STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE事件表示TTS已经合成完并通过回调传回了所有音频数据, 而不是表示播放器已经播放完了所有音频数据。
|
||||||
|
*/
|
||||||
|
Log.i(TAG, "play end");
|
||||||
|
|
||||||
|
// 表示推送完数据, 当播放器播放结束则会有playOver回调
|
||||||
|
ttsAudioTrack.isFinishSend(true);
|
||||||
|
|
||||||
|
if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_TASK_FAILED) {
|
||||||
|
Log.e(TAG, "STREAM_INPUT_TTS_EVENT_TASK_FAILED: " + "error_code(" + ret_code + ") error_message(" + error_msg + ")");
|
||||||
|
}
|
||||||
|
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SENTENCE_BEGIN) {
|
||||||
|
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SENTENCE_BEGIN:" + all_response);
|
||||||
|
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SENTENCE_END) {
|
||||||
|
Log.i(TAG, "STREAM_INPUT_TTS_EVENT_SENTENCE_END:" + all_response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStreamInputTtsDataCallback(byte[] data) {
|
||||||
|
if (data.length > 0) {
|
||||||
|
ttsAudioTrack.setAudioData(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, genTtsTicket(), genTtsParameters(isChinese), "", Constants.LogLevel.toInt(Constants.LogLevel.LOG_LEVEL_NONE), false);
|
||||||
|
if (Constants.NuiResultCode.SUCCESS != ret) {
|
||||||
|
Log.i(TAG, "start tts failed " + ret);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
package com.example.ai_assistant_plugin;
|
||||||
|
|
||||||
|
import android.media.AudioFormat;
|
||||||
|
import android.media.AudioRecord;
|
||||||
|
import android.media.MediaRecorder;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.idst.nui.AsrResult;
|
||||||
|
import com.alibaba.idst.nui.Constants;
|
||||||
|
import com.alibaba.idst.nui.INativeNuiCallback;
|
||||||
|
import com.alibaba.idst.nui.KwsResult;
|
||||||
|
|
||||||
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
|
||||||
|
public class AsrCallBack implements INativeNuiCallback {
|
||||||
|
|
||||||
|
private static final String TAG = "AliAsr";
|
||||||
|
private final static int ASR_SAMPLE_RATE = 16000;
|
||||||
|
private final static int ASR_WAVE_FRAM_SIZE = 20 * 2 * 1 * ASR_SAMPLE_RATE / 1000; //20ms audio for 16k/16bit/mono
|
||||||
|
private AudioRecord asrAudioRecorder = null;
|
||||||
|
private MethodChannel channel;
|
||||||
|
private String asrText = "";
|
||||||
|
private Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
public AsrCallBack(MethodChannel channel) {
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNuiEventCallback(Constants.NuiEvent event, final int resultCode,
|
||||||
|
final int arg2, KwsResult kwsResult,
|
||||||
|
AsrResult asrResult) {
|
||||||
|
Log.i(TAG, "event=" + event + " resultCode=" + resultCode);
|
||||||
|
if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_STARTED) {
|
||||||
|
asrText = "";
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_TRANSCRIBER_COMPLETE) {
|
||||||
|
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_ASR_PARTIAL_RESULT) {
|
||||||
|
JSONObject jsonObject = JSON.parseObject(asrResult.allResponse);
|
||||||
|
JSONObject payload = jsonObject.getJSONObject("payload");
|
||||||
|
String result = payload.getString("result");
|
||||||
|
if (channel != null && result != null && !result.isBlank()) {
|
||||||
|
handler.post(() -> channel.invokeMethod("onAsrResult", asrText + result));
|
||||||
|
}
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_SENTENCE_END) {
|
||||||
|
JSONObject jsonObject = JSON.parseObject(asrResult.allResponse);
|
||||||
|
JSONObject payload = jsonObject.getJSONObject("payload");
|
||||||
|
String result = payload.getString("result");
|
||||||
|
if (channel != null && result != null && !result.isBlank()) {
|
||||||
|
asrText += result;
|
||||||
|
handler.post(() -> channel.invokeMethod("onAsrResult", asrText));
|
||||||
|
}
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_VAD_START) {
|
||||||
|
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_VAD_END) {
|
||||||
|
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_ASR_ERROR) {
|
||||||
|
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_MIC_ERROR) {
|
||||||
|
|
||||||
|
} else if (event == Constants.NuiEvent.EVENT_DIALOG_EX) { /* unused */
|
||||||
|
Log.i(TAG, "dialog extra message = " + asrResult.asrResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//当调用NativeNui的start后,会一定时间反复回调该接口,底层会提供buffer并告知这次需要数据的长度
|
||||||
|
//返回值告知底层读了多少数据,应该尽量保证return的长度等于需要的长度,如果返回<=0,则表示出错
|
||||||
|
@Override
|
||||||
|
public int onNuiNeedAudioData(byte[] buffer, int len) {
|
||||||
|
if (asrAudioRecorder == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asrAudioRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
|
||||||
|
Log.e(TAG, "audio recorder not init");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return asrAudioRecorder.read(buffer, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
//当录音状态发送变化的时候调用
|
||||||
|
@Override
|
||||||
|
public void onNuiAudioStateChanged(Constants.AudioState state) {
|
||||||
|
Log.i(TAG, "onNuiAudioStateChanged");
|
||||||
|
if (state == Constants.AudioState.STATE_OPEN) {
|
||||||
|
Log.i(TAG, "audio recorder start");
|
||||||
|
asrAudioRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,
|
||||||
|
ASR_SAMPLE_RATE,
|
||||||
|
AudioFormat.CHANNEL_IN_MONO,
|
||||||
|
AudioFormat.ENCODING_PCM_16BIT,
|
||||||
|
ASR_WAVE_FRAM_SIZE * 4);
|
||||||
|
asrAudioRecorder.startRecording();
|
||||||
|
Log.i(TAG, "audio recorder start done");
|
||||||
|
} else if (state == Constants.AudioState.STATE_CLOSE) {
|
||||||
|
Log.i(TAG, "audio recorder close");
|
||||||
|
if (asrAudioRecorder != null) {
|
||||||
|
asrAudioRecorder.release();
|
||||||
|
}
|
||||||
|
} else if (state == Constants.AudioState.STATE_PAUSE) {
|
||||||
|
Log.i(TAG, "audio recorder pause");
|
||||||
|
if (asrAudioRecorder != null) {
|
||||||
|
asrAudioRecorder.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNuiAudioRMSChanged(float val) {
|
||||||
|
// Log.i(TAG, "onNuiAudioRMSChanged vol " + val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNuiVprEventCallback(Constants.NuiVprEvent event) {
|
||||||
|
Log.i(TAG, "onNuiVprEventCallback event " + event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNuiLogTrackCallback(Constants.LogLevel level, String log) {
|
||||||
|
Log.i(TAG, "onNuiLogTrackCallback log level:" + level + ", message -> " + log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void release() {
|
||||||
|
// 释放音频录制资源
|
||||||
|
if (asrAudioRecorder != null) {
|
||||||
|
try {
|
||||||
|
asrAudioRecorder.stop();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "release error", e);
|
||||||
|
}
|
||||||
|
asrAudioRecorder.release();
|
||||||
|
asrAudioRecorder = null;
|
||||||
|
}
|
||||||
|
channel = null;
|
||||||
|
asrText = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.ai_chat_assistant;
|
package com.example.ai_assistant_plugin;
|
||||||
|
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.ai_chat_assistant;
|
package com.example.ai_assistant_plugin;
|
||||||
|
|
||||||
public interface AudioPlayerCallback {
|
public interface AudioPlayerCallback {
|
||||||
public void playStart();
|
public void playStart();
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package com.example.ai_chat_assistant;
|
package com.example.ai_assistant_plugin;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.example.ai_assistant_plugin.token.AccessToken;
|
||||||
import com.example.ai_chat_assistant.token.AccessToken;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.ai_chat_assistant.token;
|
package com.example.ai_assistant_plugin.token;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.ai_chat_assistant.token;
|
package com.example.ai_assistant_plugin.token;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.ai_chat_assistant.token;
|
package com.example.ai_assistant_plugin.token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Say something
|
* Say something
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.ai_chat_assistant.token;
|
package com.example.ai_assistant_plugin.token;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.ai_chat_assistant.token;
|
package com.example.ai_assistant_plugin.token;
|
||||||
|
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
|
||||||
45
example/.gitignore
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# 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
|
||||||
|
**/doc/api/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
/coverage/
|
||||||
|
|
||||||
|
# Symbolication related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Android Studio will place build artifacts here
|
||||||
|
/android/app/debug
|
||||||
|
/android/app/profile
|
||||||
|
/android/app/release
|
||||||
30
example/.metadata
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# 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: "05db9689081f091050f01aed79f04dce0c750154"
|
||||||
|
channel: "stable"
|
||||||
|
|
||||||
|
project_type: app
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||||
|
base_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||||
|
- platform: android
|
||||||
|
create_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||||
|
base_revision: 05db9689081f091050f01aed79f04dce0c750154
|
||||||
|
|
||||||
|
# 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'
|
||||||
16
example/README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# example
|
||||||
|
|
||||||
|
A new Flutter project.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This project is a starting point for a Flutter application.
|
||||||
|
|
||||||
|
A few resources to get you started if this is your first Flutter project:
|
||||||
|
|
||||||
|
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||||
|
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||||
|
|
||||||
|
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.
|
||||||
28
example/analysis_options.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# This file configures the analyzer, which statically analyzes Dart code to
|
||||||
|
# check for errors, warnings, and lints.
|
||||||
|
#
|
||||||
|
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||||
|
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||||
|
# invoked from the command line by running `flutter analyze`.
|
||||||
|
|
||||||
|
# The following line activates a set of recommended lints for Flutter apps,
|
||||||
|
# packages, and plugins designed to encourage good coding practices.
|
||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
linter:
|
||||||
|
# The lint rules applied to this project can be customized in the
|
||||||
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
|
# included above or to enable additional rules. A list of all available lints
|
||||||
|
# and their documentation is published at https://dart.dev/lints.
|
||||||
|
#
|
||||||
|
# Instead of disabling a lint rule for the entire project in the
|
||||||
|
# section below, it can also be suppressed for a single line of code
|
||||||
|
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||||
|
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||||
|
# producing the lint.
|
||||||
|
rules:
|
||||||
|
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||||
|
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||||
|
|
||||||
|
# Additional information about this file can be found at
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
||||||
14
example/android/.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
gradle-wrapper.jar
|
||||||
|
/.gradle
|
||||||
|
/captures/
|
||||||
|
/gradlew
|
||||||
|
/gradlew.bat
|
||||||
|
/local.properties
|
||||||
|
GeneratedPluginRegistrant.java
|
||||||
|
.cxx/
|
||||||
|
|
||||||
|
# Remember to never publicly share your keystore.
|
||||||
|
# See https://flutter.dev/to/reference-keystore
|
||||||
|
key.properties
|
||||||
|
**/*.keystore
|
||||||
|
**/*.jks
|
||||||
@@ -6,9 +6,9 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.example.ai_chat_assistant"
|
namespace = "com.example.example"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion = "29.0.13599879"
|
ndkVersion = flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
@@ -21,10 +21,10 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId = "com.example.ai_chat_assistant"
|
applicationId = "com.example.example"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
minSdk = 24
|
minSdk = flutter.minSdkVersion
|
||||||
targetSdk = flutter.targetSdkVersion
|
targetSdk = flutter.targetSdkVersion
|
||||||
versionCode = flutter.versionCode
|
versionCode = flutter.versionCode
|
||||||
versionName = flutter.versionName
|
versionName = flutter.versionName
|
||||||
@@ -37,18 +37,16 @@ android {
|
|||||||
signingConfig = signingConfigs.getByName("debug")
|
signingConfig = signingConfigs.getByName("debug")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
repositories {
|
viewBinding {
|
||||||
flatDir {
|
// isEnabled = viewBindingEnabled
|
||||||
dirs("libs")
|
|
||||||
}
|
}
|
||||||
|
dependenciesInfo {
|
||||||
|
includeInApk = includeInApk
|
||||||
|
includeInBundle = includeInBundle
|
||||||
}
|
}
|
||||||
|
ndkVersion = ndkVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
source = "../.."
|
source = "../.."
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation(files("libs/fastjson-1.1.46.android.jar"))
|
|
||||||
implementation(files("libs/nuisdk-release.aar"))
|
|
||||||
}
|
|
||||||
@@ -4,5 +4,4 @@
|
|||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.intent.action.TTS_SERVICE" />
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<application
|
<application
|
||||||
android:label="ai_chat_assistant"
|
android:label="example"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
@@ -41,8 +41,5 @@
|
|||||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||||
<data android:mimeType="text/plain"/>
|
<data android:mimeType="text/plain"/>
|
||||||
</intent>
|
</intent>
|
||||||
<intent>
|
|
||||||
<action android:name="android.intent.action.TTS_SERVICE"/>
|
|
||||||
</intent>
|
|
||||||
</queries>
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.example.example;
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity;
|
||||||
|
|
||||||
|
public class MainActivity extends FlutterActivity {
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 544 B |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
7
example/android/app/src/profile/AndroidManifest.xml
Normal file
@@ -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>
|
||||||
29
example/android/build.gradle.kts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/public") }
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/google") }
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/central") }
|
||||||
|
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newBuildDir: Directory =
|
||||||
|
rootProject.layout.buildDirectory
|
||||||
|
.dir("../../build")
|
||||||
|
.get()
|
||||||
|
rootProject.layout.buildDirectory.value(newBuildDir)
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
|
||||||
|
project.layout.buildDirectory.value(newSubprojectBuildDir)
|
||||||
|
}
|
||||||
|
subprojects {
|
||||||
|
project.evaluationDependsOn(":app")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Delete>("clean") {
|
||||||
|
delete(rootProject.layout.buildDirectory)
|
||||||
|
}
|
||||||
663
example/android/build/reports/problems/problems-report.html
Normal file
3
example/android/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
|
android.useAndroidX=true
|
||||||
|
android.enableJetifier=true
|
||||||
5
example/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
|
||||||
31
example/android/settings.gradle.kts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
pluginManagement {
|
||||||
|
val flutterSdkPath =
|
||||||
|
run {
|
||||||
|
val properties = java.util.Properties()
|
||||||
|
file("local.properties").inputStream().use { properties.load(it) }
|
||||||
|
val flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
|
||||||
|
flutterSdkPath
|
||||||
|
}
|
||||||
|
|
||||||
|
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/public") }
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/google") }
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
|
||||||
|
maven { url = uri("https://maven.aliyun.com/repository/central") }
|
||||||
|
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||||
|
id("com.android.application") version "8.9.1" apply false
|
||||||
|
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
|
||||||
|
}
|
||||||
|
|
||||||
|
include(":app")
|
||||||
58
example/lib/main.dart
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:ai_chat_assistant/app.dart';
|
||||||
|
import 'package:ai_chat_assistant/services/message_service.dart';
|
||||||
|
import 'package:ai_chat_assistant/enums/vehicle_command_type.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
// 请求麦克风权限
|
||||||
|
if (!await Permission.microphone.isGranted) {
|
||||||
|
await Permission.microphone.request();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 AI Chat Assistant,注册车控命令回调
|
||||||
|
ChatAssistantApp.initialize(
|
||||||
|
commandCallback: (VehicleCommandType type, Map<String, dynamic>? params) async {
|
||||||
|
// 这里是示例的车控命令处理逻辑
|
||||||
|
print('收到车控命令: $type, 参数: $params');
|
||||||
|
return Future.value((true, {'message': '命令已执行'}));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
runApp(
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (_) => MessageService(),
|
||||||
|
child: const MyApp(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyApp extends StatelessWidget {
|
||||||
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
title: 'AI Chat Assistant Example',
|
||||||
|
theme: ThemeData(
|
||||||
|
primarySwatch: Colors.blue,
|
||||||
|
useMaterial3: true,
|
||||||
|
),
|
||||||
|
home: const ExampleHomePage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExampleHomePage extends StatelessWidget {
|
||||||
|
const ExampleHomePage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Scaffold(
|
||||||
|
body: ChatAssistantApp(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
608
example/pubspec.lock
Normal file
@@ -0,0 +1,608 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
ai_chat_assistant:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: ".."
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "1.0.0+1"
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.7.0"
|
||||||
|
async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: async
|
||||||
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.0"
|
||||||
|
audioplayers:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers
|
||||||
|
sha256: c05c6147124cd63e725e861335a8b4d57300b80e6e92cea7c145c739223bbaef
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.2.1"
|
||||||
|
audioplayers_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_android
|
||||||
|
sha256: b00e1a0e11365d88576320ec2d8c192bc21f1afb6c0e5995d1c57ae63156acb5
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.3"
|
||||||
|
audioplayers_darwin:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_darwin
|
||||||
|
sha256: "3034e99a6df8d101da0f5082dcca0a2a99db62ab1d4ddb3277bed3f6f81afe08"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.2"
|
||||||
|
audioplayers_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_linux
|
||||||
|
sha256: "60787e73fefc4d2e0b9c02c69885402177e818e4e27ef087074cf27c02246c9e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
|
audioplayers_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_platform_interface
|
||||||
|
sha256: "365c547f1bb9e77d94dd1687903a668d8f7ac3409e48e6e6a3668a1ac2982adb"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.0"
|
||||||
|
audioplayers_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_web
|
||||||
|
sha256: "22cd0173e54d92bd9b2c80b1204eb1eb159ece87475ab58c9788a70ec43c2a62"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
|
audioplayers_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_windows
|
||||||
|
sha256: "9536812c9103563644ada2ef45ae523806b0745f7a78e89d1b5fb1951de90e1a"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
|
basic_intl:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
path: "../packages/basic_intl"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "0.2.0"
|
||||||
|
boolean_selector:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: boolean_selector
|
||||||
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
characters:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: characters
|
||||||
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
clock:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: clock
|
||||||
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: collection
|
||||||
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.19.1"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.6"
|
||||||
|
cupertino_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: cupertino_icons
|
||||||
|
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.8"
|
||||||
|
fake_async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fake_async
|
||||||
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
|
ffi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ffi
|
||||||
|
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file
|
||||||
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
|
flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_lints:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: flutter_lints
|
||||||
|
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.0"
|
||||||
|
flutter_markdown:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_markdown
|
||||||
|
sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.7+1"
|
||||||
|
flutter_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_tts:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_tts
|
||||||
|
sha256: bdf2fc4483e74450dc9fc6fe6a9b6a5663e108d4d0dad3324a22c8e26bf48af4
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.3"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
fluttertoast:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fluttertoast
|
||||||
|
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "8.2.12"
|
||||||
|
http:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.0"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.7"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "11.0.1"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.10"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
lints:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: lints
|
||||||
|
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.1.1"
|
||||||
|
markdown:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: markdown
|
||||||
|
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "7.3.0"
|
||||||
|
matcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: matcher
|
||||||
|
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.17"
|
||||||
|
material_color_utilities:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: material_color_utilities
|
||||||
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.11.1"
|
||||||
|
meta:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: meta
|
||||||
|
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.16.0"
|
||||||
|
nested:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nested
|
||||||
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
path:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path
|
||||||
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.1"
|
||||||
|
path_provider:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider
|
||||||
|
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.5"
|
||||||
|
path_provider_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_android
|
||||||
|
sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.18"
|
||||||
|
path_provider_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_foundation
|
||||||
|
sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.2"
|
||||||
|
path_provider_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_linux
|
||||||
|
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.1"
|
||||||
|
path_provider_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_platform_interface
|
||||||
|
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
path_provider_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_windows
|
||||||
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
|
permission_handler:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler
|
||||||
|
sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "12.0.1"
|
||||||
|
permission_handler_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_android
|
||||||
|
sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "13.0.1"
|
||||||
|
permission_handler_apple:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_apple
|
||||||
|
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "9.4.7"
|
||||||
|
permission_handler_html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_html
|
||||||
|
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3+5"
|
||||||
|
permission_handler_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_platform_interface
|
||||||
|
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.3.0"
|
||||||
|
permission_handler_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_windows
|
||||||
|
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
|
platform:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: platform
|
||||||
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.6"
|
||||||
|
plugin_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: plugin_platform_interface
|
||||||
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.8"
|
||||||
|
provider:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.5+1"
|
||||||
|
record:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record
|
||||||
|
sha256: "9dbc6ff3e784612f90a9b001373c45ff76b7a08abd2bd9fdf72c242320c8911c"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.1"
|
||||||
|
record_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_android
|
||||||
|
sha256: "8361a791c9a3fa5c065f0b8b5adb10f12531f8538c86b19474cf7b56ea80d426"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
record_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_ios
|
||||||
|
sha256: "13e241ed9cbc220534a40ae6b66222e21288db364d96dd66fb762ebd3cb77c71"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
record_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_linux
|
||||||
|
sha256: "235b1f1fb84e810f8149cc0c2c731d7d697f8d1c333b32cb820c449bf7bb72d8"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
|
record_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_macos
|
||||||
|
sha256: "2849068bb59072f300ad63ed146e543d66afaef8263edba4de4834fc7c8d4d35"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
record_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_platform_interface
|
||||||
|
sha256: b0065fdf1ec28f5a634d676724d388a77e43ce7646fb049949f58c69f3fcb4ed
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
record_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_web
|
||||||
|
sha256: "4f0adf20c9ccafcc02d71111fd91fba1ca7b17a7453902593e5a9b25b74a5c56"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
|
record_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: record_windows
|
||||||
|
sha256: "223258060a1d25c62bae18282c16783f28581ec19401d17e56b5205b9f039d78"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.7"
|
||||||
|
sky_engine:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
source_span:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_span
|
||||||
|
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.10.1"
|
||||||
|
stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stack_trace
|
||||||
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.12.1"
|
||||||
|
stream_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_channel
|
||||||
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
string_scanner:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: string_scanner
|
||||||
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
synchronized:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: synchronized
|
||||||
|
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.4.0"
|
||||||
|
term_glyph:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: term_glyph
|
||||||
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
test_api:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_api
|
||||||
|
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.6"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
uuid:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
|
vector_math:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_math
|
||||||
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "15.0.2"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
xdg_directories:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xdg_directories
|
||||||
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
sdks:
|
||||||
|
dart: ">=3.9.0 <4.0.0"
|
||||||
|
flutter: ">=3.29.0"
|
||||||
93
example/pubspec.yaml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
name: example
|
||||||
|
description: "AI Chat Assistant Example App"
|
||||||
|
# The following line prevents the package from being accidentally published to
|
||||||
|
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||||
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
|
# The following defines the version and build number for your application.
|
||||||
|
# A version number is three numbers separated by dots, like 1.2.43
|
||||||
|
# followed by an optional build number separated by a +.
|
||||||
|
# Both the version and the builder number may be overridden in flutter
|
||||||
|
# build by specifying --build-name and --build-number, respectively.
|
||||||
|
# In Android, build-name is used as versionName while build-number used as versionCode.
|
||||||
|
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
||||||
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
|
||||||
|
# Read more about iOS versioning at
|
||||||
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ^3.9.0
|
||||||
|
|
||||||
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
|
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
||||||
|
# dependencies can be manually updated by changing the version numbers below to
|
||||||
|
# the latest version available on pub.dev. To see which dependencies have newer
|
||||||
|
# versions available, run `flutter pub outdated`.
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
# The following adds the Cupertino Icons font to your application.
|
||||||
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
cupertino_icons: ^1.0.8
|
||||||
|
|
||||||
|
# 添加本地 AI Chat Assistant plugin 依赖
|
||||||
|
ai_chat_assistant:
|
||||||
|
path: ../
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
# The "flutter_lints" package below contains a set of recommended lints to
|
||||||
|
# encourage good coding practices. The lint set provided by the package is
|
||||||
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
|
# package. See that file for information about deactivating specific lint
|
||||||
|
# rules and activating additional ones.
|
||||||
|
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:
|
||||||
|
|
||||||
|
# The following line ensures that the Material Icons font is
|
||||||
|
# included with your application, so that you can use the icons in
|
||||||
|
# the material Icons class.
|
||||||
|
uses-material-design: true
|
||||||
|
|
||||||
|
# To add assets to your application, add an assets section, like this:
|
||||||
|
# assets:
|
||||||
|
# - images/a_dot_burr.jpeg
|
||||||
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|
||||||
|
# For details regarding adding assets from package dependencies, see
|
||||||
|
# https://flutter.dev/to/asset-from-package
|
||||||
|
|
||||||
|
# To add custom fonts to your application, 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 from package dependencies,
|
||||||
|
# see https://flutter.dev/to/font-from-package
|
||||||
30
example/test/widget_test.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// This is a basic Flutter widget test.
|
||||||
|
//
|
||||||
|
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||||
|
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||||
|
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||||
|
// tree, read text, and verify that the values of widget properties are correct.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'package:example/main.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||||
|
// Build our app and trigger a frame.
|
||||||
|
await tester.pumpWidget(const MyApp());
|
||||||
|
|
||||||
|
// Verify that our counter starts at 0.
|
||||||
|
expect(find.text('0'), findsOneWidget);
|
||||||
|
expect(find.text('1'), findsNothing);
|
||||||
|
|
||||||
|
// Tap the '+' icon and trigger a frame.
|
||||||
|
await tester.tap(find.byIcon(Icons.add));
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
// Verify that our counter has incremented.
|
||||||
|
expect(find.text('0'), findsNothing);
|
||||||
|
expect(find.text('1'), findsOneWidget);
|
||||||
|
});
|
||||||
|
}
|
||||||
3
packages/basic_intl/lib/basic_intl.dart
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
library basic_intl;
|
||||||
|
|
||||||
|
export 'src/intl.dart';
|
||||||
3
packages/basic_intl/lib/intl.dart
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
library basic_intl;
|
||||||
|
|
||||||
|
export 'src/intl.dart';
|
||||||
32
packages/basic_intl/lib/src/intl.dart
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
class Intl {
|
||||||
|
static String _currentLocale = 'zh_CN';
|
||||||
|
|
||||||
|
/// 获取当前语言环境
|
||||||
|
static String getCurrentLocale() {
|
||||||
|
// 尝试从系统获取语言环境
|
||||||
|
try {
|
||||||
|
final systemLocale = PlatformDispatcher.instance.locale;
|
||||||
|
_currentLocale = '${systemLocale.languageCode}_${systemLocale.countryCode ?? 'CN'}';
|
||||||
|
} catch (e) {
|
||||||
|
_currentLocale = 'zh_CN';
|
||||||
|
}
|
||||||
|
return _currentLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 设置当前语言环境
|
||||||
|
static void setCurrentLocale(String locale) {
|
||||||
|
_currentLocale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 判断是否为中文环境
|
||||||
|
static bool isChineseLocale() {
|
||||||
|
return getCurrentLocale().startsWith('zh');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 判断是否为英文环境
|
||||||
|
static bool isEnglishLocale() {
|
||||||
|
return getCurrentLocale().startsWith('en');
|
||||||
|
}
|
||||||
|
}
|
||||||
189
packages/basic_intl/pubspec.lock
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: async
|
||||||
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.0"
|
||||||
|
boolean_selector:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: boolean_selector
|
||||||
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
characters:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: characters
|
||||||
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
clock:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: clock
|
||||||
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: collection
|
||||||
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.19.1"
|
||||||
|
fake_async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fake_async
|
||||||
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
|
flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "11.0.1"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.10"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
matcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: matcher
|
||||||
|
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.17"
|
||||||
|
material_color_utilities:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: material_color_utilities
|
||||||
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.11.1"
|
||||||
|
meta:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: meta
|
||||||
|
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.16.0"
|
||||||
|
path:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path
|
||||||
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.1"
|
||||||
|
sky_engine:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
source_span:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_span
|
||||||
|
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.10.1"
|
||||||
|
stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stack_trace
|
||||||
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.12.1"
|
||||||
|
stream_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_channel
|
||||||
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
string_scanner:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: string_scanner
|
||||||
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
term_glyph:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: term_glyph
|
||||||
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
test_api:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_api
|
||||||
|
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.6"
|
||||||
|
vector_math:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_math
|
||||||
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "15.0.2"
|
||||||
|
sdks:
|
||||||
|
dart: ">=3.8.0-0 <4.0.0"
|
||||||
|
flutter: ">=3.18.0-18.0.pre.54"
|
||||||
16
packages/basic_intl/pubspec.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
name: basic_intl
|
||||||
|
description: Basic internationalization utilities for ai_chat_assistant
|
||||||
|
version: 0.2.0
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ^3.6.2
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
flutter:
|
||||||
231
pubspec.lock
@@ -6,7 +6,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.7.0"
|
||||||
async:
|
async:
|
||||||
@@ -14,7 +14,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.0"
|
version: "2.13.0"
|
||||||
audioplayers:
|
audioplayers:
|
||||||
@@ -22,7 +22,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: audioplayers
|
name: audioplayers
|
||||||
sha256: c05c6147124cd63e725e861335a8b4d57300b80e6e92cea7c145c739223bbaef
|
sha256: c05c6147124cd63e725e861335a8b4d57300b80e6e92cea7c145c739223bbaef
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.2.1"
|
version: "5.2.1"
|
||||||
audioplayers_android:
|
audioplayers_android:
|
||||||
@@ -30,7 +30,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: audioplayers_android
|
name: audioplayers_android
|
||||||
sha256: b00e1a0e11365d88576320ec2d8c192bc21f1afb6c0e5995d1c57ae63156acb5
|
sha256: b00e1a0e11365d88576320ec2d8c192bc21f1afb6c0e5995d1c57ae63156acb5
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.3"
|
version: "4.0.3"
|
||||||
audioplayers_darwin:
|
audioplayers_darwin:
|
||||||
@@ -38,7 +38,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: audioplayers_darwin
|
name: audioplayers_darwin
|
||||||
sha256: "3034e99a6df8d101da0f5082dcca0a2a99db62ab1d4ddb3277bed3f6f81afe08"
|
sha256: "3034e99a6df8d101da0f5082dcca0a2a99db62ab1d4ddb3277bed3f6f81afe08"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.2"
|
version: "5.0.2"
|
||||||
audioplayers_linux:
|
audioplayers_linux:
|
||||||
@@ -46,7 +46,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: audioplayers_linux
|
name: audioplayers_linux
|
||||||
sha256: "60787e73fefc4d2e0b9c02c69885402177e818e4e27ef087074cf27c02246c9e"
|
sha256: "60787e73fefc4d2e0b9c02c69885402177e818e4e27ef087074cf27c02246c9e"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
audioplayers_platform_interface:
|
audioplayers_platform_interface:
|
||||||
@@ -54,7 +54,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: audioplayers_platform_interface
|
name: audioplayers_platform_interface
|
||||||
sha256: "365c547f1bb9e77d94dd1687903a668d8f7ac3409e48e6e6a3668a1ac2982adb"
|
sha256: "365c547f1bb9e77d94dd1687903a668d8f7ac3409e48e6e6a3668a1ac2982adb"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.0"
|
version: "6.1.0"
|
||||||
audioplayers_web:
|
audioplayers_web:
|
||||||
@@ -62,7 +62,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: audioplayers_web
|
name: audioplayers_web
|
||||||
sha256: "22cd0173e54d92bd9b2c80b1204eb1eb159ece87475ab58c9788a70ec43c2a62"
|
sha256: "22cd0173e54d92bd9b2c80b1204eb1eb159ece87475ab58c9788a70ec43c2a62"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.1.0"
|
||||||
audioplayers_windows:
|
audioplayers_windows:
|
||||||
@@ -70,63 +70,54 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: audioplayers_windows
|
name: audioplayers_windows
|
||||||
sha256: "9536812c9103563644ada2ef45ae523806b0745f7a78e89d1b5fb1951de90e1a"
|
sha256: "9536812c9103563644ada2ef45ae523806b0745f7a78e89d1b5fb1951de90e1a"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
basic_intl:
|
basic_intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: basic_intl
|
path: "packages/basic_intl"
|
||||||
sha256: "15ba8447fb069bd80f0b0c74c71faf5dea45874e9566a68e4e30c897ab2b07c4"
|
relative: true
|
||||||
url: "http://175.24.250.68:4000"
|
source: path
|
||||||
source: hosted
|
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.4.0"
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
|
||||||
url: "http://175.24.250.68:4000"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.2"
|
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.19.0"
|
version: "1.19.1"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.6"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.4"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
flutter:
|
flutter:
|
||||||
@@ -139,7 +130,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.0"
|
||||||
flutter_markdown:
|
flutter_markdown:
|
||||||
@@ -147,7 +138,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: flutter_markdown
|
name: flutter_markdown
|
||||||
sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
|
sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.7+1"
|
version: "0.7.7+1"
|
||||||
flutter_tts:
|
flutter_tts:
|
||||||
@@ -155,7 +146,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: flutter_tts
|
name: flutter_tts
|
||||||
sha256: bdf2fc4483e74450dc9fc6fe6a9b6a5663e108d4d0dad3324a22c8e26bf48af4
|
sha256: bdf2fc4483e74450dc9fc6fe6a9b6a5663e108d4d0dad3324a22c8e26bf48af4
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.3"
|
version: "4.2.3"
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
@@ -168,7 +159,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: fluttertoast
|
name: fluttertoast
|
||||||
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.2.12"
|
version: "8.2.12"
|
||||||
http:
|
http:
|
||||||
@@ -176,7 +167,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
|
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0"
|
version: "1.5.0"
|
||||||
http_parser:
|
http_parser:
|
||||||
@@ -184,7 +175,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
js:
|
js:
|
||||||
@@ -192,7 +183,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.7"
|
version: "0.6.7"
|
||||||
lints:
|
lints:
|
||||||
@@ -200,7 +191,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.1"
|
version: "5.1.1"
|
||||||
markdown:
|
markdown:
|
||||||
@@ -208,7 +199,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: markdown
|
name: markdown
|
||||||
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.3.0"
|
version: "7.3.0"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
@@ -216,23 +207,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.16.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: nested
|
name: nested
|
||||||
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
path:
|
path:
|
||||||
@@ -240,7 +231,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
path_provider:
|
path_provider:
|
||||||
@@ -248,31 +239,31 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.5"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
|
sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.17"
|
version: "2.2.18"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.4.2"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
@@ -280,7 +271,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
@@ -288,55 +279,63 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
permission_handler:
|
permission_handler:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: permission_handler
|
name: permission_handler
|
||||||
sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5
|
sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.4.5"
|
version: "12.0.1"
|
||||||
permission_handler_android:
|
permission_handler_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_android
|
name: permission_handler_android
|
||||||
sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47"
|
sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.3.6"
|
version: "13.0.1"
|
||||||
permission_handler_apple:
|
permission_handler_apple:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_apple
|
name: permission_handler_apple
|
||||||
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
|
sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.1.4"
|
version: "9.4.7"
|
||||||
|
permission_handler_html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_html
|
||||||
|
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3+5"
|
||||||
permission_handler_platform_interface:
|
permission_handler_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_platform_interface
|
name: permission_handler_platform_interface
|
||||||
sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
|
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.12.0"
|
version: "4.3.0"
|
||||||
permission_handler_windows:
|
permission_handler_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_windows
|
name: permission_handler_windows
|
||||||
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
|
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.2.1"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.6"
|
version: "3.1.6"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
@@ -344,81 +343,81 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84"
|
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.5"
|
version: "6.1.5+1"
|
||||||
record:
|
record:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: record
|
name: record
|
||||||
sha256: daeb3f9b3fea9797094433fe6e49a879d8e4ca4207740bc6dc7e4a58764f0817
|
sha256: "9dbc6ff3e784612f90a9b001373c45ff76b7a08abd2bd9fdf72c242320c8911c"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0"
|
version: "6.1.1"
|
||||||
record_android:
|
record_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_android
|
name: record_android
|
||||||
sha256: "97d7122455f30de89a01c6c244c839085be6b12abca251fc0e78f67fed73628b"
|
sha256: "8361a791c9a3fa5c065f0b8b5adb10f12531f8538c86b19474cf7b56ea80d426"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.4.1"
|
||||||
record_ios:
|
record_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_ios
|
name: record_ios
|
||||||
sha256: "73706ebbece6150654c9d6f57897cf9b622c581148304132ba85dba15df0fdfb"
|
sha256: "13e241ed9cbc220534a40ae6b66222e21288db364d96dd66fb762ebd3cb77c71"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.1.2"
|
||||||
record_linux:
|
record_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_linux
|
name: record_linux
|
||||||
sha256: "0626678a092c75ce6af1e32fe7fd1dea709b92d308bc8e3b6d6348e2430beb95"
|
sha256: "235b1f1fb84e810f8149cc0c2c731d7d697f8d1c333b32cb820c449bf7bb72d8"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.2.1"
|
||||||
record_macos:
|
record_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_macos
|
name: record_macos
|
||||||
sha256: "02240833fde16c33fcf2c589f3e08d4394b704761b4a3bb609d872ff3043fbbd"
|
sha256: "2849068bb59072f300ad63ed146e543d66afaef8263edba4de4834fc7c8d4d35"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.1.1"
|
||||||
record_platform_interface:
|
record_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_platform_interface
|
name: record_platform_interface
|
||||||
sha256: c1ad38f51e4af88a085b3e792a22c685cb3e7c23fc37aa7ce44c4cf18f25fe89
|
sha256: b0065fdf1ec28f5a634d676724d388a77e43ce7646fb049949f58c69f3fcb4ed
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.4.0"
|
||||||
record_web:
|
record_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_web
|
name: record_web
|
||||||
sha256: a12856d0b3dd03d336b4b10d7520a8b3e21649a06a8f95815318feaa8f07adbb
|
sha256: "4f0adf20c9ccafcc02d71111fd91fba1ca7b17a7453902593e5a9b25b74a5c56"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.9"
|
version: "1.2.0"
|
||||||
record_windows:
|
record_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: record_windows
|
name: record_windows
|
||||||
sha256: "85a22fc97f6d73ecd67c8ba5f2f472b74ef1d906f795b7970f771a0914167e99"
|
sha256: "223258060a1d25c62bae18282c16783f28581ec19401d17e56b5205b9f039d78"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.7"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -429,7 +428,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.1"
|
version: "1.10.1"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
@@ -437,23 +436,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: synchronized
|
name: synchronized
|
||||||
sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225"
|
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.0+3"
|
version: "3.4.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.2"
|
version: "1.2.2"
|
||||||
typed_data:
|
typed_data:
|
||||||
@@ -461,7 +460,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
uuid:
|
uuid:
|
||||||
@@ -469,23 +468,23 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.7"
|
version: "3.0.7"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.2.0"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
@@ -493,9 +492,9 @@ packages:
|
|||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
url: "http://175.24.250.68:4000"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.6.2 <4.0.0"
|
dart: ">=3.8.0 <4.0.0"
|
||||||
flutter: ">=3.27.0"
|
flutter: ">=3.29.0"
|
||||||
|
|||||||
11
pubspec.yaml
@@ -14,10 +14,12 @@ dependencies:
|
|||||||
flutter_markdown: ^0.7.7+1
|
flutter_markdown: ^0.7.7+1
|
||||||
audioplayers: ^5.2.1
|
audioplayers: ^5.2.1
|
||||||
uuid: ^3.0.5
|
uuid: ^3.0.5
|
||||||
permission_handler: ^10.3.0
|
permission_handler: ^12.0.0
|
||||||
provider: ^6.1.5
|
provider: ^6.1.5
|
||||||
flutter_tts: ^4.2.0
|
flutter_tts: ^4.2.0
|
||||||
basic_intl: ^0.2.0
|
# basic_intl: 0.2.0
|
||||||
|
basic_intl:
|
||||||
|
path: packages/basic_intl
|
||||||
# flutter_ingeek_carkey: 1.4.7
|
# flutter_ingeek_carkey: 1.4.7
|
||||||
# app_car:
|
# app_car:
|
||||||
# path: ../app_car
|
# path: ../app_car
|
||||||
@@ -27,6 +29,11 @@ flutter:
|
|||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
assets:
|
assets:
|
||||||
- assets/images/
|
- assets/images/
|
||||||
|
plugin:
|
||||||
|
platforms:
|
||||||
|
android:
|
||||||
|
package: com.example.ai_assistant_plugin
|
||||||
|
pluginClass: AiAssistantPlugin
|
||||||
fonts:
|
fonts:
|
||||||
- family: VWHead_Bold
|
- family: VWHead_Bold
|
||||||
fonts:
|
fonts:
|
||||||
|
|||||||