我在Android App中使用AltBeacon库 .
我实现了一个活动,然后是示例,可以成功检测到beacon并触发didEnterRegion . 前
公共类MonitoringActivity扩展Activity实现BeaconConsumer {
然后我实现了一个后台应用程序,可以在后台检测信标并触发didEnterRegion . 前
公共类BackgroundApplication extends Application实现BootstrapNotifier {
但是当我尝试将它们组合在一起时,它不起作用 .
我想要做的是:调用MonitoringActivity从BackgroundApplication didEnterRegion()调用启动beaconManager.startMonitoringBeaconsInRegion .
这个想法是:
BackgroundApplication监视特定的uuid major:null minor:null . 检测到时,启动实现beaconConsumer的活动,并观察具有特定主要和次要ID的小特定区域并执行相关操作,从特定主要/次要ID的 Cloud 查询数据 .
我的测试告诉我:
-
当我有“regionBootstrap = new RegionBootstrap(this,regionList);”在BackgroundApplication onCreate()中,即使信标是广告,MonitoringActivity也不显示任何内容 . 删除regionBootStrap寄存器后,MonitoringActivity正确显示信标 .
-
在前一种情况下,另一种使MonitoringActivity正确显示信标的方法是:暂停应用程序(转到后台)并再次恢复(返回前台),然后正确触发MonitoringActivity didEnterRegion .
-
我尝试将regionBootstrap寄存器从应用程序启动时间推迟到以后,来自MonitoringActivity onPause() . 在这种情况下,应用程序启动后,MonitoringActivity会正确显示信标 . 当我将它暂停到后台时,startBeaconMonitoring()调用了哪个区域进行了注册 . 但在这种情况下,后台任务无法检测到信标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来触发它 . 现在我从区域获得的major / minorId为null / null,这与我创建的相同 .
任何评论表示赞赏 .
更新:这是我的第一个想法,与David的建议相同 . 但正如我所提到的,MonitorActivity onBeaconServiceConnect被调用,但didEnterRegion将不会被回调 . 但是在我将其暂停到背景并再次将其恢复到前景之后,会正确调用didEnterRegion . 这就是我试图提出一些建议的原因 .
在BackgroundApplication中:
@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());
}
}
1 回答
一些提示:
RegionBootstrap
类仅设计为在中心Application
类中使用一次 . 在Activity
类中使用on,并使用RegionBootstrap
的多个实例将无法正常工作 .使用
RegionBootstrap
时,您可以通过调用以下方式添加要从活动中动态监视的新区域:BeaconManager.getInstanceForApplication(MyActivity.this).startMonitoringBeaconsInRegion(region);
发现的任何信标都将包含在中央应用程序类的didEnterRegion
回调中 . 您可以使用各种技术将检测到的信标的信息从中央Application
类传递到Activity
.或者直到上面的点,您也可以使用Monitoring Sample Code here.中的代码开始监视
Activity
中的信标 . 这涉及使用beaconManager.bind(MyActivity.this);
从Activity
绑定到BeaconManager
,然后在调用onBeaconServiceConnect()
方法后开始监视您的特定区域 .