Was ist der beste Weg, um damit umzugehen? Ich muss es vorziehen, all diese invokeasync und statehaschanged Anrufe zu schreiben. class = "Lang-none hübschprint-override">
Code: Select all
@inject IBluetoothService bluetoothService;
@{
if (isDiscovering)
{
Stop Discovery
}
else
{
Start Discovery
}
}
[list]
@foreach (var device in devices)
{
[*]@device
}
[/list]
@code
{
private bool isDiscovering = false;
private ObservableCollection devices = new();
private async Task StartDiscovery()
{
isDiscovering = true;
await bluetoothService.StartDiscovery(OnDeviceDiscovered, OnDiscoveryFinished);
}
private async Task OnDeviceDiscovered(string deviceName)
{
await InvokeAsync(() =>
{
devices.Add(deviceName);
StateHasChanged(); // Have to do this before the UI updates
});
}
private async Task OnDiscoveryFinished()
{
await InvokeAsync(() =>
{
isDiscovering = false;
StateHasChanged(); // Have to do this before the UI updates
});
}
private void StopDiscovery()
{
isDiscovering = false;
}
}
Code: Select all
internal class BluetoothService : IBluetoothService
{
private readonly BluetoothAdapter? bluetoothAdapter = BluetoothAdapter.DefaultAdapter;
private readonly global::Android.Content.Context context;
CustomCode.BluetoothReceiver? bluetoothReceiver = new();
public bool IsDiscovering { get; private set; }
public BluetoothService()
{
context = global::Microsoft.Maui.ApplicationModel.Platform.CurrentActivity
?? global::Microsoft.Maui.MauiApplication.Context;
if (bluetoothAdapter == null || !bluetoothAdapter.IsEnabled)
throw new Exception("Bluetooth not available/enabled");
bluetoothReceiver = new BluetoothReceiver();
bluetoothReceiver.DiscoveryStarted += BluetoothReceiver_DiscoveryStarted;
bluetoothReceiver.DiscoveryFinished += BluetoothReceiver_DiscoveryFinished;
bluetoothReceiver.DeviceFound += BluetoothReceiver_DeviceFound;
foreach (var action in new[] { BluetoothDevice.ActionFound, BluetoothAdapter.ActionDiscoveryStarted, BluetoothAdapter.ActionDiscoveryFinished, BluetoothDevice.ActionBondStateChanged })
context.RegisterReceiver(bluetoothReceiver, new global::Android.Content.IntentFilter(action));
}
private Func deviceFound;
private Func discoveryFinished;
public Task StartDiscovery(Func deviceFound, Func discoveryFinished)
{
if (IsDiscovering) throw new InvalidOperationException();
IsDiscovering = true;
this.deviceFound = deviceFound;
this.discoveryFinished = discoveryFinished;
//BluetoothDevices.Clear();
ActivityCompat.RequestPermissions(global::Microsoft.Maui.ApplicationModel.Platform.CurrentActivity!, [
global::Android.Manifest.Permission.Bluetooth,
global::Android.Manifest.Permission.BluetoothAdmin,
global::Android.Manifest.Permission.BluetoothAdvertise,
global::Android.Manifest.Permission.BluetoothConnect,
global::Android.Manifest.Permission.BluetoothPrivileged,
global::Android.Manifest.Permission.BluetoothScan,
global::Android.Manifest.Permission.AccessCoarseLocation,
global::Android.Manifest.Permission.AccessFineLocation,
//"android.hardware.sensor.accelerometer"
], 1);
return Task.CompletedTask;
}
private async void BluetoothReceiver_DeviceFound(object? sender, Platforms.Android.CustomCode.EventArgs.DeviceFoundEventArgs e)
{
if (e.Device?.Name is string name)
await deviceFound(name);
// Binding to this collection, and updating it is pointless
//BluetoothDevices.Add(name);
}
private void BluetoothReceiver_DiscoveryFinished(object? sender, EventArgs e)
{
// Binding to this variable, and updating it is pointless
IsDiscovering = false;
discoveryFinished();
}
private void BluetoothReceiver_DiscoveryStarted(object? sender, EventArgs e) { }
}
Code: Select all
internal class BluetoothReceiver : BroadcastReceiver
{
public override void OnReceive(Context? context, Intent? intent)
{
switch (intent?.Action)
{
case BluetoothDevice.ActionFound:
if (intent.GetParcelableExtra(BluetoothDevice.ExtraDevice) is BluetoothDevice device)
OnDeviceFound(new EventArgs.DeviceFoundEventArgs { Device = device });
break;
case BluetoothAdapter.ActionDiscoveryStarted:
OnDiscoveryStarted(System.EventArgs.Empty);
break;
case BluetoothAdapter.ActionDiscoveryFinished:
OnDiscoveryFinished(System.EventArgs.Empty);
break;
case BluetoothDevice.ActionBondStateChanged:
if (intent.GetParcelableExtra(BluetoothDevice.ExtraDevice) is BluetoothDevice device2)
{
var oldState = (Bond)(int)intent.GetParcelableExtra(BluetoothDevice.ExtraPreviousBondState);
var newState = (Bond)(int)intent.GetParcelableExtra(BluetoothDevice.ExtraBondState);
OnBondStateChanged(new EventArgs.BondStateChangedEventArgs { Device = device2, OldState = oldState, NewState = newState });
}
break;
case BluetoothDevice.ActionUuid:
if (intent.GetParcelableExtra(BluetoothDevice.ExtraUuid) is UUID uuid)
OnUUIDFetched(new EventArgs.UuidFetchedEventArgs { UUID = uuid });
break;
}
}
#region DeviceFound
public event EventHandler DeviceFound;
protected void OnDeviceFound(EventArgs.DeviceFoundEventArgs e)
{
if (DeviceFound != null)
DeviceFound(this, e);
}
#endregion
#region DiscoveryStarted
public event EventHandler? DiscoveryStarted;
protected void OnDiscoveryStarted(System.EventArgs e)
{
if (DiscoveryStarted != null)
DiscoveryStarted(this, e);
}
#endregion
#region DiscoveryFinished
public event EventHandler? DiscoveryFinished;
protected void OnDiscoveryFinished(System.EventArgs e)
{
if (DiscoveryFinished != null)
DiscoveryFinished(this, e);
}
#endregion
#region BondStateChanged
public event EventHandler? BondStateChanged;
protected void OnBondStateChanged(EventArgs.BondStateChangedEventArgs e)
{
if (BondStateChanged != null)
BondStateChanged(this, e);
}
#endregion
#region UuidFetched
public event EventHandler? UuidFetched;
protected void OnUUIDFetched(EventArgs.UuidFetchedEventArgs e)
{
if (UuidFetched != null)
UuidFetched(this, e);
}
#endregion
}
< /code>
Bearbeiten: < /p>
Ich habe versucht, < /p>
zu verwendenMainThread.BeginInvokeOnMainThread(() => BluetoothDevices.Add(name));