使用 Kontakt.io 个信标在 Android 上找到信标时发送本地通知

send local notification when finding a Beacon on Android using Kontakt.io beacons

我真的需要了解如何启动服务以便扫描信标,即使应用程序在后台运行也是如此,我查看了在 Github 上找到的管理应用程序,但我做不到真正理解它是如何工作的。有没有人有一段简单的代码来告诉我它是如何工作的?

我试过的一个简单的解决方案(在网上找到)如下:

public class BeaconRangingService extends Service {

        private static final String TAG = BeaconRangingService.class.getSimpleName();
        private BeaconManager beaconManager;

        @Override
        public void onCreate() {
            super.onCreate();
            beaconManager = BeaconManager.newInstance(getApplicationContext());
            beaconManager.setMonitorPeriod(MonitorPeriod.MINIMAL);
            beaconManager.setForceScanConfiguration(ForceScanConfiguration.DEFAULT);
            beaconManager.registerMonitoringListener(new BeaconManager.MonitoringListener() {
                @Override
                public void onMonitorStart() {
                    Log.v(TAG, "start monitoring beacons");
                }

                @Override
                public void onMonitorStop() {
                    Log.wtf(TAG, "stop monitoring beacons");
                }

                @Override
                public void onBeaconsUpdated(Region region, List<Beacon> list) {

                }

                @Override
                public void onBeaconAppeared(Region region, Beacon beacon) {
                   Toast.makeText(getApplicationContext(), "Beacon appeared\n BEACON ID: " + beacon.getBeaconUniqueId(), Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onRegionEntered(Region region) {

                }

                @Override
                public void onRegionAbandoned(Region region) {

                }
            });

        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {

            Log.v(TAG, "service started");

            if (!beaconManager.isBluetoothEnabled()) {
                Log.w(TAG, "bluetooth disabled, stop service");
                stopSelf();
            } else {
                connect();
            }

            return super.onStartCommand(intent, flags, startId);
        }

        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public void onDestroy() {
            Log.v(TAG, "service destroyed");
            beaconManager.stopMonitoring();
            beaconManager.disconnect();
            beaconManager = null;
            super.onDestroy();
        }

        private void connectBeaconManager() {
            try {
                beaconManager.connect(new OnServiceBoundListener() {
                    @Override
                    public void onServiceBound() {
                        try {
                            HashSet<Region> regions = new HashSet<>();
                            regions.add(Region.EVERYWHERE);
                            beaconManager.startMonitoring(regions);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                });
            } catch (RemoteException e) {
                throw new IllegalStateException(e);
            }
        }

    }     

但我无法让它工作

如果您愿意尝试免费和开源 Android Beacon Library,有一个现成的 运行 参考应用程序,您可以尝试启动该应用程序并在信标出现时发送通知在后台发现。可在此处获取:

https://github.com/AltBeacon/android-beacon-library-reference

您可以按照 here.

中所述添加 Beacon 解析器来使用 Kontakt.io 信标

此参考应用程序的工作原理是在 phone 开机时自动启动 BeaconService 扫描信标。此服务在后台使用自定义 AndroidApplication class here(您可以自定义)中使用的 RegionBootstrap class。此 class' didEnterRegion 方法在首次发现信标时被调用,允许您启动 Activity(该示例在首次检测时执行)或发送通知(该示例执行在随后的通知中。)

有更多关于这一切如何与这个库一起工作的文档here and here.

我假设您一直在测试 kontakt-beacon-admin-sample-app - foreground/background 展示柜。该机制非常简单,但需要了解如何在 Android.

中拦截广播

让我们分析一下 BackgroundScanService

首先BeaconManager负责通过回调方法通知BLE远程设备存在。

其次BeaconManager是在后台服务中故意配置和控制的,因为服务充当广播生成器。该服务的主要优势在于,即使用户放弃该应用程序,它也可以正常工作。 所以实际上服务盲目地发送广播,希望有人会拦截它。

第三,请求发送在下面一行执行:

    sendOrderedBroadcast(intent, null);

sendOrderedBroadcast() is documented here.

第四,现在是拦截广播的时候了。然后我们配置 2 个广播接收器来执行此操作:BackgroundScanReceiver and the ForegroundScanReceiver

BackgroundScanReceiver 在拦截扫描广播时显示通知。

ForegroundScanReceiver 只是显示 toasts,但这可以根据需要进行更改。

此时有一个技巧,我们可以指定拦截广播的顺序。我们配置 ForegroundScanReceiver 以拦截第一顺序的任何广播。 我们通过在与接收器绑定的 Intent 过滤器中设置优先级来实现(see SCAN_INTENT_FILTER) that we register dynamically in onResume() (the app becomes visible) and onPause() (the app becomes partially visible). We also configure statically the BackgroundBroadcastReceiver and give it the priority with value 1.

切换foreground/background

我们现在已经确定了优先级,并且我们知道 ForegroundScanReceiver 首先拦截广播,因为它具有更高的优先级。

当应用程序处于前台时,两个扫描接收器(前台和后台)都会被注册,但只有前台拦截广播并防止每个广播被后台拦截。它是 done by the following method - abortBroadcast()(注意 Foreground 和 Background 接收器扩展了公共抽象):

   abortBroadcast();

然而,当应用程序隐藏在后台时,ForegroundScanReceiver 未注册 (see onPause() method),因此原始接收器是 BackgroundScanReceiver。

You can find the documentation about abortBroadcast() here.

为什么 kontakt.io Proximity SDK 中不包含此功能?

kontakt-beacon-admin-sample-app 中介绍的方法可以通过不同的方式解决,kontakt.io 移动 SDK 的目标是不向您提供已实现的所有功能,因为这会带来一些限制SDK 到您的应用程序。目标是为您提供基础知识并在 SDK 组件使用方面提供灵活性。 kontakt-beacon-admin-sample-app 是概念证明,我们的 SDK 与一些不同的 Android 组件协作可以为您提供您期望的功能,最重要的是,为您提供所需的灵活性对其进行处理。

我建议观察 kontakt-beacon-admin-sample-app 因为这是第一个项目,其中首先介绍了将 kontakt.io SDK 与其他开源库和核心 Android SDK 集成的不同方法。

我也强烈建议您在希望 SDK 的行为符合您的期望时提出问题。

希望我对您的问题做出了一些澄清。