Fix build warnings and update android sample

This commit is contained in:
Morten Nielsen 2023-08-04 10:29:27 -07:00
parent 9e84b9eb81
commit b611d6c0a6
4 changed files with 116 additions and 38 deletions

View file

@ -42,13 +42,15 @@ namespace NmeaParser
public class BluetoothDevice : NmeaDevice
{
private static Java.Util.UUID SERIAL_UUID = Java.Util.UUID.FromString("00001101-0000-1000-8000-00805F9B34FB")!;
private Android.Bluetooth.BluetoothDevice m_device;
private readonly Android.Bluetooth.BluetoothDevice m_device;
private BluetoothSocket? m_socket;
private readonly Android.Content.Context? m_context;
/// <summary>
/// Gets a list of bluetooth devices that supports serial communication
/// </summary>
/// <returns>A set of bluetooth devices available that supports serial connections</returns>
[Obsolete("Use GetBluetoothSerialDevices(Context)")]
public static IEnumerable<Android.Bluetooth.BluetoothDevice> GetBluetoothSerialDevices()
{
var adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
@ -59,19 +61,58 @@ namespace NmeaParser
}
}
/// <summary>
/// Gets a list of bluetooth devices that supports serial communication
/// </summary>
/// <param name="context">The Android context</param>
/// <returns>A set of bluetooth devices available that supports serial connections</returns>
public static IEnumerable<Android.Bluetooth.BluetoothDevice> GetBluetoothSerialDevices(Android.Content.Context context)
{
var bluetoothManager = context.GetSystemService(Android.Content.Context.BluetoothService) as BluetoothManager;
var adapter = bluetoothManager?.Adapter;
if (adapter != null && adapter.IsEnabled && adapter.BondedDevices is not null)
{
foreach (var b in adapter.BondedDevices.Where(d => d.GetUuids()?.Any(t => SERIAL_UUID.CompareTo(t.Uuid) == 0) == true))
yield return b;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="BluetoothDevice"/> class.
/// </summary>
/// <param name="device">The Android Bluetooth Device.</param>
[Obsolete("Use BluetoothDevice(BluetoothDevice, Context)")]
public BluetoothDevice(Android.Bluetooth.BluetoothDevice device)
{
m_device = device ?? throw new ArgumentNullException(nameof(device));
}
/// <inheritdoc />
protected override Task<System.IO.Stream> OpenStreamAsync()
/// <summary>
/// Initializes a new instance of the <see cref="BluetoothDevice"/> class.
/// </summary>
/// <param name="device">The Android Bluetooth Device.</param>
/// <param name="context">The Android context</param>
public BluetoothDevice(Android.Bluetooth.BluetoothDevice device, Android.Content.Context context)
{
var adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
m_device = device ?? throw new ArgumentNullException(nameof(device));
m_context = context ?? throw new ArgumentNullException(nameof(context));
}
/// <inheritdoc />
protected override async Task<System.IO.Stream> OpenStreamAsync()
{
BluetoothAdapter? adapter;
if (m_context is not null)
{
var bluetoothManager = m_context.GetSystemService(Android.Content.Context.BluetoothService) as BluetoothManager;
adapter = bluetoothManager?.Adapter;
}
else
{
#pragma warning disable CS0618 // Type or member is obsolete. Only used if deprecated constructor is used
adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
#pragma warning restore CS0618 // Type or member is obsolete
}
if (adapter?.IsEnabled != true)
throw new InvalidOperationException("Bluetooth Adapter not enabled");
var d = adapter.GetRemoteDevice(m_device.Address);
@ -80,11 +121,25 @@ namespace NmeaParser
var socket = d.CreateRfcommSocketToServiceRecord(SERIAL_UUID);
if (socket == null)
throw new InvalidOperationException($"Failed to create socket");
socket.Connect();
try
{
await socket.ConnectAsync();
}
catch (Java.IO.IOException)
{
// This sometimes fails. Use fallback approach to open socket
// Based on https://stackoverflow.com/a/41627149
socket?.Dispose();
var m = d.Class?.GetMethod("createRfcommSocket", new Java.Lang.Class[] { Java.Lang.Integer.Type! })!;
if (m is null)
throw;
socket = (Android.Bluetooth.BluetoothSocket)m.Invoke(d, new Java.Lang.Object[] { 1 })!;
socket.Connect();
}
m_socket = socket;
if (socket.InputStream == null)
throw new InvalidOperationException($"Failed to create socket input stream");
return Task.FromResult<Stream>(socket.InputStream);
return socket.InputStream;
}
/// <inheritdoc />

View file

@ -31,6 +31,7 @@
<Nullable>enable</Nullable>
<PackageIcon>logo.png</PackageIcon>
<PackageIconUrl />
<CheckEolWorkloads>false</CheckEolWorkloads>
</PropertyGroup>
<PropertyGroup Label="PackageValidationSettings">

View file

@ -68,7 +68,11 @@ namespace NmeaParser
stream = new StringStream();
listener = new Listener();
listener.NmeaMessage += (s, e) => stream?.Append(e);
#if MONOANDROID50
bool success = manager.AddNmeaListener(listener);
#else
bool success = manager.AddNmeaListener(listener, null);
#endif
manager.RequestLocationUpdates(LocationManager.GpsProvider, 0, 0f, listener );
return Task.FromResult<Stream>(stream);
}
@ -76,10 +80,13 @@ namespace NmeaParser
/// <inheritdoc />
protected override Task CloseStreamAsync(Stream stream)
{
manager.RemoveUpdates(listener);
manager.RemoveNmeaListener(listener);
listener?.Dispose();
listener = null;
if (listener is not null)
{
manager.RemoveUpdates(listener);
manager.RemoveNmeaListener(listener);
listener.Dispose();
listener = null;
}
stream.Dispose();
return Task.CompletedTask;
}

View file

@ -1,4 +1,5 @@
using Android;
using Android.Bluetooth;
using Android.Content.PM;
using AndroidX.Core.App;
@ -32,15 +33,15 @@ public class MainActivity : Activity
return;
}
foreach (var d in NmeaParser.BluetoothDevice.GetBluetoothSerialDevices())
foreach (var d in NmeaParser.BluetoothDevice.GetBluetoothSerialDevices(ApplicationContext))
{
devices[d.Name + " " + d.Address] = d.Address;
devices[d.Name + " " + d.Address] = d;
}
devicePicker.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerDropDownItem, devices.Keys.ToArray());
devicePicker.SetSelection(0);
}
private Dictionary<string, string?> devices = new Dictionary<string, string?>();
private Dictionary<string, BluetoothDevice?> devices = new Dictionary<string, BluetoothDevice?>();
private void StopButton_Click(object? sender, EventArgs e)
{
@ -100,25 +101,27 @@ public class MainActivity : Activity
{
try
{
status.Text = "Opening bluetooth...";
var adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
var bt = Android.Bluetooth.BluetoothAdapter.DefaultAdapter.GetRemoteDevice(btAddress);
Java.Util.UUID SERIAL_UUID = Java.Util.UUID.FromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for Serial Device Service
socket = bt.CreateRfcommSocketToServiceRecord(SERIAL_UUID);
try
{
await socket.ConnectAsync();
}
catch (Java.IO.IOException)
{
// This sometimes fails. Use fallback approach to open socket
// Based on https://stackoverflow.com/a/41627149
socket?.Dispose();
var m = bt.Class.GetMethod("createRfcommSocket", new Java.Lang.Class[] { Java.Lang.Integer.Type });
socket = (Android.Bluetooth.BluetoothSocket)m.Invoke(bt, new Java.Lang.Object[] { 1 })!;
socket.Connect();
}
listener = new NmeaParser.StreamDevice(socket.InputStream);
listener = new NmeaParser.BluetoothDevice(btAddress, ApplicationContext!);
//status.Text = "Opening bluetooth...";
//var bluetoothManager = ApplicationContext!.GetSystemService(Android.Content.Context.BluetoothService) as Android.Bluetooth.BluetoothManager;
//var adapter = bluetoothManager?.Adapter;
//var bt = adapter.GetRemoteDevice(btAddress);
//Java.Util.UUID SERIAL_UUID = Java.Util.UUID.FromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for Serial Device Service
//socket = bt.CreateRfcommSocketToServiceRecord(SERIAL_UUID);
//try
//{
// await socket.ConnectAsync();
//}
//catch (Java.IO.IOException)
//{
// // This sometimes fails. Use fallback approach to open socket
// // Based on https://stackoverflow.com/a/41627149
// socket?.Dispose();
// var m = bt.Class.GetMethod("createRfcommSocket", new Java.Lang.Class[] { Java.Lang.Integer.Type });
// socket = (Android.Bluetooth.BluetoothSocket)m.Invoke(bt, new Java.Lang.Object[] { 1 })!;
// socket.Connect();
//}
//listener = new NmeaParser.StreamDevice(socket.InputStream);
}
catch (System.Exception ex)
{
@ -132,11 +135,23 @@ public class MainActivity : Activity
{
listener.MessageReceived += Listener_MessageReceived;
status!.Text += "\nOpening device...";
await listener.OpenAsync();
status.Text += "\nConnected!";
startButton.Enabled = !(stopButton.Enabled = true);
monitor = new NmeaParser.Gnss.GnssMonitor(listener);
monitor.LocationChanged += Monitor_LocationChanged;
try
{
await listener.OpenAsync();
status.Text += "\nConnected!";
monitor = new NmeaParser.Gnss.GnssMonitor(listener);
monitor.LocationChanged += Monitor_LocationChanged;
startButton.Enabled = !(stopButton.Enabled = true);
}
catch (Exception ex)
{
status.Text += "\nError opening device:\n" + ex.Message;
startButton.Enabled = true;
stopButton.Enabled = false;
}
finally
{
}
}
else
{