0

我在 Android 应用程序中使用 AltBeacon 库。

我实现了一个活动,然后是示例,可以检测到信标并成功触发 didEnterRegion。前任

公共类 MonitoringActivity 扩展 Activity 实现 BeaconConsumer {

然后我实现了一个后台应用程序,可以在后台检测信标并触发 didEnterRegion。前任

公共类 BackgroundApplication 扩展应用程序实现 BootstrapNotifier {

但是当我尝试将它们组合在一起时,它不起作用。

我想要做的是:调用 MonitoringActivity 从 BackgroundApplication didEnterRegion() 调用中启动 beaconManager.startMonitoringBeaconsInRegion。

这个想法是:

BackgroundApplication 监视特定的 uuid + major:null + minor:null。当它检测到时,启动实现 beaconConsumer 的活动,并监视具有特定主要和次要 ID 的小型特定区域并执行相关操作,例如通过特定主要/次要 ID 从云中查询数据。

我的测试告诉我:

  1. 当我有“regionBootstrap = new RegionBootstrap(this, regionList);” 在 BackgroundApplication onCreate() 中,即使信标在做广告,MonitoringActivity 也不会显示任何内容。删除 regionBootStrap 寄存器后,MonitoringActivity 正确显示信标。

  2. 在以前的情况下,使 MonitoringActivity 正确显示信标的另一种方法是:暂停应用程序(转到后台)并再次恢复它(回到前台),然后 MonitoringActivity didEnterRegion 正确触发。

  3. 我尝试将 regionBootstrap 寄存器从应用程序启动时间推迟到以后,例如 MonitoringActivity onPause()。在这种情况下,应用启动后,MonitoringActivity 会正确显示信标。当我将它暂停到后台时,调用的 startBeaconMonitoring() 会执行 regionBootstrap 注册。但在这种情况下,后台任务无法检测到信标 didEnterRegion。

我猜这是由 BackgroundApplication 中的一个 beaconManager 和 MonitoringActivity 中的另一个 beaconManager 引起的,它们存在冲突,但我不确定。

这是我的 AndroidManifest.xml

<application
    android:name="com.abc.BackgroundApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:launchMode="singleInstance"
        android:name="com.abc.MonitoringActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

现在我的临时解决方案又回到了一般用法: 1. 让 monitorActivity 像正常活动一样干净,没有信标监控活动。2.让backgroundApplication在后台监控具有特定uuid/major/minorId的区域。进入区域后,调用并传递major/minorId 到monitorActivity 并执行相关操作。

但是这样一来,我需要在 backgroundApplication 中预先配置所有特定的 uuid/major/minorId 用于区域回调。

我想在 backgroundApplication 中监视一个简单的特定 uuid 和 null major/minorId 区域,并让 monitorActivity 处理不同 major/minorId 的不同区域情况。可能吗?

例如,创建并监控一个区域 xxx/null/null,当 didEnterRegion 被触发时,我们可以得到它是由哪个 major/minorId 触发的。现在我从区域获得的主要/次要 ID 是 null/null,这与我创建的相同。

任何评论表示赞赏。

更新:这是我的第一个想法,与大卫的建议相同。但正如我提到的,MonitorActivity onBeaconServiceConnect 被调用,但 didEnterRegion 不会被回调。但是在 II 将其暂停到后台并再次将其恢复到前台后,didEnterRegion 被正确调用。这就是为什么我试图征求一些建议。

在后台应用程序中:

@Override
public void onCreate() {
    super.onCreate();
    Log.i(TAG, "App started up");
    BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
    beaconManager.getBeaconParsers().add(new BeaconParser().
            setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
    //set scan frequency
    beaconManager.setBackgroundBetweenScanPeriod(5000);

    // wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
    String uuid1 = "e37ba058-c5bd-40f0-b71d-xxxxxxxxxxxx";
    Identifier id1 = Identifier.parse(uuid1);
    Region region1 = new Region("com.abc.beaconRegion1", id1, null, null);

    ArrayList regionList = new ArrayList<Region>();
    regionList.add(region1);
    regionBootstrap = new RegionBootstrap(this, regionList);
}

@Override
public void didEnterRegion(org.altbeacon.beacon.Region region) {
    Log.i(TAG, "Got a didEnterRegion call");
    Intent intent = new Intent(this, MonitoringActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    this.startActivity(intent);
}

在 MonitorActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_monitor);

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

    //set table layout view
    msgList = (TableLayout)findViewById(R.id.msgList);
    msgList.setStretchAllColumns(true);
}

@Override
public void onBeaconServiceConnect() {
    beaconManager.setMonitorNotifier(new MonitorNotifier() {
        @Override
        public void didEnterRegion(Region region) {
            Log.i(TAG,"didEnterREgion");
            if(region.getId1() == null || region.getId2() == null || region.getId3() == null) {
                return;
            }
            Log.i(TAG, "I just saw an beacon for the first time!");
            uuid = region.getId1().toString();
            majorId = region.getId2().toInt();
            minorId = region.getId3().toInt();
        }
        @Override
        public void didExitRegion(Region region) {

        }

        @Override
        public void didDetermineStateForRegion(int state, Region region) {
        }
    });

    try {
        String uuid = "e37ba058-c5bd-40f0-b71d-xxxxxxxxxxxx";
        Identifier uuidId1 = Identifier.parse(uuid);
        Identifier majorId1 = Identifier.fromInt(21617);
        Identifier minorId1 = Identifier.fromInt(515);
        Identifier minorId2 = Identifier.fromInt(545);
        Region region1 = new Region("com.abc.beaconRegion1", uuidId1, majorId1, minorId1);
        beaconManager.startMonitoringBeaconsInRegion(region1);
        Region region2 = new Region("com.abc.beaconRegion2", uuidId2, majorId1, minorId2);
        beaconManager.startMonitoringBeaconsInRegion(region2);
        Log.i(TAG,"beaconManager start monitor beacons in region");

    } catch (RemoteException e) {
        Log.e("log_tag", e.toString());
    }
}
4

1 回答 1

0

一些提示:

  • 该课程仅设计为在中心课程RegionBootstrap中使用一次。Application在一个Activity类中使用 on 并使用多个实例RegionBootstrap将无法正常工作。

  • 使用时,RegionBootstrap您可以添加新区域以从 Activity 动态监控,只需调用:BeaconManager.getInstanceForApplication(MyActivity.this).startMonitoringBeaconsInRegion(region); 发现的任何信标都将包含在didEnterRegion中央应用程序类的回调中。您可以使用多种技术将有关检测到的信标的信息从您的中心Application类传递到Activity.

  • 或者,您也可以在 Activity使用代码中开始监控信标,例如此处的监控示例代码。 这涉及绑定到BeaconManagerfrom Activity,然后在调用该方法beaconManager.bind(MyActivity.this);后开始监视您的特定区域。onBeaconServiceConnect()

于 2016-02-04T11:20:04.963 回答