diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 965383b..488914e 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -30,6 +30,15 @@
+
+
+
@@ -39,6 +48,7 @@
+
diff --git a/android/app/src/main/res/xml/filepaths.xml b/android/app/src/main/res/xml/filepaths.xml
new file mode 100644
index 0000000..774ca56
--- /dev/null
+++ b/android/app/src/main/res/xml/filepaths.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/lib/config/constant.dart b/lib/config/constant.dart
index 7bd69f9..e852b4f 100644
--- a/lib/config/constant.dart
+++ b/lib/config/constant.dart
@@ -45,3 +45,7 @@ const String LOGIN_API = 'https://mp4.ikksgroup.com' + "/authentication/login";
const String PRODUCT_API = 'https://mp4.ikksgroup.com' + "/example/getProduct";
const String SERVLET_API =
'https://mp4.ikksgroup.com' + "/MobilePortal4_external/UploadPhotoServlet";
+
+// https://blogit.q2ii.fr
+// https://mp4.ikksgroup.com
+const String DOMAIN_CHECK_VERSION = 'https://mp4.ikksgroup.com';
diff --git a/lib/network/api_provider.dart b/lib/network/api_provider.dart
index 31bea63..a997956 100644
--- a/lib/network/api_provider.dart
+++ b/lib/network/api_provider.dart
@@ -481,4 +481,24 @@ class ApiProvider {
void close() {
_dio.close();
}
+
+ Future checkAppVersion() async {
+ try {
+ final response = await http
+ .get(Uri.parse(DOMAIN_CHECK_VERSION + '/deploy/mobdr/version.json'));
+ final data = jsonDecode(response.body);
+
+ if (data.containsKey('latest_version')) {
+ if (data['latest_version'] != SharedPrefs().appVersion) {
+ // The versions differ
+ return true;
+ }
+ }
+ } catch (e) {
+ print('Error verifying the version : $e');
+ }
+
+ // If an error has occurred or if the versions are identical
+ return false;
+ }
}
diff --git a/lib/ui/account/tab_account.dart b/lib/ui/account/tab_account.dart
index 3c319df..fae6cf8 100644
--- a/lib/ui/account/tab_account.dart
+++ b/lib/ui/account/tab_account.dart
@@ -11,6 +11,7 @@ import 'package:mobdr/ui/account/settings.dart';
import 'package:mobdr/ui/account/log.dart';
import 'package:mobdr/ui/general/notification.dart';
import 'package:mobdr/ui/reusable/reusable_widget.dart';
+import 'package:mobdr/ui/appstore/updatecheck.dart';
import 'package:flutter/material.dart';
import 'package:mobdr/ui/authentication/signin.dart';
import 'dart:convert';
@@ -78,6 +79,8 @@ class _TabAccountPageState extends State
_reusableWidget.divider1(),
_createListMenu('Show logs', LogPage()),
_reusableWidget.divider1(),
+ _createListMenu('Check version', UpdateCheckPage()),
+ _reusableWidget.divider1(),
Container(
margin: EdgeInsets.fromLTRB(0, 18, 0, 0),
child: GestureDetector(
diff --git a/lib/ui/appstore/updatecheck.dart b/lib/ui/appstore/updatecheck.dart
new file mode 100644
index 0000000..9e4ea75
--- /dev/null
+++ b/lib/ui/appstore/updatecheck.dart
@@ -0,0 +1,175 @@
+import 'dart:convert';
+import 'package:flutter/material.dart';
+import 'package:ota_update/ota_update.dart';
+import 'package:http/http.dart' as http;
+
+import 'package:mobdr/service/shared_prefs.dart';
+import 'package:mobdr/config/constant.dart';
+
+class UpdateCheckPage extends StatefulWidget {
+ @override
+ _UpdateCheckPageState createState() => _UpdateCheckPageState();
+}
+
+class _UpdateCheckPageState extends State {
+ OtaEvent? currentEvent = null;
+
+ String _currentVersion = SharedPrefs().appVersion;
+ String _latestVersion = '';
+ String _releaseDate = '';
+ List _releaseNotes = [];
+ String _downloadLink = '';
+ String _checksum = '';
+
+ @override
+ void initState() {
+ super.initState();
+ _fetchLatestVersion();
+ }
+
+ Future _fetchLatestVersion() async {
+ try {
+ final response = await http
+ .get(Uri.parse(DOMAIN_CHECK_VERSION + '/deploy/mobdr/version.json'));
+ final data = jsonDecode(response.body);
+
+ setState(() {
+ _latestVersion = data['latest_version'];
+ _releaseDate = data['release_date'];
+ _releaseNotes = List.from(data['release_notes']);
+ _downloadLink = data['download_link'];
+ _checksum = data['checksum'];
+ });
+ } catch (e) {
+ print('Error retrieving latest version : $e');
+ }
+ }
+
+ Future _doUpdate() async {
+ try {
+ OtaUpdate()
+ .execute(
+ _downloadLink,
+ // OPTIONAL
+ destinationFilename: 'app_release.apk',
+ //OPTIONAL, ANDROID ONLY - ABILITY TO VALIDATE CHECKSUM OF FILE:
+ sha256checksum: _checksum,
+ )
+ .listen(
+ (OtaEvent event) {
+ setState(() => currentEvent = event);
+ },
+ );
+ } catch (e) {
+ print('Failed to make OTA update. Details: $e');
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Checking for update'),
+ ),
+ body: Center(
+ child: currentEvent == null
+ ? Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ 'Current version : ',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 16,
+ ),
+ ),
+ Text(
+ _currentVersion,
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 22,
+ color: Colors.red,
+ ),
+ ),
+ SizedBox(height: 16),
+ Text(
+ 'Version available : ',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 18,
+ ),
+ ),
+ Text(
+ _latestVersion,
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 24,
+ color: Colors.green,
+ ),
+ ),
+ if (_currentVersion != _latestVersion) ...[
+ SizedBox(height: 16),
+ Text(
+ 'Publication date : $_releaseDate',
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ SizedBox(height: 8),
+ Text(
+ 'Release notes :',
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ for (String note in _releaseNotes) ...[
+ SizedBox(height: 4),
+ Text('- $note'),
+ ],
+ SizedBox(height: 16),
+ ElevatedButton(
+ onPressed: _doUpdate,
+ child: Text(
+ 'Update',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 18,
+ ),
+ ),
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Colors.blue,
+ ),
+ ),
+ ] else ...[
+ SizedBox(height: 32),
+ Text(
+ 'You have the latest version',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 18,
+ ),
+ ),
+ ],
+ ],
+ )
+ : Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ 'OTA status',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 24,
+ ),
+ ),
+ SizedBox(height: 32),
+ Text('${currentEvent!.status}'),
+ SizedBox(height: 16),
+ Text(
+ '${currentEvent!.value}',
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 16,
+ ),
+ )
+ ],
+ )),
+ );
+ }
+}
diff --git a/lib/ui/sync/tab_synchro.dart b/lib/ui/sync/tab_synchro.dart
index 252a931..492b291 100644
--- a/lib/ui/sync/tab_synchro.dart
+++ b/lib/ui/sync/tab_synchro.dart
@@ -7,6 +7,7 @@ import 'package:mobdr/config/global_style.dart';
import 'package:mobdr/main.dart';
import 'package:mobdr/events.dart';
import 'package:mobdr/ui/reusable/reusable_widget.dart';
+import 'package:mobdr/ui/appstore/updatecheck.dart';
import 'package:mobdr/service/shared_prefs.dart';
import 'package:mobdr/network/api_provider.dart';
import 'package:mobdr/db/box_visit_photo.dart';
@@ -71,7 +72,43 @@ class _SynchronizationPageState extends State
_isInternetConnexion = true;
// synchronization start
- startSync();
+ await startSync();
+
+ // Vérifier si une mise à jour est disponible
+ bool isUpdateAvailable = await _apiProvider.checkAppVersion();
+
+ if (isUpdateAvailable) {
+ // Afficher le message de mise à jour
+ showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: Text("New version available"),
+ content: Text(
+ "A new version is available. Would you like to install it?"),
+ actions: [
+ TextButton(
+ child: Text("No"),
+ onPressed: () {
+ Navigator.pop(context); // Closes the dialog box
+ },
+ ),
+ TextButton(
+ child: Text("Yes"),
+ onPressed: () {
+ Navigator.pop(context); // Closes the dialog box
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => UpdateCheckPage()),
+ );
+ },
+ ),
+ ],
+ );
+ },
+ );
+ }
}
}
@@ -200,7 +237,7 @@ class _SynchronizationPageState extends State
}
}
- void startSync() async {
+ Future startSync() async {
// disable navigation bar buttons
eventBus.fire(SynchronizationEvent(true));
diff --git a/macos/Podfile.lock b/macos/Podfile.lock
index c77e049..10e64f5 100644
--- a/macos/Podfile.lock
+++ b/macos/Podfile.lock
@@ -1,4 +1,6 @@
PODS:
+ - audioplayers_darwin (0.0.1):
+ - FlutterMacOS
- connectivity_plus (0.0.1):
- FlutterMacOS
- ReachabilitySwift
@@ -28,13 +30,14 @@ PODS:
- FlutterMacOS
DEPENDENCIES:
+ - audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos`)
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- objectbox_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/objectbox_flutter_libs/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`)
- - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`)
+ - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
+ - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
- wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`)
@@ -45,6 +48,8 @@ SPEC REPOS:
- ReachabilitySwift
EXTERNAL SOURCES:
+ audioplayers_darwin:
+ :path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos
connectivity_plus:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
device_info_plus:
@@ -56,15 +61,16 @@ EXTERNAL SOURCES:
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation:
- :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos
+ :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
shared_preferences_foundation:
- :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos
+ :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sqflite:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
wakelock_macos:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos
SPEC CHECKSUMS:
+ audioplayers_darwin: dcad41de4fbd0099cb3749f7ab3b0cb8f70b810c
connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747
device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
diff --git a/pubspec.lock b/pubspec.lock
index ef81716..5133d87 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -429,10 +429,10 @@ packages:
dependency: transitive
description:
name: ffi
- sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+ sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "2.0.2"
file:
dependency: transitive
description:
@@ -781,6 +781,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
+ ota_update:
+ dependency: "direct main"
+ description:
+ name: ota_update
+ sha256: "7ce0af2119458cb7cc3122ecdc4e18ec3c0108162bfab9a4b064d686e1a5fc22"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.0"
package_config:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 465359b..058fb76 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# 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: 0.0.1+1
+version: 0.2.3+1
environment:
sdk: '>=2.19.0 <3.0.0'
@@ -99,7 +99,7 @@ dependencies:
# https://pub.dev/packages/device_info_plus/
device_info_plus: ^8.2.0
- # https://pwebview_flutterub.dev/packages/webview_flutter/
+ # https://pub.dev/packages/webview_flutter/
# MP4
webview_flutter: ^4.2.1
@@ -121,6 +121,9 @@ dependencies:
# https://pub.dev/packages/permission_handler
permission_handler: 10.3.0
+ # https://pub.dev/packages/ota_update
+ ota_update: ^5.1.0
+
# hhttps://pub.dev/packages/timelines
#timelines: ^0.1.0