123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- using Android.Bluetooth;
- using Android.Bluetooth.LE;
- using Android.Content;
- using InABox.Core;
- using Microsoft.Maui.ApplicationModel;
- namespace InABox.Avalonia.Platform.Android;
- public class Android_Bluetooth : IBluetooth
- {
- public Logger? Logger { get; set; }
- public CoreObservableCollection<IBluetoothDevice> Devices { get; private set; } = new CoreObservableCollection<IBluetoothDevice>();
-
- private readonly BluetoothLeScanner? _scanner;
- public event EventHandler? Changed;
- public Android_Bluetooth()
- {
- var _manager = Application.Context.GetSystemService(Context.BluetoothService) as BluetoothManager;
- var _adapter = _manager?.Adapter;
- _scanner = _adapter?.BluetoothLeScanner;
-
- Task.Run(() =>
- {
- while (true)
- {
- var stale = Devices.ToArray().Where(x => (x == null) || (x.LastSeen < DateTime.Now.Subtract(new TimeSpan(0, 0, 5))))
- .ToArray();
- if (stale.Any())
- {
- Devices.RemoveRange(stale);
- Changed?.Invoke(this, EventArgs.Empty);
- }
-
- Task.Delay(500);
- }
- });
- }
-
- public static async Task<bool> IsPermitted<TPermission>() where TPermission : Permissions.BasePermission, new()
- {
- try
- {
- PermissionStatus status = await Permissions.CheckStatusAsync<TPermission>();
- if (status == PermissionStatus.Granted)
- return true;
- var request = await Permissions.RequestAsync<TPermission>();
- return request == PermissionStatus.Granted;
- }
- catch (TaskCanceledException ex)
- {
- return false;
- }
- }
- public async Task<bool> IsAvailable()
- {
- if (await IsPermitted<Permissions.Bluetooth>())
- return _scanner != null;
- return false;
- }
- BluetoothScanManager? _callback;
-
- public async Task<bool> StartScanningAsync(Guid configServiceId)
- {
- if (await IsAvailable())
- {
- _callback = new BluetoothScanManager((d) => DoDeviceFound(d, configServiceId), ScanStopped);
- _scanner!.StartScan(_callback);
- return true;
- }
- return false;
- }
- public async Task<bool> StopScanningAsync()
- {
- if (await IsAvailable())
- {
- if (_callback != null)
- {
- _scanner!.StopScan(_callback);
- return true;
- }
- }
- return false;
- }
-
- private void DoDeviceFound(ScanResult device, Guid configServiceId)
- {
- var isTarget = device.ScanRecord?.ServiceUuids?
- .Any(x=>string.Equals(x.ToString(),configServiceId.ToString(), StringComparison.OrdinalIgnoreCase))
- ?? false;
- if (isTarget)
- {
- var abd = Devices.FirstOrDefault(x => x.ID == device.Device?.Address);
- if (abd == null)
- {
- if (isTarget)
- {
- var services = device.ScanRecord?.ServiceUuids?
- .Select(x => Guid.Parse(x.ToString()))
- .Where(x => !x.ToString().ToUpper().EndsWith("-0000-1000-8000-00805F9B34FB") &&
- configServiceId != x)
- .ToArray() ?? [];
- if (services.Any())
- {
- abd = new Android_BluetoothDevice(device, services, DateTime.Now);
- Devices.Add(abd);
- Changed?.Invoke(this, EventArgs.Empty);
- }
- }
- }
- else
- abd.LastSeen = DateTime.Now;
- }
- }
- private void ScanStopped()
- {
- _callback = null;
- }
- public async Task<IConnectedBluetoothDevice?> Connect(IBluetoothDevice device)
- {
- if (device is Android_BluetoothDevice d && d.Scan.Device is BluetoothDevice bd)
- {
- var result = new Android_ConnectedBluetoothDevice(bd);
- if (await result.ConnectAsync())
- {
- await result.DiscoverServicesAsync();
- return result;
- }
- }
- return null;
- }
-
-
- public async Task<bool> Disconnect(IConnectedBluetoothDevice device)
- {
- if (device is Android_ConnectedBluetoothDevice d)
- d.Dispose();
-
- return await Task.FromResult(true);
- }
- }
|