public void DeviceLeft(WebView view, DeploymentUser deploymentUser) { try { JObject returnObject = new JObject(); returnObject.Add("deploymentUserId", deploymentUser.id); this.ConsoleLog(view, returnObject); view.EvaluateJavascript($"window.onAndroidEvent('DeviceLeft', '{ JsonConvert.SerializeObject(returnObject) }');", null); } catch (Exception e) { Console.WriteLine($"JSONError: { e.ToString() }"); } }
public void RequestData(string deploymentUser) { try { JObject JSONDeploymentUser = JObject.Parse(deploymentUser); DeploymentUser _deploymentUser = new DeploymentUser(JSONDeploymentUser); OnRequestData?.Invoke(this, _deploymentUser); } catch (Exception e) { Console.WriteLine($"JSONError: { e.ToString() }"); } }
private async Task ConnectToDevice(DeploymentUser dUser) { DeploymentUser deploymentUser = _deploymentUsers.SingleOrDefault(du => du.device.macAddress == dUser.device.macAddress); // if deploymentUser is found if (deploymentUser != default(DeploymentUser)) { IAxLE device = null; try { await _axLEManager.StopScan(); Console.WriteLine($"CONNECTION: ConnectDevice()"); for (var retry = 0; ; retry++) { try { device = await _axLEManager.ConnectDevice(deploymentUser.device.macAddress); break; } catch (OpenMovement.AxLE.Comms.Exceptions.CommandFailedException e) { Console.WriteLine($"CONNECTION: GATT error, retry {retry}"); Crashes.TrackError(e); if (retry > 10) { throw; } } catch (OpenMovement.AxLE.Comms.Exceptions.ConnectException e) { Console.WriteLine($"CONNECTION: ConnectException error, retry {retry}"); Crashes.TrackError(e); if (retry > 10) { throw; } } } // try auth with known password Console.WriteLine($"CONNECTION: Authenticate()"); bool authSuccess = await device.Authenticate(deploymentUser.device.password); // if fails, reset device if (!authSuccess) { Console.WriteLine($"CONNECTION: ResetPassword()"); await device.ResetPassword(); Console.WriteLine($"CONNECTION: Authenticate()"); await device.Authenticate(device.SerialNumber.Substring(device.SerialNumber.Length - 6)); Console.WriteLine($"CONNECTION: SetPassword()"); await device.SetPassword(deploymentUser.device.password); deploymentUser.device.lastBlockSynced = null; deploymentUser.device.lastRTC = null; deploymentUser.device.lastSyncTime = null; } // buzz device Console.WriteLine($"FLASH AND BUZZ START:{ DateTime.Now }"); //await device.LEDFlash(); await device.VibrateDevice(); Console.WriteLine($"FLASH AND BUZZ END:{ DateTime.Now }"); // HACK: Use this butchered version to skip updating cueing //await ((OpenMovement.AxLE.Comms.AxLEv1_5)device).UpdateDeviceState((uint)(0xffffffff & ~0x0010)); // Don't update cueing status await device.UpdateDeviceState(); // proceed with sync and update deployment user if (device.EpochPeriod != 300) { device.EpochPeriod = 300; // 5 minutes (300 seconds) } if (!deploymentUser.device.lastBlockSynced.HasValue || !deploymentUser.device.lastRTC.HasValue || !deploymentUser.device.lastSyncTime.HasValue) { BlockDetails blockDetails = await device.ReadBlockDetails(); deploymentUser.device.lastBlockSynced = blockDetails.ActiveBlock; deploymentUser.device.lastRTC = blockDetails.Time; deploymentUser.device.lastSyncTime = DateTime.UtcNow; // send off server request to update these details DeviceSyncAttempt _deviceSyncAttempt = new DeviceSyncAttempt { deploymentUserId = deploymentUser.id, batteryLevel = device.Battery, deploymentDeviceId = deploymentUser.device.id, samples = new DeviceSampleRecord[0], lastBlockSynced = (blockDetails.ActiveBlock), lastRTC = blockDetails.Time, lastSyncTime = DateTime.UtcNow, raw = new byte[0][] }; RunOnUiThread(() => { _webViewClient.RecievedData(_webView, _deviceSyncAttempt); }); WriteSyncAttemptToDisk(deploymentUser.deploymentId, deploymentUser.device.macAddress, _deviceSyncAttempt); } else { var start = DateTime.Now; // we have data on the device, sync the data using previous deploymentUser.device... Console.WriteLine($"BLOCK READ START:{ DateTime.Now }"); var blocks = await device.SyncEpochData((UInt16)deploymentUser.device.lastBlockSynced, (UInt32)deploymentUser.device.lastRTC, (DateTimeOffset)deploymentUser.device.lastSyncTime); Console.WriteLine($"BLOCK READ END:{ DateTime.Now }"); var end = DateTime.Now; /* * { * deploymentUserId: 15, * batteryLevel: 15, * deploymentDeviceId: 1, * epochInterval: 60000 * samples: [ * { * steps: 123, * batteryLevel: 15 * recordedOn: 2018-05-31 14:23:01Z4 * } * ], * raw: "RAW BYTES FROM SYNC" * } */ DeviceSampleRecord[] samples = blocks.SelectMany(b => { var deviceSampleRecords = new List <DeviceSampleRecord>(); ulong samplesLength = (ulong)b.Samples.Length; for (ulong i = 0; i < samplesLength; i++) { deviceSampleRecords.Add(new DeviceSampleRecord() { steps = b.Samples[i].Steps, batteryLevel = b.Samples[i].Battery, recordedOn = b.BlockInfo.Timestamp.AddSeconds(i * b.BlockInfo.EpochPeriod) }); } return(deviceSampleRecords); }).ToArray(); var lastBlock = blocks.LastOrDefault(); var lastBlockNumber = lastBlock == default(EpochBlock) ? deploymentUser.device.lastBlockSynced : lastBlock.BlockInfo.BlockNumber; DeviceSyncAttempt _deviceSyncAttempt = new DeviceSyncAttempt { deploymentUserId = deploymentUser.id, batteryLevel = device.Battery, deploymentDeviceId = deploymentUser.device.id, samples = samples, lastBlockSynced = (ushort)lastBlockNumber, lastRTC = device.DeviceTime, lastSyncTime = DateTime.UtcNow, raw = blocks.Select(b => b.Raw).ToArray() }; WriteSyncAttemptToDisk(deploymentUser.deploymentId, deploymentUser.device.macAddress, _deviceSyncAttempt); // save locally // post data off to tablet RunOnUiThread(() => { _webViewClient.RecievedData(_webView, _deviceSyncAttempt); }); } } catch (BlockSyncFailedException e) { // move read head to active block Console.WriteLine("BlockSyncFailedException:" + e.ToString()); Crashes.TrackError(e); RunOnUiThread(() => { _webViewClient.RequestDataFailed(_webView); }); } catch (DeviceNotInRangeException e) { // display not in range Console.WriteLine("DeviceNotInRangeException:" + e.ToString()); Crashes.TrackError(e); RunOnUiThread(() => { _webViewClient.RequestDataFailed(_webView); }); } catch (CommandFailedException e) { // display not in range Console.WriteLine("Command Failed Exception:" + e.ToString()); Crashes.TrackError(e); RunOnUiThread(() => { _webViewClient.RequestDataFailed(_webView); }); } catch (Exception e) { Console.WriteLine("Exception:" + e.ToString()); Crashes.TrackError(e); // restart this process RunOnUiThread(() => { _webViewClient.RequestDataFailed(_webView); }); } finally { if (device != null) { await _axLEManager.DisconnectDevice(device); } //DisableBluetooth(); } } else { Toast.MakeText(ApplicationContext, "Could not connect to your activity tracker", ToastLength.Short).Show(); } }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.activityMain); MobileBarcodeScanner.Initialize(Application); _webView = FindViewById <WebView>(Resource.Id.mainWebview); this.Window.SetFlags(WindowManagerFlags.KeepScreenOn, WindowManagerFlags.KeepScreenOn); AppCenter.Start("APP_CENTER_ID", typeof(Analytics), typeof(Crashes)); try { // set up webview client _webViewClient = new ThinkActiveWebViewClient(); _jsInterface = new ThinkActiveJSInterface(); _webView.Settings.JavaScriptEnabled = true; _webView.AddJavascriptInterface(_jsInterface, "ThinkActiveApplication"); _webView.SetWebViewClient(_webViewClient); _webView.Settings.SetAppCacheEnabled(false); WebView.SetWebContentsDebuggingEnabled(true); // Start Bluetooth _androidBluetoothManager = (BluetoothManager)GetSystemService(Context.BluetoothService); _bluetoothBroadcastReceiver = new BluetoothBroadcastReceiver(); this.RegisterReceiver(_bluetoothBroadcastReceiver, new IntentFilter(BluetoothAdapter.ActionStateChanged)); _deploymentUsers = new List <DeploymentUser>(); // Listen for JSInterface events after page finished loading _webViewClient.PageFinished += (object sender, EventArgs e) => {}; _jsInterface.OnSetDeploymentUsers += (object s, DeploymentUser[] deploymentUsers) => { _deploymentUsers = deploymentUsers; foreach (var macAddress in _observedDevices) { DeploymentUser deploymentUser = _deploymentUsers.SingleOrDefault(du => du.device.macAddress == macAddress); // if deploymentUser is found if (deploymentUser != default(DeploymentUser)) { RunOnUiThread(() => { Console.WriteLine($"CONNECTION: SHOW AVATAR"); _webViewClient.DeviceJoined(_webView, deploymentUser); }); } } }; // QR code scanned, webview is requesting device information from specific device _jsInterface.OnRequestData += async(object s, DeploymentUser deploymentUser) => { RunOnUiThread(() => { _webViewClient.ConsoleLog(_webView, JsonConvert.SerializeObject(deploymentUser)); }); // try to connect to specfic device if (deploymentUser != null) { // update the _deploymentUser list with the latest information DeploymentUser outdatedDeploymentUser = _deploymentUsers.FirstOrDefault(dU => dU.id == deploymentUser.id); if (outdatedDeploymentUser != null) { //var position = _deploymentUsers.IndexOf(outdatedDeploymentUser); //_deploymentUsers[position] = deploymentUser; outdatedDeploymentUser = deploymentUser; } await ConnectToDevice(deploymentUser); } else { RunOnUiThread(() => { Toast.MakeText(ApplicationContext, "User not found", ToastLength.Short).Show(); }); } }; _jsInterface.OnVibrateDevice += async(object s, string macAddress) => { RunOnUiThread(() => { _webViewClient.ConsoleLog(_webView, $"OnVirbateDevice:{ macAddress }"); }); await VibrateDevice(macAddress); }; // attach bluetooth receiver _bluetoothBroadcastReceiver.onStateChanged += async(object bluetoothSender, State state) => { // check bluetooth state is off, restart if off if (state == Android.Bluetooth.State.Off) { // turn back on EnableBluetooth(); } else if (state == Android.Bluetooth.State.On) { await SetupAxLEManager(); } }; _webView.LoadUrl(webViewUrl); _bluetoothToggleTimer = new System.Timers.Timer { Interval = 1000, AutoReset = true }; _bluetoothToggleTimer.Elapsed += (s, e) => { lock (_syncBluetoothToggle) { var now = DateTime.Now; DateTime[] resets = { new DateTime(now.Year, now.Month, now.Day, 7, 00, 0), new DateTime(now.Year, now.Month, now.Day, 12, 30, 0), }; bool disable = false; foreach (var reset in resets) { if (_lastTimeBluetoothToggleChecked != default(DateTime) && now >= reset && _lastTimeBluetoothToggleChecked < reset) { disable = true; } } if (disable) { DisableBluetooth(); } _lastTimeBluetoothToggleChecked = now; } }; _bluetoothToggleTimer.Start(); } catch (Exception e) { Console.WriteLine(e.ToString()); } }
private void StartScanningForQRCode() { var opts = new MobileBarcodeScanningOptions { PossibleFormats = new List <ZXing.BarcodeFormat> { ZXing.BarcodeFormat.QR_CODE }, CameraResolutionSelector = availableResolutions => { return(null); }, AutoRotate = false, TryHarder = false, UseFrontCameraIfAvailable = true, }; _scanFragment.StartScanning(result => { // Null result means scanning was cancelled if (result == null || string.IsNullOrEmpty(result.Text)) { Toast.MakeText(this, "Scanning Cancelled", ToastLength.Long).Show(); return; } // Otherwise, proceed with result try { _scanFragment.PauseAnalysis(); var url = new Uri(result.Text); // if we don't have a command, exit if (url.Segments.Length < 2) { throw new Exception("QR Code not recognised"); } string command = url.Segments[1].Replace("/", ""); switch (command) { case "deploymentUser": // if the command isn't exit and we don't have an id to look for, exit if (url.Segments.Length != 3) { throw new Exception("Invalid QR code"); } int deploymentUserId = Int32.Parse(url.Segments[2]); DeploymentUser deploymentUser = _deploymentUsers.SingleOrDefault(du => du.id == deploymentUserId); if (deploymentUser == null) { throw new Exception("Invalid QR code"); } else { RunOnUiThread(() => { _webViewClient.DeviceScanned(_webView, deploymentUser); }); } break; case "food": if (url.Segments.Length != 3) { throw new Exception("Invalid QR code"); } int foodId = Int32.Parse(url.Segments[2]); // fire off food event RunOnUiThread(() => { _webViewClient.FoodScanned(_webView, foodId); }); break; case "exit": // fire off exit event RunOnUiThread(() => { _webViewClient.ExitTablet(_webView); _webView.LoadUrl("javascript:location.reload(true)"); }); break; default: throw new Exception("QR code command not found"); } } catch (Exception e) { RunOnUiThread(() => { Toast.MakeText(this, "Oops I can't understand that", ToastLength.Long).Show(); }); Crashes.TrackError(e); } _scanFragment.ResumeAnalysis(); }, opts); }
async Task SetupAxLEManager() { if (_axLEManager != null) { await _axLEManager.StopScan(); } if (_bluetoothManager != null) { _bluetoothManager.Dispose(); } _bluetoothManager = new OpenMovement.AxLE.Comms.Bluetooth.Mobile.Android.BluetoothManager(CrossBluetoothLE.Current); _axLEManager = new AxLEManager(_bluetoothManager, 30000); _axLEManager.DeviceFound += (object sender, string macAddress) => { try { //Console.WriteLine($"DeviceFound:{macAddress}"); _observedDevices.Add(macAddress); DeploymentUser deploymentUser = _deploymentUsers.SingleOrDefault(du => du.device.macAddress == macAddress); // if deploymentUser is found if (deploymentUser != default(DeploymentUser)) { RunOnUiThread(() => { Console.WriteLine($"CONNECTION: SHOW AVATAR"); _webViewClient.DeviceJoined(_webView, deploymentUser); }); } } catch (Exception e) { Console.WriteLine("Error:" + e.ToString()); Crashes.TrackError(e); } }; _axLEManager.DeviceLost += (object sender, string macAddress) => { try { _observedDevices.Remove(macAddress); DeploymentUser deploymentUser = _deploymentUsers.SingleOrDefault(du => du.device.macAddress == macAddress); // if deploymentUser is found if (deploymentUser != default(DeploymentUser)) { RunOnUiThread(() => { Console.WriteLine($"CONNECTION: HIDE AVATAR"); _webViewClient.DeviceLeft(_webView, deploymentUser); }); } } catch (Exception e) { Console.WriteLine("Error:" + e.ToString()); Crashes.TrackError(e); } }; _axLEManager.SwitchToHighPowerScan(); _axLEManager.StartScan(); }