Android アプリで AltBeacon ライブラリを使用しています。
アクティビティとそれに続く例を実装します。ビーコンを検出して didEnterRegion を正常にトリガーしても問題ありません。元
public class MonitoringActivity extends Activity implement BeaconConsumer {
次に、バックグラウンド アプリケーションを実装します。バックグラウンドでビーコンを検出して didEnterRegion をトリガーしても問題ありません。元
public class BackgroundApplication extends Application implement BootstrapNotifier {
しかし、それらを組み合わせようとすると、うまくいきません。
私がやりたいことは、MonitoringActivity を呼び出して、beaconManager.startMonitoringBeaconsInRegion を BackgroundApplication didEnterRegion() 呼び出しから開始することです。
アイデアは次のとおりです。
BackgroundApplication ウォッチ固有の uuid + メジャー:null + マイナー:null。検出されると、beaconConsumer を実装するアクティビティを開始し、特定のメジャー ID とマイナー ID を持つ小さな特定の領域を監視し、関連するアクションを実行します。たとえば、特定のメジャー ID とマイナー ID でクラウドからデータをクエリします。
私のテストは私に教えてくれます:
「regionBootstrap = new RegionBootstrap(this, regionList);」がある場合 BackgroundApplication onCreate() では、ビーコンがアドバタイズしても MonitoringActivity は何も表示しません。regionBootStrap レジスタを削除した後、MonitoringActivity はビーコンを正しく表示します。
前のケースで、MonitoringActivity にビーコンを正しく表示させる別の方法は、アプリを一時停止 (バックグラウンドに移動) し、再開 (フォアグラウンドに戻る) してから、MonitoringActivity didEnterRegion が正しくトリガーされるようにすることです。
アプリの起動時から後で regionBootstrap レジスタをプッシュバックしようとしています (例: MonitoringActivity onPause())。この場合、アプリの起動後、MonitoringActivity はビーコンを正しく表示します。バックグラウンドで一時停止すると、startBeaconMonitoring() が呼び出され、regionBootstrap が登録されます。ただし、この場合、バックグラウンド タスクはビーコン didEnterRegion を検出できません。
BackgroundApplication の 1 つの 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 で単純な 1 つの特定の uuid と null のメジャー/マイナー ID 領域を監視し、monitorActivity が異なるメジャー/マイナー ID の異なる領域のケースを処理できるようにします。出来ますか?
たとえば、リージョン xxx/null/null を作成して監視し、didEnterRegion がトリガーされると、正確にどのメジャー/マイナー ID によってトリガーされるかを取得できます。これで、リージョンから取得した major/minorId は null/null になりました。これは、作成したものと同じです。
どんなコメントでも大歓迎です。
更新: これは、David の提案と同じ私の最初のアイデアです。しかし、前述したように、MonitorActivity onBeaconServiceConnect は呼び出されますが、didEnterRegion はコールバックされません。しかし、バックグラウンドで一時停止し、再びフォアグラウンドで再開すると、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());
}
}