0

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 でクラウドからデータをクエリします。

私のテストは私に教えてくれます:

  1. 「regionBootstrap = new RegionBootstrap(this, regionList);」がある場合 BackgroundApplication onCreate() では、ビーコンがアドバタイズしても MonitoringActivity は何も表示しません。regionBootStrap レジスタを削除した後、MonitoringActivity はビーコンを正しく表示します。

  2. 前のケースで、MonitoringActivity にビーコンを正しく表示させる別の方法は、アプリを一時停止 (バックグラウンドに移動) し、再開 (フォアグラウンドに戻る) してから、MonitoringActivity didEnterRegion が正しくトリガーされるようにすることです。

  3. アプリの起動時から後で 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());
    }
}
4

1 に答える 1