运行后台服务以扫描和保存蓝牙设备中的数据

时间:2019-04-10 00:49:35

标签: android xamarin bluetooth prism

我正在创建一项在后台扫描蓝牙设备并将其数据保存在sqlite中的服务。应用重新启动后,我无法访问棱镜容器。

我创建了一个服务,可以无限期地扫描蓝牙设备。现在,我在回调中得到结果,并尝试将数据保存在sqlite中。我已经注册了一个单例服务类“ SensorDataService”,该类将数据保存在sqlite中。当我启动服务时一切正常,但是过了一段时间或当我关闭应用程序时(我猜这时服务会重新启动),我从棱镜容器获取Sensordataservice实例时得到了空指针异常。当应用关闭时,我想棱镜容器被破坏了。现在我不知道从蓝牙设备获得扫描结果时如何从后台服务访问棱镜容器。

[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>();
    }
}

0 个答案:

没有答案