Я создаю сервис, который сканирует устройство Bluetooth в фоновом режиме и сохраняет его данные в sqlite. Я не могу получить доступ к контейнеру призмы после перезапуска приложения.
Я создал службу, где я сканирую устройства Bluetooth бесконечно. Теперь я получаю результат в обратном вызове и пытаюсь сохранить данные в sqlite. Я зарегистрировал одноэлементный класс обслуживания «SensorDataService», который сохраняет данные в sqlite. Все работает, когда я запускаю сервис, но через некоторое время или когда я закрываю приложение (в этот момент сервис перезапускается, я думаю), я получаю исключение нулевого указателя при получении экземпляра Sensordataservice из контейнера призмы. Я думаю, что когда приложение закрывается, контейнер призмы уничтожается. Теперь я понятия не имею, как получить доступ к контейнеру призмы из фоновых служб, когда результаты сканирования получены с устройства Bluetooth.
[Service]
public class PodScanningService : Service
{
private IAdapter BleAdapter;
public override IBinder OnBind(Intent intent)
{
return null;
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
Intent receiverIntent = new Intent(this, typeof(MyReceiver));
receiverIntent.SetAction("com.company.ACTION_FOUND");
PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, 1, receiverIntent, PendingIntentFlags.UpdateCurrent);
BluetoothAdapter adapter = BluetoothAdapter.DefaultAdapter;
BluetoothLeScanner bluetoothLeScanner = adapter.BluetoothLeScanner;
ScanFilter filter = GetScanFilter();
List<ScanFilter> scanFilters = new List<ScanFilter>();
scanFilters.Add(filter);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
bluetoothLeScanner.StartScan(scanFilters, getScanSettings(), pendingIntent);
}
else
{
bluetoothLeScanner.StartScan(new MScanCallBack());
}
string CHANNEL_ID = "SAS101";
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelName = "SAS";
var channelDescription = "SAS Experiment Service";
var channel = new NotificationChannel(CHANNEL_ID, channelName, NotificationImportance.Default)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.SetContentTitle("SAS_Experiment")
.SetContentText("Scanning Service Running")
.SetSmallIcon(Resource.Drawable.abc_btn_radio_material)
.SetOngoing(true);
Notification notification = builder.Build();
var SERVICE_RUNNING_NOTIFICATION_ID = 1200;
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
return StartCommandResult.Sticky;
}
private ScanFilter GetScanFilter()
{
ScanFilter.Builder builder = new ScanFilter.Builder();
return builder.Build();
}
private ScanSettings getScanSettings()
{
ScanSettings.Builder builder = new ScanSettings.Builder();
builder.SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency);
return builder.Build();
}
}
public class MScanCallBack : ScanCallback
{
public override void OnScanResult([GeneratedEnum] ScanCallbackType callbackType, Android.Bluetooth.LE.ScanResult result)
{
base.OnScanResult(callbackType, result);
Console.WriteLine("Device Found300:" + "TEST:300");
if (result != null)
{
var bytes = result.ScanRecord.GetBytes();
if (bytes[2] == 0xB0 && bytes[3] == 0xA0)
{
ISensorDataService sensorDataService = App.ContainerResolve<ISensorDataService>();
var idStr = result.Device.Address;
var dataStr = BitConverter.ToString(bytes).Replace("-", "");
var timeStamp = DateTime.UtcNow;
sensorDataService.SaveData(new SensorData()
{
Data = dataStr,
TimeStamp = timeStamp,
RSSI = result.Rssi,
DeviceId = idStr
});
}
}
}
public override void OnScanFailed([GeneratedEnum] ScanFailure errorCode)
{
base.OnScanFailed(errorCode);
}
}
[BroadcastReceiver]
public class MyReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var action = intent.Action;
if (intent.HasExtra(BluetoothLeScanner.ExtraListScanResult))
{
var x = intent.GetParcelableArrayListExtra(BluetoothLeScanner.ExtraListScanResult);
var res = x.Cast<Android.Bluetooth.LE.ScanResult>().ToList();
Console.WriteLine("Device Found400:" + "TEST:");
foreach (var result in res)
{
var bytes = result.ScanRecord.GetBytes();
if (bytes[2] == 0xB0 && bytes[3] == 0xA0)
{
ISensorDataService sensorDataService = App.ContainerResolve<ISensorDataService>(); // This is where the problem is
Console.WriteLine("Device Found:" + result.Device.Address + DateTime.Now);
var idStr = result.Device.Address;
var dataStr = BitConverter.ToString(bytes).Replace("-", "");
var timeStamp = DateTime.UtcNow;
sensorDataService.SaveData(new SensorData()
{
Data = dataStr,
TimeStamp = timeStamp,
RSSI = result.Rssi,
DeviceId = idStr
});
}
}
}
}
}
Я инициализировал синглтон в инициализаторе Android:
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<ISQLiteProvider, SQLiteProvider>();
containerRegistry.RegisterSingleton<ISensorDataService, SensorDataService>();
}
}