Пытаюсь понять, как можно включить уведомление для функции уровня заряда батареи. Я читал о дескрипторах, но пока не смог понять их использование. Я использую Android как клиент (xamarin) и Windows как сервер. Вот мой код:
Server (BatteryService)
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using GattServicesLibrary.Helpers;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Power;
namespace GattServicesLibrary.Services
{
/// <summary>
/// Class for Battery Services
/// </summary>
public class BatteryService : GenericGattService
{
/// <summary>
/// Name of the service
/// </summary>
public override string Name
{
get
{
return "Battery Service";
}
}
/// <summary>
/// Battery level
/// </summary>
private GenericGattCharacteristic batteryLevel;
/// <summary>
/// Gets or sets the battery level
/// </summary>
public GenericGattCharacteristic BatteryLevel
{
get
{
return batteryLevel;
}
set
{
if (batteryLevel != value)
{
batteryLevel = value;
OnPropertyChanged(new PropertyChangedEventArgs("BatteryLevel"));
}
}
}
/// <summary>
/// Asynchronous initialization
/// </summary>
/// <returns>Initialization Task</returns>
public override async Task Init()
{
await CreateServiceProvider(GattServiceUuids.Battery);
// Preparing the Battery Level characteristics
GattLocalCharacteristicParameters batteryCharacteristicsParameters = PlainReadNotifyParameters;
// Set the user descriptions
batteryCharacteristicsParameters.UserDescription = "Battery Level percentage remaining";
// Add presentation format - 16-bit integer, with exponent 0, the unit is percentage, defined per Bluetooth SIG with Microsoft as descriptor
batteryCharacteristicsParameters.PresentationFormats.Add(
GattPresentationFormat.FromParts(
Convert.ToByte(PresentationFormats.FormatTypes.Unsigned8BitInteger),
PresentationFormats.Exponent,
Convert.ToUInt16(PresentationFormats.Units.Percentage),
Convert.ToByte(PresentationFormats.NamespaceId.BluetoothSigAssignedNumber),
PresentationFormats.Description));
// Create the characteristic for the service
GattLocalCharacteristicResult result =
await ServiceProvider.Service.CreateCharacteristicAsync(
GattCharacteristicUuids.BatteryLevel,
batteryCharacteristicsParameters);
// Grab the characterist object from the service set it to the BatteryLevel property which is of a specfic Characteristic type
GattLocalCharacteristic baseBatteryLevel = null;
GattServicesHelper.GetCharacteristicsFromResult(result, ref baseBatteryLevel);
if (baseBatteryLevel != null)
{
BatteryLevel = new Characteristics.BatteryLevelCharacteristic(baseBatteryLevel, this);
}
}
}
}
Server Characteristi c (BatteryLevelCharacteristi c)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GattServicesLibrary.Helpers;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Power;
using Windows.Storage.Streams;
namespace GattServicesLibrary.Characteristics
{
/// <summary>
/// Implementation of the battery profile
/// </summary>
public class BatteryLevelCharacteristic : GenericGattCharacteristic
{
/// <summary>
/// Access to the battery of this system
/// </summary>
private Battery aggBattery = Battery.AggregateBattery;
/// <summary>
/// Initializes a new instance of the <see cref="BatteryLevelCharacteristic" /> class.
/// </summary>
/// <param name="characteristic">The characteristic that this wraps</param>
public BatteryLevelCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
{
aggBattery.ReportUpdated += AggBattery_ReportUpdated;
UpdateBatteryValue();
}
/// <summary>
/// Callback when the battery level changes
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void AggBattery_ReportUpdated(Battery sender, object args)
{
UpdateBatteryValue();
NotifyValue();
}
/// <summary>
/// Method that updates <see cref="GenericGattCharacteristic.Value"/> with the current battery level
/// </summary>
private void UpdateBatteryValue()
{
// Get report
BatteryReport report = aggBattery.GetReport();
float fullCharge = Convert.ToSingle(report.FullChargeCapacityInMilliwattHours);
float currentCharge = Convert.ToSingle(report.RemainingCapacityInMilliwattHours);
float val = (fullCharge > 0) ? (currentCharge / fullCharge) * 100.0f : 0.0f;
Value = GattHelper.Converters.GattConvert.ToIBuffer((byte)Math.Round(val, 0));
}
}
}
Клиент (Xamarin.Droid)
На моем клиенте я хотел бы знать, как получать уведомления при изменении уровня заряда батареи. Я знаю, что это связано с дескрипторами, но я не знаю, как это сделать
using Android.App;
using Android.Bluetooth;
namespace MyProject.Bluetooth
{
public class GattCallback : BluetoothGattCallback
{
private readonly BluetoothDevice _device;
private readonly BluetoothScanner _scanner;
internal GattCallback(BluetoothDevice device, BluetoothScanner scanner)
{
_device = device;
_scanner = scanner;
_device.ConnectGatt(Application.Context, true, this);
}
public override void OnConnectionStateChange(BluetoothGatt gatt, GattStatus status, ProfileState newState)
{
base.OnConnectionStateChange(gatt, status, newState);
//this.Log("OnConnectionStateChange: " + newState);
switch (newState)
{
case ProfileState.Connected:
gatt.DiscoverServices();
break;
case ProfileState.Disconnected:
_scanner.Disconnect(this, gatt);
break;
}
}
public override void OnServicesDiscovered(BluetoothGatt gatt, GattStatus status)
{
base.OnServicesDiscovered(gatt, status);
//this.Log("OnServicesDiscovered: " + status);
if (status == GattStatus.Success)
_scanner.ConnectionSuccess(this, gatt);
else
_scanner.ConnectionFailed(this);
}
public override void OnCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, GattStatus status)
{
base.OnCharacteristicRead(gatt, characteristic, status);
_scanner.OnCharacteristicUpdated(new DroidBtCharacteristic(characteristic));
}
}
}