单独的android进程中的AltBeacon服务 [英] AltBeacon service in separate android process

查看:45
本文介绍了单独的android进程中的AltBeacon服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助.有一个适用于 Xamarin Android 的应用程序.在其中,启动了一个与 AltBeacon 库一起工作的服务.在此服务中,创建了一个线程,其中不断扫描信标.服务作为 StartForeground(...) 启动.该服务应该持续工作,所以决定在一个单独的进程中运行它,因为一段时间后android系统停止分配内存和服务终止.如果您在一个进程中运行应用程序和服务,则一切正常.服务工作,信标被扫描.但是一旦我在一个单独的进程中运行它(使用 Process =: myProcess 属性),扫描不起作用.DidRangeBeaconsInRegion 方法不适用于 IRangeNotifier 实现对象.它根本不起作用,没有例外.简要代码库:

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

推荐答案

可以将 Android Beacon 库设置为在单独的进程中运行.您可以在此处阅读基本配置说明:

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

此多进程设置已通过库版本 2.11 成功测试.但是,版本 2.12 包含大量返工以支持 Android 8,并且我尚未测试版本 2.12+ 的多进程支持,因此请谨慎使用这些版本.最好的办法是使用 2.11 版.

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.

上面链接的说明是为使用标准 Java 或 Kotlin 开发工具集和 Android Studio 或 Gradle 构建的 Android 应用编写的.显然需要进行修改才能使 Xamarin 能够正常工作.由于我不是 Xamarin 专家,因此我很难提供更多帮助.

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.

这篇关于单独的android进程中的AltBeacon服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