Bläddra i källkod

PRS MOBILE - refactoring of MainPage, improved error logging, changed to target android 13 + given extra bluetooth permissions required for Android 13

Nick-PRSDigital@bitbucket.org 2 år sedan
förälder
incheckning
3d0b1859f3

+ 13 - 2
prs.mobile/comal.timesheets.Android/MainActivity.cs

@@ -36,7 +36,10 @@ namespace comal.timesheets.Droid
             Manifest.Permission.Bluetooth,
             Manifest.Permission.BluetoothAdmin,
             Manifest.Permission.AccessCoarseLocation,
-            Manifest.Permission.AccessFineLocation
+            Manifest.Permission.AccessFineLocation,
+            Manifest.Permission.BluetoothScan,
+            Manifest.Permission.BluetoothAdvertise,
+            Manifest.Permission.BluetoothConnect
         };
 
         protected override void OnCreate(Bundle savedInstanceState)
@@ -154,7 +157,15 @@ namespace comal.timesheets.Droid
                 const string errorFileName = "Fatal.log";
                 var libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // iOS: Environment.SpecialFolder.Resources
                 var errorFilePath = Path.Combine(libraryPath, errorFileName);
-                var errorMessage = String.Format("Time: {0}\r\nError: Unhandled Exception\r\n{1}",
+
+                var errorMessage = "";
+
+                if (File.Exists(errorFilePath))
+                {
+                    errorMessage = File.ReadAllText(errorFilePath);
+                }
+
+                errorMessage = errorMessage + System.Environment.NewLine +  String.Format("Time: {0}\r\nError: Unhandled Exception\r\n{1}",
                 DateTime.Now, exception.ToString());
                 File.WriteAllText(errorFilePath, errorMessage);
 

+ 4 - 1
prs.mobile/comal.timesheets.Android/Properties/AndroidManifest.xml

@@ -1,12 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="440400" android:versionName="4.40.4" package="au.com.frogsoftware.timesheets.comal_timesheets" android:installLocation="auto">
-	<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
+	<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="33" />
 	<uses-permission android:name="android.permission.INTERNET" />
 	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+	<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
 	<uses-permission android:name="android.permission.BLUETOOTH" />
 	<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+	<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
 	<uses-permission android:name="android.permission.CAMERA" />
 	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
@@ -17,6 +19,7 @@
 	<uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES" />
 	<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
 	<uses-permission android:name="android.permission.CALL_PHONE" />
+	<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
 	<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
 	<application android:resizeableActivity="false">
 		<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyB9ZnKdEpKsbN9cm3K7rNfqeN5fIe_xlJ0" />

+ 1 - 1
prs.mobile/comal.timesheets.Android/comal.timesheets.Android.csproj

@@ -15,7 +15,7 @@
     <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
     <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
     <MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
-    <TargetFrameworkVersion>v11.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v13.0</TargetFrameworkVersion>
     <NuGetPackageImportStamp>
     </NuGetPackageImportStamp>
     <CodePage>65001</CodePage>

+ 34 - 84
prs.mobile/comal.timesheets/Main/MainPage.xaml.cs

@@ -23,14 +23,8 @@ namespace comal.timesheets
     {
         #region Fields
         List<ToolEntry> toolEntries = new List<ToolEntry>();
-        private TimeSheet _timesheet = null;
-        private Employee _employee = null;
-        private CoreTable _jobs = null;
         public bool SettingsChanged { get; private set; }
         bool bUpdatingTimesheet = false;
-        bool firstLoad = true;
-        bool recentlyAskedToUpdate = true;
-        int updateCounter;
         public static ConnectionSettings connectionSettings = null;
         bool midnightTimerOn = false;
         DateTime oneSecondBeforeMidnight = DateTime.Today.AddSeconds(864399);
@@ -39,7 +33,6 @@ namespace comal.timesheets
         bool bSharedDeviceFirstLoad = true;
         bool bSharedDevice = false;
         int NumberOfNotfications = 0;
-        string deviceName = "";
         string matchedDeviceName = "";
         int notCount = 1;
         #endregion
@@ -50,80 +43,52 @@ namespace comal.timesheets
             InitializeComponent();
             try
             {
-                InitEvents();
-
-                InitData();
+                InitItems();
 
                 LoadCacheLists();
 
-                InitToolEntryList();
-
-                InitTimers();
-
-                InitNotificationCentre();
-                                
-                CheckCurrentAssignment();
-
-                NotifyChanges();
-
                 //if (GlobalVariables.EmpID == Guid.Parse("40f6ccd9-5272-4b1a-99bf-de7542205aac"))
                 //RunCustomScript();
             }
-            catch (Exception e)
-            {
-
-            }
-            NavigationPage.SetHasBackButton(this, false);
+            catch (Exception e) { }           
         }
         private void RunCustomScript()
         {
 
         }
 
-
-        private void InitEvents()
+        private void InitItems()
         {
-            App.GPS.OnLocationFound += LocationFound;
-            App.GPS.OnLocationError += LocationError;
-            App.Bluetooth.OnScanFinished += ScanFinished;
-            App.Data.DataChanged += DataChanged;
-            App.Data.DataRefreshed += DataRefreshed;
+            NavigationPage.SetHasBackButton(this, false);
+
+            MainPageUtils.Init();
+
+            InitNotificationCentre();
+
+            MainPageUtils.OnRefreshScreen += () =>
+            {
+                Device.BeginInvokeOnMainThread(() =>
+                {
+                    RefreshScreen();
+                });
+            };
 
             MessagingCenter.Subscribe<App>(this, App.MessageOnResume,
             (o) =>
             {
                 if (!App.GPS.RecentlyLocated)
-                     App.GPS.GetLocation();
-                    RefreshScreen();
+                    App.GPS.GetLocation();
+                RefreshScreen();
             }
             );
-        }
-
-        private void InitData()
-        {
-            GlobalVariables.EmpID = GlobalVariables.GetEmployeeID();
-            GlobalVariables.EmpName = GlobalVariables.GetEmployeeName();
-
-            App.Data.Employee.ID = GlobalVariables.EmpID;
-            App.Data.Employee.Name = GlobalVariables.EmpName;
 
-            _timesheet = App.Data.TimeSheets?.Rows.FirstOrDefault()?.ToObject<TimeSheet>();
-            _employee = App.Data.Employee;
-            _jobs = App.Data.Jobs;
+            InitToolEntryList();
 
-            deviceName = MobileUtils.GetDeviceID();
+            CheckCurrentAssignment();
 
-            firstLoad = false;
+            NotifyChanges();
         }
 
-        private void InitTimers()
-        {
-            Timer t = new Timer(RecentlyAskedToUpdateTimer, null, 600000, 600000); //user is reminded to update when opening screen after timer of 10 minutes
-            updateCounter = 1; //user is forced to update after 3rd reminder
-
-            Timer t1 = new Timer(RecentlyUpdatedTilesTimer, null, 30000, 30000);
-            //bluetooth data is allowed to upload once every minute, notifications refreshing is piggybacked to this too
-        }
 
         private void CheckCurrentAssignment()
         {
@@ -215,7 +180,7 @@ namespace comal.timesheets
             //    ForceLayout();
             //}
 
-            if (!firstLoad)
+            if (!MainPageUtils.firstLoad)
                 RefreshScreen();
 
             Task.Run(async () =>
@@ -229,24 +194,24 @@ namespace comal.timesheets
                 }
                 catch (Exception eLatest)
                 {
-                    if (!recentlyAskedToUpdate)
+                    if (!MainPageUtils.recentlyAskedToUpdate)
                     {
                         Device.BeginInvokeOnMainThread(() =>
                         {
 
                         });
 
-                        recentlyAskedToUpdate = true;
+                        MainPageUtils.recentlyAskedToUpdate = true;
                     }
                     string s = eLatest.Message;
                 }
 
                 if (!isLatest)
                 {
-                    if (!recentlyAskedToUpdate)
+                    if (!MainPageUtils.recentlyAskedToUpdate)
                     {
                         string latestVersionNumber = await MobileUtils.AppVersion.GetLatestVersionNumber();
-                        if (updateCounter < 3)
+                        if (MainPageUtils.updateCounter < 3)
                         {
                             Device.BeginInvokeOnMainThread(async () =>
                             {
@@ -266,7 +231,7 @@ namespace comal.timesheets
 
                             });
                         }
-                        else if (updateCounter >= 3)
+                        else if (MainPageUtils.updateCounter >= 3)
                         {
                             Device.BeginInvokeOnMainThread(() =>
                             {
@@ -277,8 +242,8 @@ namespace comal.timesheets
                             });
                             });
                         }
-                        recentlyAskedToUpdate = true;
-                        updateCounter++;
+                        MainPageUtils.recentlyAskedToUpdate = true;
+                        MainPageUtils.updateCounter++;
                     }
                 }
 
