Xamarin的.形成蓝牙低能量不一致
本文关键字:能量 不一致 Xamarin | 更新日期: 2023-09-27 18:17:25
我正在构建一个蓝牙低功耗应用程序:https://github.com/xabre/xamarin-bluetooth-le
这个想法是有一个应用程序,将连接到一个外围设备和设置一些属性。(用户数据)。如果在外围设备上有一些例外,我也希望通过中央应用程序进行一些日志记录。
所以我成功地连接到我的外设和按钮点击这个设备,我得到通知在我的中心设备(客户端),如果我以前按下客户端设备上的"开始更新"按钮。
连接成功后,我也可以给Firstname特性写信了。
问题是关于不一致。我关闭了两台设备的Wifi。我用的是Nexus 6P(外设)和一加一(中置)。Xamarin.Forms .
有时(经常)我在连接后得到双重服务。
断开连接时的问题(从不从await返回),经常需要重新启动设备。
连接经常丢失…
这是我的BleServer类:(凌乱)
public class BleServer
{
public class OfflineListener : Java.Lang.Object, IOnClickListener
{
private List<string> objects = new List<string>() { "Itaque his sapiens semper", "Sed tamen est aliquid", "Apparet statim", "habes enim a rhetoribus", "Non quam nostram", "Luxuriam non reprehendit" };
public void OnClick(View v)
{
QueueMessages.QueueMessageHandler.Instance.Enqueue(objects.OrderBy(a => Guid.NewGuid()).First());
}
}
public class MyListener : Java.Lang.Object, IOnClickListener
{
private BluetoothGattCharacteristic _characteristic;
private BluetoothGattServer _bluetoothServer;
private BluetoothDevice _device;
private List<string> objects = new List<string>() { "Itaque his sapiens semper", "Sed tamen est aliquid", "Apparet statim", "habes enim a rhetoribus", "Non quam nostram", "Luxuriam non reprehendit" };
public MyListener(BluetoothGattCharacteristic characteristic, BluetoothGattServer bluetoothServer, BluetoothDevice device)
{
_characteristic = characteristic;
_bluetoothServer = bluetoothServer;
_device = device;
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void OnClick(View v)
{
try
{
if (!QueueMessages.QueueMessageHandler.Instance.IsEmpty())
{
while (!QueueMessages.QueueMessageHandler.Instance.IsEmpty())
{
var message = QueueMessages.QueueMessageHandler.Instance.Dequeue();
_characteristic.SetValue(message);
_bluetoothServer.NotifyCharacteristicChanged(_device, _characteristic, false);
}
}
_characteristic.SetValue(objects.OrderBy(a => Guid.NewGuid()).First());
var ara = _bluetoothServer.NotifyCharacteristicChanged(_device, _characteristic, false);
}
catch(Exception ex)
{
Console.WriteLine("OnClick: {0}", ex.Message);
}
}
}
private readonly BluetoothManager _bluetoothManager;
private BluetoothAdapter _bluetoothAdapter;
private BleGattServerCallback _bluettothServerCallback;
private BluetoothGattServer _bluetoothServer;
private BluetoothGattCharacteristic _characteristic;
private Button _button;
private static UUID Notification_Service_UUID = UUID.FromString("00001811-0000-1000-8000-00805f9b34fb");
private static UUID Notification_NewAlert_UUID = UUID.FromString("00002A46-0000-1000-8000-00805f9b34fb");
//private static UUID Notification_SupportedNewAlert_UUID = UUID.FromString("00002A47-0000-1000-8000-00805f9b34fb");
//private static UUID Notification_SupportedUnreadAlertCategory_UUID = UUID.FromString("00002A48-0000-1000-8000-00805f9b34fb");
//private static UUID Notification_UnreadAlertStatus_UUID = UUID.FromString("00002A45-0000-1000-8000-00805f9b34fb");
//private static UUID Notification_AlertControlPoint_UUID = UUID.FromString("00002A44-0000-1000-8000-00805f9b34fb");
private static UUID UserData_Service_UUID = UUID.FromString("0000181c-0000-1000-8000-00805f9b34fb");
private static UUID UserData_Fname_Level_UUID = UUID.FromString("00002a8a-0000-1000-8000-00805f9b34fb");
private static UUID UserData_Lname_Level_UUID = UUID.FromString("00002A90-0000-1000-8000-00805f9b34fb");
private static UUID UserData_Email_Level_UUID = UUID.FromString("00002A87-0000-1000-8000-00805f9b34fb");
private static UUID UserData_Language_Level_UUID = UUID.FromString("00002AA2-0000-1000-8000-00805f9b34fb");
public BleServer(Activity activity)
{
_button = activity.FindViewById<Button>(Resource.Id.MyButton);
_button.SetOnClickListener(new OfflineListener());
_bluetoothManager = (BluetoothManager)activity.ApplicationContext.GetSystemService(Context.BluetoothService);
_bluetoothAdapter = _bluetoothManager.Adapter;
_bluettothServerCallback = new BleGattServerCallback();
_bluetoothServer = _bluetoothManager.OpenGattServer(activity.ApplicationContext, _bluettothServerCallback);
var service = new BluetoothGattService(Notification_Service_UUID, GattServiceType.Primary);
_characteristic = new BluetoothGattCharacteristic(Notification_NewAlert_UUID, GattProperty.Notify | GattProperty.Write | GattProperty.Read, GattPermission.Read | GattPermission.Write);
service.AddCharacteristic(_characteristic);
_bluetoothServer.AddService(service);
//test UserData
var userDataServie = new BluetoothGattService(UserData_Service_UUID, GattServiceType.Primary);
///
var firstName = new BluetoothGattCharacteristic(UserData_Fname_Level_UUID, GattProperty.Read | GattProperty.Write, GattPermission.Read | GattPermission.Write);
userDataServie.AddCharacteristic(firstName);
_bluetoothServer.AddService(userDataServie);
//
var batteryService = new BluetoothGattService(UUID.FromString("0000180F-0000-1000-8000-00805f9b34fb"), GattServiceType.Primary);
var batteryLevel = new BluetoothGattCharacteristic(UUID.FromString("00002A19-0000-1000-8000-00805f9b34fb"), GattProperty.Read | GattProperty.Notify, GattPermission.Read);
batteryService.AddCharacteristic(batteryLevel);
_bluetoothServer.AddService(batteryService);
_bluettothServerCallback.CharacteristicReadRequest += _bluettothServerCallback_CharacteristicReadRequest;
_bluettothServerCallback.CharacteristicWriteRequest += _bluettothServerCallback_CharacteristicWriteRequest;
_bluettothServerCallback.NotificationSent += _bluettothServerCallback_NotificationSent;
_bluettothServerCallback.ConnectionStateChange += _bluettothServerCallback_ConnectionStateChange;
Console.WriteLine("Server created!");
BluetoothLeAdvertiser myBluetoothLeAdvertiser = _bluetoothAdapter.BluetoothLeAdvertiser;
var builder = new AdvertiseSettings.Builder();
builder.SetAdvertiseMode(AdvertiseMode.LowLatency);
builder.SetConnectable(true);
builder.SetTimeout(0);
builder.SetTxPowerLevel(AdvertiseTx.PowerHigh);
AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
dataBuilder.SetIncludeDeviceName(true);
dataBuilder.SetIncludeTxPowerLevel(true);
myBluetoothLeAdvertiser.StartAdvertising(builder.Build(), dataBuilder.Build(), new BleAdvertiseCallback());
}
void _bluettothServerCallback_NotificationSent(object sender, BleEventArgs e)
{
Debug.WriteLine("NotificationSent to: " + e.Device);
}
void _bluettothServerCallback_CharacteristicReadRequest(object sender, BleEventArgs e)
{
_bluetoothServer.SendResponse(e.Device, e.RequestId, GattStatus.Success, e.Offset, e.Characteristic.GetValue());
return;
}
void _bluettothServerCallback_CharacteristicWriteRequest(object sender, BleEventArgs e)
{
e.Characteristic.SetValue(e.Value);
_bluetoothServer.SendResponse(e.Device, e.RequestId, e.GattStatus, e.Offset, e.Characteristic.GetValue());
return;
}
void _bluettothServerCallback_ConnectionStateChange(object sender, BleEventArgs e)
{
if(e.ProfileNewState == ProfileState.Connected || e.ProfileNewState == ProfileState.Connecting)
{
_button.SetOnClickListener(new MyListener(_characteristic, _bluetoothServer, e.Device));
}
else
{
_button.SetOnClickListener(new OfflineListener());
}
}
}
public class BleAdvertiseCallback : AdvertiseCallback
{
public override void OnStartFailure(AdvertiseFailure errorCode)
{
Console.WriteLine("Adevertise start failure {0}", errorCode);
base.OnStartFailure(errorCode);
}
public override void OnStartSuccess(AdvertiseSettings settingsInEffect)
{
Console.WriteLine("Adevertise start success {0}", settingsInEffect.Mode);
base.OnStartSuccess(settingsInEffect);
}
}
AndroidManifest on android project(central)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="prop.Mobile.Explorer.Droid"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="23" />
<application android:label="Microprop" android:icon="@drawable/icon" android:theme="@style/MyTheme"></application>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
</manifest>
我做了一些阅读,BLE通常被认为是令人讨厌的东西。
<标题> 总结Xamarin的。表单应用程序在不同的智能手机上运行。这个应用程序将连接到不同的外围设备实例。当拥有中心应用程序的人连接到一个外围设备时,他的名字(userdata设置)应该写入外围设备。
如果有什么错误,即异常,这应该排队并记录到中央应用程序,然后再到云。
<标题>- 这是正确的前进方向吗?
- 当写用户名数据时,我应该使用UserData和Firstname的特征吗?(1) ? attributeXmlFile = org.bluetooth.service.user_data.xml
- 对于日志功能,我将使用警报通知服务,这是正确的吗?(1) ? attributeXmlFile = org.bluetooth.service.alert_notification.xml 我在一些文章中看到了信标,我应该调查一下吗?为什么我有这个问题?(请给出你希望看到的代码示例)
(1) bluetooth.com/specifications/gatt/viewer
标题>标题>关于频繁的连接丢失:
尝试改变连接参数,特别是连接监督超时。超时定义了在主服务器将其解释为连接丢失之前,从服务器可以在多长时间内不响应主服务器。如果此值过低,如果从服务器需要很长时间才能应答,将经常发生连接丢失。
有关连接参数的更多信息,请参阅此处:
https://devzone.nordicsemi.com/question/60/what-is-connection-parameters/对于服务的双元,通常是由于以下两种原因之一:要么是外设上的服务注册错误,要么是发现方法有问题。
目前我没有看到你的注册方法有问题,如果有的话,你总是会看到服务副本。所以我认为你的发现方法有问题。也许您不小心查询了句柄区域(从而查询了服务)两次?如果没有看到相应的方法(发送发现请求和接收发现响应),很难说。
一个好的方法是记录所有的发现请求和响应,并检查请求了哪些句柄间隔,返回了哪些结果。我们有重复的处理间隔吗?还是在两个不同的句柄区域注册服务?