AltBeacon service in separate android process

邮差的信 提交于 2019-12-24 09:57:41

问题


I need help. There is an application for Xamarin Android. Inside it, a service is started that works with the AltBeacon library. In this service, a thread is created, in which beacons are constantly being scanned. Service started as StartForeground(...). The service should work constantly, so it was decided to run it in a separate process, because after a while the android system stops allocating memory and service terminates. If you run the application and the service in one process, everything works fine. Service works, beacons are scanned. But as soon as I run it in a separate process (using the Process =: myProcess attribute), the scanning not works. The DidRangeBeaconsInRegion method does not work for the IRangeNotifier implementation object. It simply does not work, there are no exceptions. Brief code base:

public class BeaconsWorker : Java.Lang.Object, IBeaconConsumer
    {
 private string[] guids;



        private readonly Context context;
        private readonly BeaconManager beaconManager;
        private readonly RangeNotifier rangeNotifier;
        private readonly List<BeaconEntry> beacons;



        public Context ApplicationContext
        {
            get { return context.ApplicationContext; }
        }


        public BeaconsWorker(Context context, string[] guids, int scanTime)
        {
            ...
            this.context = context;         
            rangeNotifier = new RangeNotifier();
            beaconManager = BeaconManager.GetInstanceForApplication(context);
            beaconManager.SetForegroundBetweenScanPeriod(1000);
            beaconManager.SetForegroundScanPeriod(1000);
            beaconManager.SetBackgroundMode(false);
            var beaconParser = new BeaconParser();
            beaconParser.SetBeaconLayout("...");
            beaconManager.BeaconParsers.Add(beaconParser);
            rangeNotifier.DidRangeBeaconsInRegionComplete += OnBeaconsRanging;
            beaconManager.SetRangeNotifier(rangeNotifier);


        }


        public bool BindService(Intent intent, IServiceConnection serviceConnection, [GeneratedEnum] Bind flags)
        {
            return context.BindService(intent, serviceConnection, flags);
        }

        public void OnBeaconServiceConnect()
        {

            foreach (var region in beaconManager.RangedRegions.ToList())
                beaconManager.StopRangingBeaconsInRegion(region);

                    for (int i = 0; i < guids.Length; i++)
                    {
                        var uuid = Identifier.Parse(guids[i]);
                        var region = new Region("R" + i, uuid, null, null);
                        beaconManager.StartRangingBeaconsInRegion(region);
                }   

        }

        public void UnbindService(IServiceConnection serviceConnection)
        {
            context.UnbindService(serviceConnection);
        }


        public async Task<BeaconEntry> GetLocationResult()
        {

            beaconManager.Bind(this);
            await Task.Delay(scanTime * 1000);         
            beaconManager.Unbind(this);
            ...

            return result;
        }


        private void OnBeaconsRanging(object sender, RangeEventArgs e)
        {

            lock (beacons)
                foreach (var item in e.Beacons)
                {
                    var beacon = new BeaconEntry()
                    {
                        BeaconGUID = item.Id1.ToString(),
                        BeaconMajor = Int32.Parse(item.Id2.ToString()),
                        BeaconMinor = Int32.Parse(item.Id3.ToString())
                    };

                    beacons.Add(beacon);
                }  
        }


        private class RangeEventArgs : EventArgs
        {
            public Region Region { get; set; }

            public ICollection<Beacon> Beacons { get; set; }
        }

        private class RangeNotifier : Java.Lang.Object, IRangeNotifier
        {
            public event EventHandler<RangeEventArgs> DidRangeBeaconsInRegionComplete;

            public void DidRangeBeaconsInRegion(ICollection<Beacon> beacons, Region region)
            {

                OnDidRangeBeaconsInRegion(beacons, region);
            }

            private void OnDidRangeBeaconsInRegion(ICollection<Beacon> beacons, Region region)
            {                
                DidRangeBeaconsInRegionComplete?.Invoke(this, new RangeEventArgs { Beacons = beacons, Region = region });
            }
        }

回答1:


It is possible to set up the Android Beacon Library to run in a separate process. You can read the basic configuration instructions here:

https://github.com/AltBeacon/android-beacon-library/pull/479

This multi-process setup was successfully tested with library version 2.11. Version 2.12, however, included significant rework to support Android 8, and I have not tested multi-process support with versions 2.12+, so use those versions with caution. Your best bet is to use version 2.11.

The instructions linked above are written for Android apps built using standard Java or Kotlin development toolset with Android Studio or Gradle. Clearly modifications are needed to make this work with Xamarin. Since I am not a Xamarin expert, it's hard for me to help more.



来源:https://stackoverflow.com/questions/48112010/altbeacon-service-in-separate-android-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!