Приложение не закрывается из-за NotificationListenerService. Как обойти? (Xamarin)
Есть приложение, которое подключается по Ble к самодельному устройству и должно отправлять на него входящие уведомления. Все работает, но из-за NotificationListenerService приложение не останавливается после закрытия и не отключается от устройства (хотя библиотека ble должна делать это сама автоматически). Если не активировать сервис уведомлений, то после закрытие отключение происходит. Можно ли остановить NotificationListenerService, либо же как-то обойти его работу?
NotificationListenerService:
[Service(Label = "Ardulens Notification listener service", Permission =
"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE", Exported =true)]
[IntentFilter(new[] { "android.service.notification.NotificationListenerService" })]
public class NotificationListenerService : Android.Service.Notification.NotificationListenerService, INotificationListenerService
{
static readonly string TAG = "X:" + typeof(NotificationListenerService).Name;
public bool isListenerConnected = false;
public event INotificationListenerService.OnNotifyPostedHundler NotificationPosted;
private static NotificationListenerService current;
public static NotificationListenerService Current
{
get
{
if(current == null)
{
current = new NotificationListenerService();
}
return current;
}
private set => current = value;
}
public override void OnListenerConnected()
{
//base.OnListenerConnected();
isListenerConnected = true;
}
public NotificationListenerService()
{
Current = this;
}
public override void OnCreate()
{
base.OnCreate();
Log.Debug(TAG, "service running!");
if (current == null)
current = this;
}
public override void OnNotificationPosted(StatusBarNotification sbn)
{
if (sbn?.PackageName != "com.android.systemui")
{
NotificationPosted?.Invoke(this, new NotificationEventArgs(sbn));
var text = sbn.Notification.Extras.GetCharSequence(Notification.ExtraText);
var title = sbn.Notification.Extras.GetCharSequence(Notification.ExtraTitle);
//Log.Debug(TAG, "ID :" + sbn.Id + "t" + sbn.Notification.TickerText + "t" + sbn.PackageName);
Debug.WriteLine("\ntext: " + text + " title: " + title + "\n");
}
}
}
public interface INotificationListenerService
{
public delegate void OnNotifyPostedHundler(object sender, NotificationEventArgs e);
public event OnNotifyPostedHundler NotificationPosted;
}
public class NotificationEventArgs
{
public StatusBarNotification Notification { get; }
public NotificationEventArgs(StatusBarNotification notification)
{
Notification = notification;
}
}
BleService:
public class BleService : IBleService
{
private static BleService current;
public static BleService Current
{
get
{
if (current == null)
current = new BleService();
return current;
}
}
private IBluetoothLE ble;
private IAdapter adapter;
private IService service;
private ICharacteristic characteristic;
private static readonly string Service_UUID = "C6FBDD3C-7123-4C9E-86AB-005F1A7EDA01";
private static readonly string Characteristic_UUID = "B88E098B-E464-4B54-B827-79EB2B150A9F";
private static readonly string Descriptor_UUID = "00002902-0000-1000-8000-00805f9b34fb";
public ObservableCollection<IDevice> FoundDevicesList { get; }
public IDevice ConnectedDevice { get; private set; }
public event IBleService.ConnectionStateChangedHundler ConnectionStateChanged;
public event IBleService.ValueUpdatedHundler ValueUpdated;
private int scan_time_out;
public int ScanTimeOut
{
get => scan_time_out;
set
{
if (value > 0)
{
scan_time_out = value;
adapter.ScanTimeout = value;
}
}
}
public bool IsConnected { get; private set; }
public async void ConnectToDevice(string device_id)
{
try
{
if (string.IsNullOrEmpty(device_id))
return;
if (ConnectedDevice == null || ConnectedDevice.State != DeviceState.Connected)
{
await adapter.StopScanningForDevicesAsync();
await adapter.ConnectToKnownDeviceAsync(Guid.Parse(device_id), new ConnectParameters(true, true));
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
public async void ConnectToDevice(IDevice device)
{
try
{
if (device == null)
return;
if (ConnectedDevice == null || ConnectedDevice.State != DeviceState.Connected)
{
await adapter.StopScanningForDevicesAsync();
await adapter.ConnectToDeviceAsync(device, new ConnectParameters(true, true));
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
public async void Disconnect()
{
try
{
await adapter.DisconnectDeviceAsync(ConnectedDevice);
service.Dispose();
service = null;
characteristic = null;
ConnectedDevice.Dispose();
ConnectedDevice = null;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
public async void ScanDevices()
{
try
{
if (!adapter.IsScanning)
{
FoundDevicesList.Clear();
await adapter.StartScanningForDevicesAsync();
}
else
{
await adapter.StopScanningForDevicesAsync();
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
public async void Send(byte[] data)
{
try
{
if (characteristic != null && data != null)
{
await characteristic.WriteAsync(data);
}
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
}
public BleService()
{
ble = CrossBluetoothLE.Current;
adapter = CrossBluetoothLE.Current.Adapter;
ScanTimeOut = 5000;
adapter.ScanTimeout = ScanTimeOut;
FoundDevicesList = new ObservableCollection<IDevice>();
service = null;
characteristic = null;
ConnectedDevice = null;
adapter.DeviceDiscovered += Adapter_DeviceDiscovered;
adapter.DeviceConnected += Adapter_DeviceConnected;
adapter.DeviceConnectionLost += Adapter_DeviceConnectionLost;
adapter.DeviceDisconnected += Adapter_DeviceDisconnected;
}
private void Adapter_DeviceDisconnected(object sender, DeviceEventArgs e)
{
IsConnected = false;
ConnectionStateChanged?.Invoke(sender, e);
}
private void Adapter_DeviceConnectionLost(object sender, DeviceErrorEventArgs e)
{
if (e.Device.State == DeviceState.Disconnected)
{
IsConnected = false;
ConnectionStateChanged?.Invoke(sender, new DeviceEventArgs() { Device = e.Device });
}
}
~BleService()
{
Disconnect();
}
private void Adapter_DeviceDiscovered(object sender, DeviceEventArgs e)
{
FoundDevicesList.Add(e.Device);
}
private void Characteristic_ValueUpdated(object sender, CharacteristicUpdatedEventArgs e)
{
ValueUpdated?.Invoke(sender, e);
}
private async void Adapter_DeviceConnected(object sender, DeviceEventArgs e)
{
try
{
service = await e.Device.GetServiceAsync(Guid.Parse(Service_UUID));
characteristic = await service?.GetCharacteristicAsync(Guid.Parse(Characteristic_UUID));
await characteristic?.GetDescriptorAsync(Guid.Parse(Descriptor_UUID));
ConnectedDevice = e.Device;
Debug.WriteLine(ConnectedDevice.Name);
IsConnected = true;
characteristic.ValueUpdated += Characteristic_ValueUpdated;
await characteristic?.StartUpdatesAsync();
ConnectionStateChanged?.Invoke(sender, e);
}
catch (Exception err)
{
Debug.WriteLine(err.Message);
}
}
}
public interface IBleService
{
delegate void ConnectionStateChangedHundler(object sender, Plugin.BLE.Abstractions.EventArgs.DeviceEventArgs e);
event ConnectionStateChangedHundler ConnectionStateChanged;
delegate void ValueUpdatedHundler(object sender, Plugin.BLE.Abstractions.EventArgs.CharacteristicUpdatedEventArgs e);
event ValueUpdatedHundler ValueUpdated;
int ScanTimeOut { get; set; }
bool IsConnected { get; }
IDevice ConnectedDevice { get; }
void ConnectToDevice(string device_id);
void ConnectToDevice(IDevice device);
void Disconnect();
void ScanDevices();
void Send(byte[] data);
ObservableCollection<IDevice> FoundDevicesList { get; }
}