diff --git a/README.md b/README.md index 105d86c..bb08a53 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,78 @@ -# problem_check_system +# 项目名称:现场问题检查系统 -系统架构为MVVM + 仓库模式 +## 核心功能 -这个应用需要实现以下功能: +本系统旨在为现场工作人员提供一个高效的问题记录与管理平台,支持离线操作和数据同步。 -离线登录系统 +1.1 在线/离线登录 +需求: 用户能够使用用户名和密码进行登录。如果设备曾成功登录过,即使在离线状态下也能进入应用。 -问题数据收集(描述、位置、图片等) +技术实现思路: -本地数据存储 +在线: 登录成功后,从服务器获取用户身份信息和Token。 -有网络时手动上传功能 +离线: 将登录凭证(如Token)安全地存储在本地数据库中,启动时优先检查本地凭证。如果凭证有效,直接进入主界面。 -技术栈 -Flutter SDK +1.2 问题数据离线增删改查 +需求: 用户在离线状态下能完整地创建、编辑、删除和查询问题数据。 -GetX (状态管理、路由管理、依赖注入) +技术实现思路: -SQFlite (本地数据库) +本地数据库: 使用 SQFlite 作为本地数据库。 -Image Picker (图片选择) +数据结构: 设计清晰的数据库表结构,包含问题描述、图片路径、创建时间、状态(如“待上传”)等字段。 -Geolocator (位置信息) +操作: 所有的增删改查操作都直接在本地数据库上进行。 -HTTP/Dio (网络请求) +1.3 问题数据上传/下载 +需求: 在有网络连接时,系统能自动或手动将本地数据同步到服务器,并从服务器下载最新数据。 -# !/bin/bash +技术实现思路: -echo "开始清理..." -flutter clean +上传队列: 在本地数据库中新增一个“待上传”队列。当用户离线进行增删改操作时,将这些操作记录在队列中。 -echo "获取依赖..." -flutter pub get +智能同步: 当网络恢复时,按顺序处理上传队列中的任务。使用统一的 HTTP/Dio 拦截器处理身份验证和错误重试。 -echo "构建APK..." -flutter build apk --release --target-platform android-arm64 +差异化下载: 从服务器下载数据时,只拉取自上次同步以来有更新的数据,避免全量下载。 -echo "构建完成!APK位置:build/app/outputs/flutter-apk/app-release.apk" +2. 系统架构:MVVM + 仓库模式 +此架构能有效分离关注点,提高代码的可测试性和可维护性。 + +模型 (Model): 负责数据管理。定义问题数据的实体类,如 Problem。 + +视图模型 (ViewModel): 作为视图和模型之间的桥梁。 + +负责业务逻辑、状态管理和数据处理。 + +通过 GetX 管理 UI 状态,并与视图进行绑定。 + +使用 GetX 的依赖注入(DI)管理 Repository 实例。 + +视图 (View): 负责 UI 展示。 + +使用 Flutter Widgets 构建界面。 + +通过 GetX 提供的响应式组件(如 Obx),监听 ViewModel 中的状态变化并自动更新 UI。 + +仓库 (Repository): 负责统一数据源(本地数据库和网络)。 + +封装数据访问逻辑,向 ViewModel 提供统一的数据接口。 + +根据网络状态,决定是从 SQFlite 获取数据还是从网络请求。 + +3. 技术栈 +Flutter SDK: 跨平台应用开发框架。 + +GetX: + +状态管理: 轻量高效,用于管理 UI 状态。 + +路由管理: 简化页面跳转。 + +依赖注入: 方便管理和提供单例服务(如 Repository)。 + +SQFlite: 本地数据库,用于离线数据存储。 + +Image Picker: 用于从图库或相机选择图片。 + +HTTP/Dio: 网络请求库。推荐使用 Dio,因为它提供了更强大的拦截器、表单数据处理和错误处理功能。 diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 8bc9705..399687d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,9 +2,9 @@ - + + @@ -16,6 +16,16 @@ android:label="现场问题检查" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> + + + + + + + + + \ No newline at end of file diff --git a/lib/app/bindings/initial_binding.dart b/lib/app/bindings/initial_binding.dart index 54dad48..c4b6468 100644 --- a/lib/app/bindings/initial_binding.dart +++ b/lib/app/bindings/initial_binding.dart @@ -8,6 +8,7 @@ import 'package:problem_check_system/data/repositories/file_repository.dart'; import 'package:problem_check_system/data/repositories/image_repository.dart'; import 'package:problem_check_system/data/repositories/image_repository_impl.dart'; import 'package:problem_check_system/data/repositories/problem_repository.dart'; +import 'package:problem_check_system/data/providers/upgrader_service.dart'; import 'package:uuid/uuid.dart'; class InitialBinding implements Bindings { @@ -19,6 +20,7 @@ class InitialBinding implements Bindings { void _registerCoreServices() { /// 立即注册所有的适配器 + Get.put(UpgraderService()); Get.put(GetStorage(), permanent: true); Get.put(Uuid(), permanent: true); Get.put(HttpProvider()); diff --git a/lib/data/providers/upgrader_service.dart b/lib/data/providers/upgrader_service.dart new file mode 100644 index 0000000..dbbc56d --- /dev/null +++ b/lib/data/providers/upgrader_service.dart @@ -0,0 +1,213 @@ +import 'dart:io'; +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:open_file/open_file.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:permission_handler/permission_handler.dart'; + +class UpgraderService extends GetxService { + final Dio _dio = Dio(); + final String _versionUrl = + 'http://xhota.anxincloud.cn/problem/version.json'; // 您的版本信息 JSON 地址 + + var isUpdateAvailable = false.obs; + var updateInfo = {}.obs; + var downloadProgress = '0'.obs; + var totalSize = '0'.obs; + var isDownloading = false.obs; + + @override + void onInit() { + super.onInit(); + checkForUpdate(); + } + + // 检查更新 + Future checkForUpdate() async { + try { + // 获取当前应用版本信息 + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + String currentVersion = packageInfo.version; + + final response = await _dio.get(_versionUrl); + if (response.statusCode == 200) { + final latestVersion = response.data['version']; + if (latestVersion.compareTo(currentVersion) > 0) { + isUpdateAvailable.value = true; + updateInfo.value = response.data; + showUpdateDialog(); + } + } + } catch (e) { + Get.log('检查更新失败: $e'); + } + } + + // 显示更新提示对话框 + void showUpdateDialog() { + Get.dialog( + AlertDialog( + title: Text('发现新版本'), + content: Text(updateInfo['description'] ?? '有新的更新可用。'), + actions: [ + TextButton(onPressed: () => Get.back(), child: Text('稍后')), + TextButton( + onPressed: () { + Get.back(); + startDownload(); + }, + child: Text('立即更新'), + ), + ], + ), + barrierDismissible: false, + ); + } + + // 开始下载 + Future startDownload() async { + isDownloading.value = true; + showDownloadProgressDialog(); + + try { + Directory? dir = await getExternalStorageDirectory(); + + if (dir == null) { + Get.back(); // 关闭进度对话框 + Get.snackbar('错误', '无法获取外部存储目录。'); + print('错误: getExternalStorageDirectory() 返回 null'); + isDownloading.value = false; + return; // 提前退出 + } + + String savePath = '${dir.path}/app-release.apk'; + print('--- 调试信息 ---'); + print('目标下载路径: $savePath'); + print('--- 调试信息 ---'); + + // 确保父目录存在 + final file = File(savePath); + if (!await file.parent.exists()) { + await file.parent.create(recursive: true); + print('--- 调试信息 ---'); + print('已尝试创建父目录: ${file.parent.path}'); + print('--- 调试信息 ---'); + } + + await _dio.download( + updateInfo['url'], + savePath, + onReceiveProgress: (received, total) { + if (total != -1) { + downloadProgress.value = (received / 1024 / 1024).toStringAsFixed( + 2, + ); + totalSize.value = (total / 1024 / 1024).toStringAsFixed(2); + // 在进度回调中也打印路径,确保一直有效 + // print('下载进度 - 目标路径: $savePath'); + } + }, + options: Options( + receiveTimeout: const Duration(seconds: 30), // 增加超时时间 + sendTimeout: const Duration(seconds: 30), + ), + ); + + isDownloading.value = false; + Get.back(); // 关闭下载进度对话框 + + // 再次验证文件是否存在 + if (await file.exists()) { + final fileSize = await file.length(); + Get.log('文件验证成功!路径: $savePath'); + Get.log('文件大小: ${(fileSize / 1024 / 1024).toStringAsFixed(2)} MB'); + installApk(savePath); + } else { + Get.snackbar('下载失败', '文件下载完毕但未找到,请联系管理员。'); + Get.log('错误:文件下载完毕但未找到!'); + } + } on DioException catch (e) { + // 使用 DioException 捕获更具体的 Dio 错误 + isDownloading.value = false; + Get.back(); + String errorMessage = '下载失败: 网络或服务器问题。'; + if (e.type == DioExceptionType.badResponse) { + errorMessage = '下载失败: 服务器响应错误 (${e.response?.statusCode})'; + Get.log('Dio响应错误: ${e.response?.data}'); + } else if (e.type == DioExceptionType.connectionError) { + errorMessage = '下载失败: 连接错误,请检查网络。'; + } else if (e.type == DioExceptionType.unknown) { + // 可能是文件系统错误、权限错误等 + errorMessage = '下载失败: 未知错误。请检查存储权限或设备空间。'; + Get.log('Dio未知错误: $e'); + } + Get.snackbar('下载失败', errorMessage); + Get.log('下载失败 (DioException): $e'); + } catch (e) { + isDownloading.value = false; + Get.back(); + Get.snackbar('下载失败', '发生未知错误。'); + Get.log('下载失败 (通用异常): $e'); + } + } + + // 显示下载进度对话框 + void showDownloadProgressDialog() { + Get.dialog( + AlertDialog( + title: Text('正在下载更新...'), + content: Obx( + () => Column( + mainAxisSize: MainAxisSize.min, + children: [ + LinearProgressIndicator( + value: totalSize.value == '0' + ? null + : double.parse(downloadProgress.value) / + double.parse(totalSize.value), + ), + SizedBox(height: 16), + Text('${downloadProgress.value} MB / ${totalSize.value} MB'), + ], + ), + ), + ), + barrierDismissible: false, + ); + } + + // 安装 APK + Future installApk(String path) async { + // 检查安装权限 + var status = await Permission.requestInstallPackages.status; + if (status.isGranted) { + // 权限已授予,直接安装 + _openApkFile(path); + } else { + // 权限未授予,发起请求 + // 这会打开系统设置页面,让用户手动授权 + status = await Permission.requestInstallPackages.request(); + if (status.isGranted) { + _openApkFile(path); + } else { + // 如果用户拒绝了权限,给出提示 + Get.snackbar( + '权限被拒绝', + '需要授权才能安装更新。请在系统设置中为本应用开启“安装未知应用”的权限。', + duration: Duration(seconds: 5), + ); + } + } + } + + // 抽离出打开文件的逻辑 + Future _openApkFile(String path) async { + final result = await OpenFile.open(path); + print('OpenFile result: ${result.type}, message: ${result.message}'); + if (result.type != ResultType.done) { + Get.snackbar('安装失败', '无法启动安装程序: ${result.message}'); + } + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 64a0ece..86be7eb 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,9 +7,17 @@ #include "generated_plugin_registrant.h" #include +#include +#include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); file_selector_plugin_register_with_registrar(file_selector_linux_registrar); + g_autoptr(FlPluginRegistrar) open_file_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin"); + open_file_linux_plugin_register_with_registrar(open_file_linux_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 2db3c22..c842924 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,8 @@ list(APPEND FLUTTER_PLUGIN_LIST file_selector_linux + open_file_linux + url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index e2ff0cb..ba06083 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,12 +7,20 @@ import Foundation import connectivity_plus import file_selector_macos +import open_file_mac +import package_info_plus import path_provider_foundation +import shared_preferences_foundation import sqflite_darwin +import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 12d8278..ebc9daf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -169,6 +169,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.0.6" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.2" dart_style: dependency: transitive description: @@ -389,6 +397,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.3.2" + html: + dependency: transitive + description: + name: html + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.15.6" http: dependency: transitive description: @@ -589,6 +605,78 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.5.0" + open_file: + dependency: "direct main" + description: + name: open_file + sha256: d17e2bddf5b278cb2ae18393d0496aa4f162142ba97d1a9e0c30d476adf99c0e + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.5.10" + open_file_android: + dependency: transitive + description: + name: open_file_android + sha256: "58141fcaece2f453a9684509a7275f231ac0e3d6ceb9a5e6de310a7dff9084aa" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.6" + open_file_ios: + dependency: transitive + description: + name: open_file_ios + sha256: "02996f01e5f6863832068e97f8f3a5ef9b613516db6897f373b43b79849e4d07" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.3" + open_file_linux: + dependency: transitive + description: + name: open_file_linux + sha256: d189f799eecbb139c97f8bc7d303f9e720954fa4e0fa1b0b7294767e5f2d7550 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.0.5" + open_file_mac: + dependency: transitive + description: + name: open_file_mac + sha256: "1440b1e37ceb0642208cfeb2c659c6cda27b25187a90635c9d1acb7d0584d324" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.3" + open_file_platform_interface: + dependency: transitive + description: + name: open_file_platform_interface + sha256: "101b424ca359632699a7e1213e83d025722ab668b9fd1412338221bf9b0e5757" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.3" + open_file_web: + dependency: transitive + description: + name: open_file_web + sha256: e3dbc9584856283dcb30aef5720558b90f88036360bd078e494ab80a80130c4f + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.0.4" + open_file_windows: + dependency: transitive + description: + name: open_file_windows + sha256: d26c31ddf935a94a1a3aa43a23f4fff8a5ff4eea395fe7a8cb819cf55431c875 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.0.3" + os_detect: + dependency: transitive + description: + name: os_detect + sha256: "7d87c0dd98c6faf110d5aa498e9a6df02ffce4bb78cc9cfc8ad02929be9bb71f" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.3" package_config: dependency: transitive description: @@ -597,6 +685,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.2.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d + url: "https://pub.flutter-io.cn" + source: hosted + version: "9.0.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.1" path: dependency: "direct main" description: @@ -773,6 +877,62 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.5.0" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.5.3" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.13" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.5.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1" shelf: dependency: transitive description: @@ -946,6 +1106,78 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" + upgrader: + dependency: "direct main" + description: + name: upgrader + sha256: a28de64108db70f77e5eacf8b87c1bdfaf9374ece9cab26f9aeac26ac3403eff + url: "https://pub.flutter-io.cn" + source: hosted + version: "12.1.0" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.3.20" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.3.4" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.3" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.4" uuid: dependency: "direct main" description: @@ -962,6 +1194,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" + version: + dependency: transitive + description: + name: version + sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.2" vm_service: dependency: transitive description: @@ -1002,6 +1242,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.0.3" + win32: + dependency: transitive + description: + name: win32 + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.14.0" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 34137a8..f35899b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: problem_check_system description: "A new Flutter project." publish_to: "none" -version: 0.1.0 +version: 1.0.0 environment: sdk: ^3.8.1 @@ -22,12 +22,15 @@ dependencies: image_picker: ^1.1.2 intl: ^0.20.2 json_annotation: ^4.9.0 + open_file: ^3.5.10 + package_info_plus: ^9.0.0 path: ^1.9.1 path_provider: ^2.1.5 permission_handler: ^12.0.1 pretty_dio_logger: ^1.4.0 sqflite: ^2.4.2 tdesign_flutter: ^0.2.4 + upgrader: ^12.1.0 uuid: ^4.5.1 dev_dependencies: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 84f9bcc..dbf8289 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -9,6 +9,7 @@ #include #include #include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { ConnectivityPlusWindowsPluginRegisterWithRegistrar( @@ -17,4 +18,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FileSelectorWindows")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index bd04dca..c22844a 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST connectivity_plus file_selector_windows permission_handler_windows + url_launcher_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST