【问题标题】:No monitoring and no change of scan period in a service using altbeacon android library使用 altbeacon android 库的服务中没有监控和扫描周期没有变化
【发布时间】:2015-06-19 14:57:13
【问题描述】:

我是一名 android 初学者,正在 Android 上测试一些 Estimote-Beacons。我的项目使用 Estimote 库,但现在我想尝试更开放的 altbeacon-library,但我遇到了几个问题。

我的应用程序的功能应该是这样的: 当应用程序启动时,BeaconApplication 应该启动 BeaconsMonitoringService。应监测两个区域。如果输入了一个区域,服务应该使用广播管理器发送一个意图。使用意图信息,应在主活动中选中/取消选中复选框。 当应用被杀死或蓝牙状态发生变化时,该服务也会启动。

问题是:

  • 未检测到区域
  • 未设置扫描周期

显示所有调试日志,除了来自 onBeaconServiceConnect 的“Entered”和“Left”。 任何帮助,将不胜感激。希望这只是一个愚蠢的/新手错误,并且通常可以正常工作。 :)

这是我的 BeaconApplication 代码:

package de.mcd.presencealtbeacon;

import android.app.Application;
import android.content.Intent;

import org.altbeacon.beacon.BeaconManager;

public class BeaconApplication extends Application {

    private BeaconManager beaconManager = null;

    @Override
    public void onCreate() {
        super.onCreate();
        beaconManager = BeaconManager.getInstanceForApplication(this);
        startService(new Intent(getApplicationContext(), BeaconsMonitoringService.class));
    }

    public BeaconManager getBeaconManager() {
        if (beaconManager == null) {
            beaconManager = BeaconManager.getInstanceForApplication(this);
        }
        return beaconManager;
    }
}

BeaconsMonitoringService 的代码如下:

package de.mcd.presencealtbeacon;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.Identifier;
import org.altbeacon.beacon.MonitorNotifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.BeaconParser;


public class BeaconsMonitoringService  extends Service implements BeaconConsumer {
    private static final String UUID = "1234567-1234-1234-1234-123456789012";
    private static final Region Room = new Region("mcd", Identifier.parse(UUID), Identifier.fromInt(1), null);
    private static final Region Kitchen = new Region("mcd", Identifier.parse(UUID), Identifier.fromInt(2), null);
    private static final String TAG = "BEACON";
    private BeaconManager beaconManager;


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

    @Override
    public void onCreate() {
        Log.d(TAG, "Beacons monitoring service started");
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "Beacons monitoring service destroyed");
    }

    public void onBeaconServiceConnect(){

        beaconManager.setMonitorNotifier(new MonitorNotifier() {
            @Override
            public void didEnterRegion(Region region) {
                Log.d(TAG, "Entered");
                if (region.getId2() == Identifier.fromInt(1)) {
                    postNotification("Room", "Entered");
                    intent("1-1");
                } else {
                    postNotification("Kitchen", "Entered");
                    intent("2-1");

                }
            }

            @Override
            public void didExitRegion(Region region) {
                Log.d(TAG, "Left");
                if (region.getId2() == Identifier.fromInt(1)) {
                    postNotification("Room", "Left");
                    intent("1-2");
                } else {
                    postNotification("Kitchen", "Left");
                    intent("2-2");
                }

            }

            @Override
            public void didDetermineStateForRegion(int state, Region region) {
                Log.d(TAG, "Don't know what it's useful for" + state);
            }
        });

        try {
            Log.d(TAG, "Service ready");
            beaconManager.startMonitoringBeaconsInRegion(Room);
            beaconManager.startMonitoringBeaconsInRegion(Kitchen);
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot start ranging", e);
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStart Start");
        BeaconApplication app = (BeaconApplication)getApplication();
        beaconManager = app.getBeaconManager();

        beaconManager.setBackgroundScanPeriod(1100l);
        beaconManager.setBackgroundBetweenScanPeriod(10000l);

        beaconManager.getBeaconParsers ().add ( new BeaconParser ().setBeaconLayout (
                "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24" ) );
        beaconManager.bind(this);

        Log.d(TAG, "onStart End");

        Notification noti = new Notification.Builder(this)
                .setContentTitle("Started")
                .setContentText("Here we go")
                .setSmallIcon(R.mipmap.ic_launcher)
                .build();

        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.cancel(2);
        mNotificationManager.notify(1, noti);


        return START_STICKY;
    }


    private void postNotification(String room, String action) {
        Intent notificationIntent = new Intent(BeaconsMonitoringService.this, MyActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(BeaconsMonitoringService.this, 0,
                notificationIntent, 0);

        Notification noti = new Notification.Builder(BeaconsMonitoringService.this)
                .setContentTitle(room)
                .setContentText(action)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(intent)
                .build();


        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.cancel(2);
        mNotificationManager.notify(1, noti);
    }


    private void intent (String code){
        Intent intent = new Intent("statechanged");
        intent.putExtra("info", code);
        LocalBroadcastManager.getInstance(BeaconsMonitoringService.this).sendBroadcast(intent);
    }
}

【问题讨论】:

    标签: android ibeacon ibeacon-android altbeacon estimote


    【解决方案1】:

    一个问题是Region 构造函数的第一个参数是一个唯一的字符串,用于标识库的区域。每个区域必须有一个唯一的字符串,否则当您开始测距或监控时,它将替换另一个具有相同标识符的区域。下面的代码对两个区域使用相同的标识符:

    private static final Region Room = new Region("mcd", Identifier.parse(UUID), Identifier.fromInt(1), null);
    private static final Region Kitchen = new Region("mcd", Identifier.parse(UUID), Identifier.fromInt(2), null);
    

    这会导致第二个监控区域替换下面代码中的第一个:

    beaconManager.startMonitoringBeaconsInRegion(Room);
    beaconManager.startMonitoringBeaconsInRegion(Kitchen);
    

    要解决此问题,请将区域设置更改为:

    private static final Region Room = new Region("mcd1", Identifier.parse(UUID), Identifier.fromInt(1), null);
    private static final Region Kitchen = new Region("mcd2", Identifier.parse(UUID), Identifier.fromInt(2), null);
    

    在更基础的层面上,构建一个在后台自动启动的后台服务对于自称是初学者来说是一项相当高级的任务。可能还有许多其他问题不是“看代码很明显。 Android 信标库已经设计为在后台自动启动并扫描信标,其扫描间隔会随着应用程序从前台更改为后台而适当更改。

    您可以在参考应用 here. 的 Application 类中看到一个简单的示例

    我建议不要使用您的 BeaconMoinitoringService,而是将代码从参考应用的 Application 类复制到您的 BeaconApplication 类中。然后,您可以将代码从 BeaconMonitoringService 类移到 BeaconApplication 类的 didEnterRegiondidExitRegion 方法中。

    如果您更喜欢使用定制服务的方法,我相信这是可能的,但可能有点上坡。

    【讨论】:

    • 嗨,大卫,感谢您的快速回答和建议。这段时间我很忙,没有时间做我的私人项目。我已经更改了名称,它现在可以识别一个区域。不幸的是,即使信标位于同一位置,该应用程序也只能识别一个区域。这取决于“第一次看到”哪个信标。 ScanPeriod 也不起作用。对我来说有很多工作,或者你有什么想法吗?与 Estimote 库相同的应用程序已经在运行,但 Estimote 库仅支持 Estimote Beacons。
    • 您应该将后台扫描周期配置移到 onBeaconServiceConnect() 中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多