@@ -287,11 +252,6 @@ namespace comal.timesheets
             base.OnAppearing();
         }
 
-        private void RecentlyAskedToUpdateTimer(object o)
-        {
-            recentlyAskedToUpdate = false;
-        }
-
         private void AutoLogoutUser(object o)
         {
             App.LogoutUser();
@@ -351,7 +311,7 @@ namespace comal.timesheets
 
                     homeScreenGrid.RaiseChild(CurrentLocation);
 
-                    firstLoad = false;
+                    MainPageUtils.firstLoad = false;
                     bBusy = false;
                 });
             }
@@ -393,17 +353,7 @@ namespace comal.timesheets
         #region Clock on/off
         private void DataChanged(object sender, Type type, Exception e)
         {
-            //if (bSharedDevice)
-            //    return;
-            Device.BeginInvokeOnMainThread(() =>
-            {
-                if (e != null)
-                {
-                    //DisplayAlert("Connection error with server - double check your connection", e.Message, "OK");
-                }
-                else
-                    RefreshScreen();
-            });
+            RefreshScreen();
         }
 
         private void DataRefreshed()
@@ -1282,7 +1232,7 @@ namespace comal.timesheets
         {
             Task.Run(() =>
             {
-                if (!string.IsNullOrWhiteSpace(deviceName) && deviceName != "unknown")
+                if (!string.IsNullOrWhiteSpace(MainPageUtils.deviceName) && MainPageUtils.deviceName != "unknown")
                 {
                     List<Equipment> companyDevices = new List<Equipment>();
                     CoreTable table = new Client<Equipment>().Query
@@ -1297,9 +1247,9 @@ namespace comal.timesheets
                         foreach (CoreRow row in table.Rows)
                         {
                             List<object> list = row.Values;
-                            if (list[0].ToString().Equals(deviceName))
+                            if (list[0].ToString().Equals(MainPageUtils.deviceName))
                             {
-                                matchedDeviceName = deviceName;
+                                matchedDeviceName = MainPageUtils.deviceName;
                             }
                         }
                     }

+ 222 - 3
prs.mobile/comal.timesheets/Main/MainPageUtils.cs

@@ -18,16 +18,83 @@ using comal.timesheets.Tasks;
 using System.IO;
 using static comal.timesheets.CustomControls.JobShell;
 using static Android.Graphics.Paint;
+using static InABox.Mobile.LocationServices;
 
 namespace comal.timesheets
 {
     public delegate void MainPageNotificationsChanged();
+    public delegate void RefreshScreen();
     public static class MainPageUtils
     {
+        public static event MainPageNotificationsChanged OnMainPageNotificationsChanged;
+        public static event RefreshScreen OnRefreshScreen;
+
         public static Assignment CurrentAssignment = null;
         public static JobShell Job = new JobShell();
         public static int NumberOfNotifications = 0;
-        public static event MainPageNotificationsChanged OnMainPageNotificationsChanged;
+        public static string matchedDeviceName = "";
+        public static string deviceName = "";
+        public static bool bRecentlyUpdatedTiles = false;
+        public static TimeSheet _timesheet = null;
+        public static Employee _employee = null;
+        public static CoreTable _jobs = null;
+        public static bool firstLoad = true;
+        public static bool recentlyAskedToUpdate = true;
+        public static int updateCounter;
+
+        public static void Init()
+        {
+            InitEvents();
+            InitData();
+            InitTimers();
+        }
+        private static void InitEvents()
+        {
+            App.GPS.OnLocationFound += LocationFound;
+            App.GPS.OnLocationError += LocationError;
+            App.Bluetooth.OnScanFinished += ScanFinished;
+            App.Data.DataChanged += (s, t, e) => { OnRefreshScreen?.Invoke(); };
+            App.Data.DataRefreshed += () => { OnRefreshScreen?.Invoke(); };
+        }
+
+        private static void InitData()
+        {
+            GlobalVariables.EmpID = GlobalVariables.GetEmployeeID();
+            GlobalVariables.EmpName = GlobalVariables.GetEmployeeName();
+
+            App.Data.Employee.ID = GlobalVariables.EmpID;
+            App.Data.Employee.Name = GlobalVariables.EmpName;
+
+            _timesheet = App.Data.TimeSheets?.Rows.FirstOrDefault()?.ToObject<TimeSheet>();
+            _employee = App.Data.Employee;
+            _jobs = App.Data.Jobs;
+
+            deviceName = MobileUtils.GetDeviceID();
+
+            firstLoad = false;
+        }
+
+        private static void InitTimers()
+        {
+            Timer t = new Timer(RecentlyAskedToUpdateTimer, null, 600000, 600000); //user is reminded to update when opening screen after timer of 10 minutes
+            updateCounter = 1; //user is forced to update after 3rd reminder
+
+            Timer t1 = new Timer(RecentlyUpdatedTilesTimer, null, 30000, 30000);
+            //bluetooth data is allowed to upload once every minute, notifications refreshing is piggybacked to this too
+        }
+
+        private static void RecentlyAskedToUpdateTimer(object o)
+        {
+            recentlyAskedToUpdate = false;
+        }
+
+        private static void RecentlyUpdatedTilesTimer(object o)
+        {
+            bRecentlyUpdatedTiles = false;
+            App.Data.Refresh(true);
+            SearchForNewNotifications();
+        }
+
         public static Assignment CheckCurrentAssignment()
         {
             Thread.Sleep(5000);
@@ -130,7 +197,7 @@ namespace comal.timesheets
                 return new AddEditTask(ID);
             else if (type == "Comal.Classes.Delivery")
                 return new DeliveryDetails(ID);
-            else 
+            else
                 return null;
         }
 
@@ -160,7 +227,7 @@ namespace comal.timesheets
                         else //new notifications or previous notifications have now been dismissed
                         {
                             NumberOfNotifications = table.Rows.Count();
-                            OnMainPageNotificationsChanged?.Invoke();                          
+                            OnMainPageNotificationsChanged?.Invoke();
                             CheckNotificationsPushed(table);
                         }
                     }
@@ -242,5 +309,157 @@ namespace comal.timesheets
         }
 
         #endregion
+
+        private static void LocationFound(LocationServices sender)
+        {
+            //if (bSharedDevice)
+            //    return;
+            if (App.Bluetooth.RecentlyScanned)
+                UploadTiles();
+
+            try
+            {
+                TimeSheet timesheet = App.Data.TimeSheets?.Rows.FirstOrDefault()?.ToObject<TimeSheet>();
+                if (timesheet != null)
+                {
+                    if (timesheet.StartLocation.Latitude.Equals(0.0F) && timesheet.StartLocation.Longitude.Equals(0.0F))
+                    {
+                        timesheet.StartLocation.Latitude = sender.Latitude;
+                        timesheet.StartLocation.Longitude = sender.Longitude;
+                        timesheet.StartLocation.Timestamp = sender.TimeStamp;
+                        timesheet.Address = sender.Address;
+                        new Client<TimeSheet>().Save(timesheet, "Updating Timesheet with GPS Coordinates", (o, e) => { });
+                    }
+                }
+
+                if (!string.IsNullOrWhiteSpace(matchedDeviceName))
+                {
+                    InABox.Core.Location curlocation = new InABox.Core.Location() { Latitude = App.GPS.Latitude, Longitude = App.GPS.Longitude };
+                    curlocation.Timestamp = DateTime.Now;
+
+                    GPSTrackerLocation gpsTrackerLocation = new GPSTrackerLocation();
+                    gpsTrackerLocation.DeviceID = matchedDeviceName;
+                    gpsTrackerLocation.Location.Timestamp = curlocation.Timestamp;
+                    gpsTrackerLocation.Location = curlocation;
+
+                    new Client<GPSTrackerLocation>().Save(gpsTrackerLocation, "Updated company device location from Timebench");
+                }
+
+                OnRefreshScreen?.Invoke();
+            }
+            catch { }
+
+        }
+
+        private static async void UploadTiles()
+        {
+            try
+            {
+                if (App.GPS.Latitude.Equals(0.0F) && App.GPS.Longitude.Equals(0.0F))
+                    return;
+                if (App.Bluetooth.DetectedBlueToothMACAddresses.Count == 0)
+                    return;
+                if (bRecentlyUpdatedTiles)
+                    return;
+                bRecentlyUpdatedTiles = true;
+                await Task.Run(() =>
+                {
+                    InABox.Core.Location curlocation = new InABox.Core.Location() { Latitude = App.GPS.Latitude, Longitude = App.GPS.Longitude };
+                    curlocation.Timestamp = DateTime.Now;
+                    List<GPSTrackerLocation> trackersToUpdate = new List<GPSTrackerLocation>();
+
+                    foreach (String id in App.Bluetooth.DetectedBlueToothMACAddresses)
+                    {
+                        GPSTracker tracker = GlobalVariables.GPSTrackerCache.Find(x => x.DeviceID.Equals(id));
+                        bool stale = tracker.Location.Timestamp < DateTime.Now.Subtract(new TimeSpan(0, 5, 0));
+                        bool moved = tracker.Location.DistanceTo(curlocation, UnitOfLength.Kilometers) > 0.1;
+                        if (stale || moved)
+                        {
+                            GlobalVariables.GPSTrackerCache.Remove(tracker);
+                            tracker.Location = curlocation;
+                            GlobalVariables.GPSTrackerCache.Add(tracker);
+                            //cache is updated
+
+                            GPSTrackerLocation gpsTrackerLocation = new GPSTrackerLocation();
+                            gpsTrackerLocation.DeviceID = tracker.DeviceID;
+                            gpsTrackerLocation.Location.Timestamp = tracker.Location.Timestamp;
+                            gpsTrackerLocation.Location = curlocation;
+                            trackersToUpdate.Add(gpsTrackerLocation);
+                        }
+                    }
+                    if (trackersToUpdate.Any())
+                    {
+                        if (ClientFactory.UserGuid != Guid.Empty)
+                            new Client<GPSTrackerLocation>().Save(trackersToUpdate, "Updating Bluetooth Device Locations");
+                    }
+                    App.Bluetooth.DetectedBlueToothMACAddresses.Clear();
+                }
+                );
+            }
+            catch (Exception e)
+            {
+
+            }
+
+
+            //if ((master != null) && (master.Location.Timestamp < DateTime.Now.Subtract(new TimeSpan(0, 15, 0))))
+            //{
+            //    GPSTrackerLocation device = new GPSTrackerLocation();
+            //    device.DeviceID = MobileUtils.GetDeviceID();
+            //    device.Location.Latitude = App.GPS.Latitude;
+            //    device.Location.Longitude = App.GPS.Longitude;
+            //    device.Location.Timestamp = DateTime.Now;
+            //    locations.Add(device);
+            //    //device.BatteryLevel = ((double)CrossBattery.Current.RemainingChargePercent);
+            //    //new Client<GPSTrackerLocation>().Save(device, "Updating Device Location"); //, SaveTrackerCallback);
+            //}
+
+            #region OLD
+            //for (int i = 0; i < App.Bluetooth.Devices.Length; i++)
+            //{
+            //    String id = App.Bluetooth.Devices[i];
+            //    int level = App.Bluetooth.BatteryLevels[i];
+            //    var btmaster = trackers.FirstOrDefault(x => x.DeviceID.Equals(id));
+
+            //    if ((btmaster != null) && (!locations.Any(x => x.DeviceID.Equals(btmaster.DeviceID))))
+            //    {
+            //        bool stale = btmaster.Location.Timestamp < DateTime.Now.Subtract(new TimeSpan(0, 15, 0));
+            //        bool moved = btmaster.Location.DistanceTo(curlocation, UnitOfLength.Kilometers) > 0.1;
+            //        if (stale || moved)
+            //        {
+            //            GPSTrackerLocation location = new GPSTrackerLocation();
+            //            location.DeviceID = id;
+            //            location.Location.Latitude = App.GPS.Latitude;
+            //            location.Location.Longitude = App.GPS.Longitude;
+            //            location.Location.Timestamp = DateTime.Now;
+            //            location.BatteryLevel = level;
+            //            locations.Add(location);
+            //        }
+            //    }
+            //    //new Client<GPSTrackerLocation>().Save(location, "Found Kontakt Device"); //, SaveTrackerCallback);
+            //}
+
+            //if (locations.Any())
+            //    new Client<GPSTrackerLocation>().Save(locations, "Updating Bluetooth Device Locations", (o, e) => { });
+            #endregion
+
+        }
+
+        private static void LocationError(LocationServices sebder, Exception error)
+        {
+
+        }
+
+        private static void ScanFinished(Bluetooth sender)
+        {
+            try
+            {
+                OnRefreshScreen?.Invoke();
+
+                if (App.GPS.RecentlyLocated)
+                    UploadTiles();
+            }
+            catch { }
+        }
     }
 }