Compare commits
	
		
			1 Commits
		
	
	
		
			1.2.0
			...
			foreground
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | c844e21e76 | 
| @@ -6,7 +6,12 @@ | |||||||
|     <uses-permission android:name="android.permission.INTERNET"/> |     <uses-permission android:name="android.permission.INTERNET"/> | ||||||
|     <uses-permission android:name="android.permission.VIBRATE" /> |     <uses-permission android:name="android.permission.VIBRATE" /> | ||||||
|     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> |     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> | ||||||
|  |     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> | ||||||
|  |     <uses-permission android:name="android.permission.WAKE_LOCK"/> | ||||||
|  |     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> | ||||||
|  |     <!-- | ||||||
|     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> |     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> | ||||||
|  |     --> | ||||||
|     <uses-permission android:name="android.permission.WAKE_LOCK"/> |     <uses-permission android:name="android.permission.WAKE_LOCK"/> | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -53,6 +58,17 @@ | |||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </activity> |         </activity> | ||||||
|  |  | ||||||
|  |         <receiver android:name="rekab.app.background_locator.LocatorBroadcastReceiver" | ||||||
|  |             android:enabled="true" | ||||||
|  |             android:exported="true"/> | ||||||
|  |         <service android:name="rekab.app.background_locator.LocatorService" | ||||||
|  |             android:permission="android.permission.BIND_JOB_SERVICE" | ||||||
|  |             android:exported="true"/> | ||||||
|  |         <service android:name="rekab.app.background_locator.IsolateHolderService" | ||||||
|  |             android:permission="android.permission.FOREGROUND_SERVICE" | ||||||
|  |             android:exported="true"/> | ||||||
|  |  | ||||||
|  |         <!--  | ||||||
|         <service |         <service | ||||||
|             android:name="io.flutter.plugins.androidalarmmanager.AlarmService" |             android:name="io.flutter.plugins.androidalarmmanager.AlarmService" | ||||||
|             android:permission="android.permission.BIND_JOB_SERVICE" |             android:permission="android.permission.BIND_JOB_SERVICE" | ||||||
| @@ -67,5 +83,6 @@ | |||||||
|                 <action android:name="android.intent.action.BOOT_COMPLETED"></action> |                 <action android:name="android.intent.action.BOOT_COMPLETED"></action> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </receiver> |         </receiver> | ||||||
|  |     --> | ||||||
|     </application> |     </application> | ||||||
| </manifest> | </manifest> | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
| import 'dart:convert'; | import 'dart:convert'; | ||||||
| import 'dart:async'; | import 'dart:async'; | ||||||
|  | import 'dart:isolate'; | ||||||
|  | import 'dart:ui'; | ||||||
| import 'dart:math' as math; | import 'dart:math' as math; | ||||||
| import 'package:flutter/foundation.dart'; | import 'package:flutter/foundation.dart'; | ||||||
| import 'package:flutter/rendering.dart'; | import 'package:flutter/rendering.dart'; | ||||||
| @@ -23,8 +25,11 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart'; | |||||||
| import 'package:in_app_purchase/in_app_purchase.dart'; | import 'package:in_app_purchase/in_app_purchase.dart'; | ||||||
| import 'plugins/dynamic_multi_column_layout.dart'; | import 'plugins/dynamic_multi_column_layout.dart'; | ||||||
| import 'plugins/spoiler_card.dart'; | import 'plugins/spoiler_card.dart'; | ||||||
| import 'package:workmanager/workmanager.dart' as workManager; | //import 'package:workmanager/workmanager.dart' as workManager; | ||||||
| import 'package:geolocator/geolocator.dart'; | //import 'package:geolocator/geolocator.dart'; | ||||||
|  | import 'package:background_locator/background_locator.dart'; | ||||||
|  | import 'package:background_locator/location_dto.dart'; | ||||||
|  | import 'package:background_locator/location_settings.dart'; | ||||||
| import 'package:battery/battery.dart'; | import 'package:battery/battery.dart'; | ||||||
| import 'package:firebase_crashlytics/firebase_crashlytics.dart'; | import 'package:firebase_crashlytics/firebase_crashlytics.dart'; | ||||||
| import 'package:flutter_webview_plugin/flutter_webview_plugin.dart' as standaloneWebview; | import 'package:flutter_webview_plugin/flutter_webview_plugin.dart' as standaloneWebview; | ||||||
| @@ -214,8 +219,11 @@ class _HAClientAppState extends State<HAClientApp> { | |||||||
|   StreamSubscription _themeChangeSubscription; |   StreamSubscription _themeChangeSubscription; | ||||||
|   AppTheme _currentTheme = AppTheme.defaultTheme; |   AppTheme _currentTheme = AppTheme.defaultTheme; | ||||||
|  |  | ||||||
|  |   ReceivePort port = ReceivePort(); | ||||||
|  |    | ||||||
|   @override |   @override | ||||||
|   void initState() { |   void initState() { | ||||||
|  |  | ||||||
|     InAppPurchaseConnection.enablePendingPurchases(); |     InAppPurchaseConnection.enablePendingPurchases(); | ||||||
|     final Stream purchaseUpdates = |     final Stream purchaseUpdates = | ||||||
|         InAppPurchaseConnection.instance.purchaseUpdatedStream; |         InAppPurchaseConnection.instance.purchaseUpdatedStream; | ||||||
| @@ -228,11 +236,18 @@ class _HAClientAppState extends State<HAClientApp> { | |||||||
|         _currentTheme = event.theme; |         _currentTheme = event.theme; | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|  |     /* | ||||||
|     workManager.Workmanager.initialize( |     workManager.Workmanager.initialize( | ||||||
|       updateDeviceLocationIsolate, |       updateDeviceLocationIsolate, | ||||||
|       isInDebugMode: false |       isInDebugMode: false | ||||||
|     ); |     ); | ||||||
|  |     */ | ||||||
|     super.initState(); |     super.initState(); | ||||||
|  |     IsolateNameServer.registerPortWithName(port.sendPort, LocationManager.isolateName); | ||||||
|  |     port.listen((dynamic data) { | ||||||
|  |       // do something with data | ||||||
|  |     }); | ||||||
|  |     initPlatformState(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void _handlePurchaseUpdates(purchase) { |   void _handlePurchaseUpdates(purchase) { | ||||||
| @@ -253,6 +268,10 @@ class _HAClientAppState extends State<HAClientApp> { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   Future<void> initPlatformState() async { | ||||||
|  |     await BackgroundLocator.initialize(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // This widget is the root of your application. |   // This widget is the root of your application. | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ class LocationManager { | |||||||
|         defaultUpdateIntervalMinutes); |         defaultUpdateIntervalMinutes); | ||||||
|     _isRunning = prefs.getBool("location-enabled") ?? false; |     _isRunning = prefs.getBool("location-enabled") ?? false; | ||||||
|     if (_isRunning) { |     if (_isRunning) { | ||||||
|       await _startLocationService(); |       //await _startLocationService(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -57,6 +57,20 @@ class LocationManager { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   _startLocationService() async { |   _startLocationService() async { | ||||||
|  |     Logger.d('Starting location tracking'); | ||||||
|  |     BackgroundLocator.registerLocationUpdate( | ||||||
|  |         locationCallback, | ||||||
|  |         //optional | ||||||
|  |         androidNotificationCallback: locationNotificationCallback, | ||||||
|  |         settings: LocationSettings( | ||||||
|  |             notificationTitle: "HA Client location tracking", | ||||||
|  |             notificationMsg: "HA Client is updating your device location", | ||||||
|  |             wakeLockTime: 20, | ||||||
|  |             autoStop: false, | ||||||
|  |             interval: 10 | ||||||
|  |         ), | ||||||
|  |     ); | ||||||
|  |     /* | ||||||
|     String webhookId = ConnectionManager().webhookId; |     String webhookId = ConnectionManager().webhookId; | ||||||
|     String httpWebHost = ConnectionManager().httpWebHost; |     String httpWebHost = ConnectionManager().httpWebHost; | ||||||
|     if (webhookId != null && webhookId.isNotEmpty) { |     if (webhookId != null && webhookId.isNotEmpty) { | ||||||
| @@ -100,14 +114,81 @@ class LocationManager { | |||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |     */ | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   _stopLocationService() async { |   _stopLocationService() async { | ||||||
|     Logger.d("Canceling previous schedule if any..."); |     Logger.d('Stopping location tracking'); | ||||||
|     await workManager.Workmanager.cancelAll(); |     IsolateNameServer.removePortNameMapping(isolateName); | ||||||
|  |     BackgroundLocator.unRegisterLocationUpdate(); | ||||||
|  |     /*Logger.d("Canceling previous schedule if any..."); | ||||||
|  |     await workManager.Workmanager.cancelAll();*/ | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static const String isolateName = "HAClientLocatorIsolate"; | ||||||
|  |  | ||||||
|  |   static void locationCallback(LocationDto locationDto) async { | ||||||
|  |     print('[Background location] Got location: $locationDto'); | ||||||
|  |     sendLocationData(locationDto); | ||||||
|  |     final SendPort send = IsolateNameServer.lookupPortByName(isolateName); | ||||||
|  |     send?.send(locationDto); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static Future<void> sendLocationData(LocationDto location) async { | ||||||
|  |     print('[Background location] Loading settings...'); | ||||||
|  |     SharedPreferences prefs = await SharedPreferences.getInstance(); | ||||||
|  |     String domain = prefs.getString('hassio-domain'); | ||||||
|  |     String port = prefs.getString('hassio-port'); | ||||||
|  |     String webhookId = prefs.getString('app-webhook-id'); | ||||||
|  |     String httpWebHost = | ||||||
|  |       "${prefs.getString('hassio-res-protocol')}://$domain:$port"; | ||||||
|  |     if (webhookId != null && webhookId.isNotEmpty) { | ||||||
|  |       String url = "$httpWebHost/api/webhook/$webhookId"; | ||||||
|  |       Map<String, String> headers = {}; | ||||||
|  |       headers["Content-Type"] = "application/json"; | ||||||
|  |       Map data = { | ||||||
|  |         "type": "update_location", | ||||||
|  |         "data": { | ||||||
|  |           "gps": [], | ||||||
|  |           "gps_accuracy": 0, | ||||||
|  |           "battery": 100 | ||||||
|  |         } | ||||||
|  |       }; | ||||||
|  |       try { | ||||||
|  |         if (location.longitude != null && location.latitude != null) { | ||||||
|  |           data["data"]["gps"] = [location.latitude, location.longitude]; | ||||||
|  |           data["data"]["gps_accuracy"] = location.accuracy; | ||||||
|  |           print('[Background location] Sending...'); | ||||||
|  |           try { | ||||||
|  |             http.Response response = await http.post( | ||||||
|  |                 url, | ||||||
|  |                 headers: headers, | ||||||
|  |                 body: json.encode(data) | ||||||
|  |             ); | ||||||
|  |             if (response.statusCode >= 200 && response.statusCode < 300) { | ||||||
|  |               print('[Background location] Success!'); | ||||||
|  |             } else { | ||||||
|  |               print('[Background location] Error sending data: ${response.statusCode}'); | ||||||
|  |             } | ||||||
|  |           } catch(e) { | ||||||
|  |             print('[Background location] Error sending data: $e'); | ||||||
|  |           } | ||||||
|  |         } else { | ||||||
|  |           print('[Background location] Error. Location is null'); | ||||||
|  |         } | ||||||
|  |       } catch (e) { | ||||||
|  |         print('[Background location] Error: $e'); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   static void locationNotificationCallback() { | ||||||
|  |     print('[Background location] User clicked on the notification'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   updateDeviceLocation() async { |   updateDeviceLocation() async { | ||||||
|  |     /* | ||||||
|     try { |     try { | ||||||
|       Logger.d("[Foreground location] Started"); |       Logger.d("[Foreground location] Started"); | ||||||
|       Geolocator geolocator = Geolocator(); |       Geolocator geolocator = Geolocator(); | ||||||
| @@ -150,10 +231,12 @@ class LocationManager { | |||||||
|     } catch (e, stack) { |     } catch (e, stack) { | ||||||
|       Logger.e('Foreground location error: ${e.toSTring()}', stacktrace: stack); |       Logger.e('Foreground location error: ${e.toSTring()}', stacktrace: stack); | ||||||
|     } |     } | ||||||
|  |     */ | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
| void updateDeviceLocationIsolate() { | void updateDeviceLocationIsolate() { | ||||||
|   workManager.Workmanager.executeTask((backgroundTask, data) async { |   workManager.Workmanager.executeTask((backgroundTask, data) async { | ||||||
|     //print("[Background $backgroundTask] Started"); |     //print("[Background $backgroundTask] Started"); | ||||||
| @@ -242,3 +325,4 @@ void updateDeviceLocationIsolate() { | |||||||
|     return true; |     return true; | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  | */ | ||||||
| @@ -53,9 +53,11 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   _switchLocationTrackingState(bool state) async { |   _switchLocationTrackingState(bool state) async { | ||||||
|  |     /* | ||||||
|     if (state) { |     if (state) { | ||||||
|       await LocationManager().updateDeviceLocation(); |       await LocationManager().updateDeviceLocation(); | ||||||
|     } |     } | ||||||
|  |     */ | ||||||
|     await LocationManager().setSettings(_locationTrackingEnabled, _locationInterval); |     await LocationManager().setSettings(_locationTrackingEnabled, _locationInterval); | ||||||
|     setState(() { |     setState(() { | ||||||
|       _wait = false; |       _wait = false; | ||||||
|   | |||||||
| @@ -27,8 +27,9 @@ dependencies: | |||||||
|   flutter_secure_storage: ^3.3.3 |   flutter_secure_storage: ^3.3.3 | ||||||
|   device_info: ^0.4.1+4 |   device_info: ^0.4.1+4 | ||||||
|   flutter_local_notifications: ^1.1.6 |   flutter_local_notifications: ^1.1.6 | ||||||
|   geolocator: ^5.3.1 |   #geolocator: ^5.3.1 | ||||||
|   workmanager: ^0.2.2 |   background_locator: ^1.1.3+1 | ||||||
|  |   #workmanager: ^0.2.2 | ||||||
|   battery: ^1.0.0 |   battery: ^1.0.0 | ||||||
|   firebase_crashlytics: ^0.1.3+3 |   firebase_crashlytics: ^0.1.3+3 | ||||||
|   syncfusion_flutter_core: ^18.1.48 |   syncfusion_flutter_core: ^18.1.48 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user