不能在蓝牙上做广告

时间:2018-03-26 22:36:06

标签: xamarin bluetooth

我想在我的Xamarin.Forms应用程序中创建一个Gatt服务器,以便其他设备可以通过蓝牙扫描它。我正在使用这个插件:

https://github.com/aritchie/bluetoothle

这是我创建Gatt服务器和广告数据的代码:

server = CrossBleAdapter.Current.CreateGattServer();
var service = server.AddService(serviceGuid, true);

var characteristic = service.AddCharacteristic(
                characteristicGuid,
                CharacteristicProperties.Read | 
CharacteristicProperties.Write | CharacteristicProperties.WriteNoResponse,
                GattPermissions.Read | GattPermissions.Write
);

var notifyCharacteristic = service.AddCharacteristic
(
    notifyCharacteristicGuid,
    CharacteristicProperties.Indicate | CharacteristicProperties.Notify,
                GattPermissions.Read | GattPermissions.Write
);

IDisposable notifyBroadcast = null;
notifyCharacteristic.WhenDeviceSubscriptionChanged().Subscribe(e =>
{
    var @event = e.IsSubscribed ? "Subscribed" : "Unsubcribed";

    if (notifyBroadcast == null)
    {
        notifyBroadcast = Observable
                        .Interval(TimeSpan.FromSeconds(1))
                        .Where(x =>    notifyCharacteristic.SubscribedDevices.Count > 0)
                        .Subscribe(_ =>
                        {
                            Debug.WriteLine("Sending Broadcast");
                            var dt = DateTime.Now.ToString("g");
                            var bytes = Encoding.UTF8.GetBytes("SendingBroadcast");
                            notifyCharacteristic.Broadcast(bytes);
                        });
                }
            });

            characteristic.WhenReadReceived().Subscribe(x =>
            {
                var write = "HELLO";

            // you must set a reply value
            x.Value = Encoding.UTF8.GetBytes(write);

                x.Status = GattStatus.Success; // you can optionally set a status, but it defaults to Success
        });

            characteristic.WhenWriteReceived().Subscribe(x =>
            {
                var write = Encoding.UTF8.GetString(x.Value, 0, x.Value.Length);
                Debug.WriteLine("in WhenWriteReceived() value: " + write);
            // do something value
        });

            await server.Start(new AdvertisementData
            {
                LocalName = "DariusServer",
                ServiceUuids = new List<Guid>() { serverServiceGuid }
            });

我正在使用此应用程序扫描我的广告数据:

https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp

我无法用它发现我的应用。我不知道我做错了什么?我正在使用真实设备SM-T350平板电脑进行测试

1 个答案:

答案 0 :(得分:1)

我花了无数个小时让这个插件工作,没有运气。但是这个本机代码适用于遇到同样问题的任何人:

private async Task AndroidBluetooth()
{
    try
    {
            await Task.Delay(5000); // just to make sure bluetooth is ready to go, this probably isn't needed, but good for peace of mind during testing

            BluetoothLeAdvertiser advertiser = BluetoothAdapter.DefaultAdapter.BluetoothLeAdvertiser;

            var advertiseBuilder = new AdvertiseSettings.Builder();
            var parameters = advertiseBuilder.SetConnectable(true)
                                             .SetAdvertiseMode(AdvertiseMode.Balanced)
                                             //.SetTimeout(10000)
                                             .SetTxPowerLevel(AdvertiseTx.PowerHigh)
                                             .Build();

            AdvertiseData data = (new AdvertiseData.Builder()).AddServiceUuid(new ParcelUuid(Java.Util.UUID.FromString("your UUID here"))).Build();
            MyAdvertiseCallback callback = new MyAdvertiseCallback();
            advertiser.StartAdvertising(parameters, data, callback);
        }
        catch(Exception e)
        {

        }
    }

    public class MyAdvertiseCallback : AdvertiseCallback
    {
        public override void OnStartFailure([GeneratedEnum] AdvertiseFailure errorCode)
        {
            // put a break point here, in case something goes wrong, you can see why
            base.OnStartFailure(errorCode);
        }

        public override void OnStartSuccess(AdvertiseSettings settingsInEffect)
        {
            base.OnStartSuccess(settingsInEffect);
        }
    }
}

请注意,如果我包含设备名称,它将无效,因为在这种情况下,蓝牙传输对于服务UUID来说太大了(我相信最多31个字节)。