using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.Mobile; using InABox.Rpc; using Xamarin.Essentials; using Xamarin.Forms; using Xamarin.Forms.Xaml; [assembly: XamlCompilation(XamlCompilationOptions.Compile)] namespace PRS.Mobile { public enum TransportStatus { BadConfiguration, NoConnection, OK, None } public partial class App : Application { public static string LaunchParameters { get; set; } public static IRpcClientTransport Transport { get; set; } public static TransportStatus ConnectTransport(string[] urls) { if (Transport?.IsConnected() == true) Transport.Disconnect(); Transport = new RpcClientSocketTransport(urls); if (!urls.Any()) return TransportStatus.BadConfiguration; try { Transport.Connect(); } catch (Exception e) { MobileLogging.Log(e); } if (!Transport.IsConnected()) return TransportStatus.NoConnection; ClientFactory.SetClientType(typeof(RpcClient<>), InABox.Core.Platform.TimeBench, MobileUtils.AppVersion.InstalledVersionNumber + App.DeviceString, Transport); // Workaround for bug in RPCSocketServer where lrge uploads (ie photos) // actually crash the server. So to get something working, we'll // fall back to a Rest Client while still maintaining the RPC Transport stuff // var info = new Client().Info(); // if (info.RestPort != 0) // { // var resturl = $"{transport.ServerName()}:{info.RestPort}"; // ClientFactory.SetClientType(typeof(RestClient<>), InABox.Core.Platform.TimeBench, // MobileUtils.AppVersion.InstalledVersionNumber + App.DeviceString, resturl); // } return TransportStatus.OK; } public static Bluetooth Bluetooth { get; } = new Bluetooth() { ScanDelay = new TimeSpan(0, 1, 0) }; public static DataModel Data { get; } = new DataModel(); public static string DeviceString { get { var result = Device.RuntimePlatform.Substring(0, 1).ToUpper(); if (Device.Idiom == TargetIdiom.Phone) result = result.ToLower(); return result; } } public static double GetXamarinWidth() { var mainDisplayInfo = DeviceDisplay.MainDisplayInfo; var width = mainDisplayInfo.Width; return width / mainDisplayInfo.Density; } public static bool IsInForeground { get; set; } = false; // this is set by PINLoginPage if DatabaseSettings.UserID is blank // Effective, this will enable the "back" (-> logout) button on the Main page // if the userid is not set. public static bool IsSharedDevice { get; set; } public const string MessageOnStart = "OnStart"; public const string MessageOnSleep = "OnSleep"; public const string MessageOnResume = "OnResume"; public App() { InitializeComponent(); MobilePage.Host = Data; // https://github.com/Baseflow/XF-Material-Library XF.Material.Forms.Material.Init(this); XF.Material.Forms.Material.Use("Material.Configuration"); MobileUtils.Init(); CoreUtils.RegisterClasses(); ComalUtils.RegisterClasses(); // PINLoginPage is going to be the root navigation page. // If shown, it will rerun the validation process // So we should be able to get to this page from // 1. App Startup => Autologin // 2. SettingsPage.Save() => AutoLogin // 3. Main Window => Always manual login? MainPage = new NavigationPage(new PinLoginPage()); //MainPage = new NavigationPage(new TestRadioList()); } protected override void OnStart() { // Handle when your app starts } protected override void OnSleep() { // Handle when your app sleeps } protected override void OnResume() { // Handle when your app resumes } public static LocationServices GPS { get; } = new LocationServices() { ScanDelay = new TimeSpan(0, 1, 0) }; public static void StartMonitoringGPS() { Task.Run(() => { while (true) { if (IsInForeground) { try { GPS.GetLocation(); } catch (Exception e) { InABox.Mobile.MobileLogging.Log(e,"GPS"); } } Thread.Sleep(TimeSpan.FromSeconds(30)); } }); } public static void StartMonitoringBlueTooth() { Task.Run(() => { while (true) { if (IsInForeground) { try { Bluetooth.ScanForDevices(); } catch (Exception e) { InABox.Mobile.MobileLogging.Log(e,"BT"); } } Thread.Sleep(TimeSpan.FromSeconds(30)); } }); } } }