0

ユーザーが定義された領域に入ったとき、およびユーザーが領域を終了したときに、ユーザーに通知しようとしています。これは私がこれまでに行ったことです。以前は rangeNotifier メソッド (didBeaconsEnterRange) を使用して、ユーザーがリージョンに入ったときにユーザーに通知していましたが、このメソッドが 1 秒ごとに呼び出されるため、通知ロジックを monitorNotifier クラス (didEnterRegion) メソッドに移動しました。

私のアプリケーション クラスは BootStrapNotifier を拡張し、scanPeriod をデフォルトの 1100l 秒ではなく 2000 秒に設定しています。これは、ビーコンが範囲内にある場合でも、終了通知と開始通知を受け取る速度が速すぎるように思われるためです。以前は、ビーコンがタイムアウト期間内にシグナルを発火しなかった場合に終了を発火させるタイムアウト期間を 10000 ミリ秒から 20000 ミリ秒に増やしました。

myapplication クラスのコード スニペット

BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
    beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(LAYOUT_HERE));
    beaconManager.setForegroundScanPeriod(2000l);
    beaconManager.setBackgroundBetweenScanPeriod(1100l);
    //beaconManager.setBackgroundScanPeriod(5000l);
    beaconManager.setDebug(true);

    Log.d(TAG, "setting up background monitoring for beacons and power saving");
    // wake up the app when a beacon is seen
    mRegion = new Region("myRangingUniqueId",
            null, null, null);
    setRegionAgain();

SetRegionAgain メソッド

if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0) {
        if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0 ) {
            try {
                mRegion = new Region("myRangingUniqueId",
                        Identifier.parse(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "")), 
                        null, null);
            }catch(IllegalArgumentException e) {
                e.printStackTrace();
                mRegion = new Region("myRangingUniqueId",
                        null, null, null);
            }
        }
    }

    regionBootstrap = new RegionBootstrap(this, mRegion);

    // simply constructing this class and holding a reference to it in your custom Application
    // class will automatically cause the BeaconLibrary to save battery whenever the application
    // is not visible.  This reduces bluetooth power usage by about 60%
    backgroundPowerSaver = new BackgroundPowerSaver(this);

通知作業を行うバックグラウンド サービスがあるため、BeaconConsumer インターフェイスを実装しています。以下のコード スニペット:

OnStart メソッド:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    flagToCheckExit = false;
    mHandler = new Handler();
    beaconManager.bind(this);
    if (beaconManager.isBound(this)) beaconManager.setBackgroundMode(false);
    return Service.START_STICKY;
}

onDestroy メソッド:

@Override
public void onDestroy() {
    super.onDestroy();
    try {
        beaconManager.stopMonitoringBeaconsInRegion(CommonUtilities.getRegion());
// this region is the one that i use to monitor (singleton types)
    } catch (RemoteException e) {
        e.printStackTrace();
    }

    beaconManager.unbind(this);
}

onServiceConnected メソッド:

@Override
public void onBeaconServiceConnect() {
    beaconManager.setMonitorNotifier(new MonitorNotifier() {

        @Override
        public void didExitRegion(final Region region) {
            LogManager.d(TAG, "didExitRegion %s", region);

            if(SharedPrefs.getString(SharedPrefs.USER_ID, "").trim().length() > 0) {
                flagToCheckExit = true;
// i use this flag to prevent random entry and exit notifications
                mHandler.postDelayed(mRunnable, 20000);
// waiting for 20seconds before firing an exit notification, since an entry notification might get fired immediately after the exit
            }
        }

        @Override
        public void didEnterRegion(Region region) {
            Log.e(TAG,"region id1 >>> " + ((region.getId1() == null) ? "null" : region.getId1().toUuidString()));

            LogManager.d(TAG, "didEnterRegion %s ",region);

            if(!flagToCheckExit) {
                if(SharedPrefs.getString(SharedPrefs.USER_ID, "").trim().length() > 0) {
                    if(region.getId1() != null && 
                            region.getId1().toUuidString().equalsIgnoreCase(SharedPrefs.getString(SharedPrefs.iBEACON_ID, ""))) {
                        if(!SharedPrefs.getBoolean(SharedPrefs.IS_ENTRY_LOG_CALLED, false)) {
                            String entryRange = getAppContext().getString(R.string.entered_beacon_region);
                    CommonUtilities.sendNotification(MonitoringAltBeaconService.this,entryRange,1);
                        }
                    }
                }
            }else {
                // invalidate the handler
                // stop all operations of the handler
                // we do this to prevent an exit getting called since entry has been called immediately.
                mHandler.removeCallbacks(mRunnable);
            }
        }

        @Override
        public void didDetermineStateForRegion(int state, Region region) {
            LogManager.d(TAG, "didDetermineStateForRegion %s ",region);
        }
    });

    startMonitoring();
}

startMonitoring メソッド:

private void startMonitoring() {
    try {
        if(SharedPrefs.getString(SharedPrefs.iBEACON_ID, "").trim().length() > 0 ) {
            try {
                beaconManager.startMonitoringBeaconsInRegion(CommonUtilities.getRegion());
            }catch(IllegalArgumentException e) {
                e.printStackTrace();

                beaconManager.startMonitoringBeaconsInRegion(CommonUtilities.getRegion());
            }
        }
    } catch (RemoteException e) {   }
}

実行可能なスレッド:

Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        SharedPrefs.putBoolean(SharedPrefs.IS_ENTRY_LOG_CALLED, false);
        SharedPrefs.putBoolean(SharedPrefs.IS_EXIT_LOG_CALLED, true);

        String exitedRange = getAppContext().getString(R.string.exited_beacon_region);
        CommonUtilities.sendNotification(MonitoringAltBeaconService.this,exitedRange,2);
        LogManager.d(TAG, "exit called");
        flagToCheckExit = false;
    }
};

これには奇妙な動作があります。ビーコン デバイスが範囲内にある場合でも取得する複数のエントリ ログと終了ログがあり、終了します。終了通知をバイパスしようとしましたが、上記のロジック (パッチ) で失敗するようです。

ログ:

03-19 18:00:25.866: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:00:25.867: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:00:26.470: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 

03-19 18:00:26.477: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 

03-19 18:00:48.076: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:00:48.076: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null

03-19 18:00:51.275: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:00:51.282: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:01:10.269: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:01:10.269: D/MonitoringAltBeaconService(22795): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-19 18:01:15.876: D/MonitoringAltBeaconService(22795): didDetermineStateForRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 
03-19 18:01:15.883: D/MonitoringAltBeaconService(22795): didEnterRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null 

私はAprilBeaconを使用しています。ビーコンが通知を正しく生成しないため、作業中のアプリが停止しています。手伝ってください。

編集:

Motorolla g2 の場合に使用するデバイス。このシナリオは、キットカット バージョンとロリポップ バージョンの両方で発生します。そして、Wifiがオンになっています。エントリの出口が決定されると、Webサービスの呼び出しが関係するため、オンになっていることを好みます。リアルタイム 、ユーザーに Wi-Fi をオフにするように求めることは推奨されません :(..

私が使用しているライブラリは android-beacon-libraryです。残念ながら 4 月のビーコンが信号を送信する頻度がわかりません。

編集2:

ログ1はここにあります

ログ2はここにあります

編集3

Wi-Fi がオフになったときのログ ビーコンが範囲内にある場合でも終了したことに気付きました。また、ロケーター アプリを開いたところ、ビーコンが存在しないことが示されました (スクリーンショットを参照)。バッテリーを取り外して元に戻すと、ビーコンが表示され、アプリもそうでした。(しかし実際には、バッテリーが改ざんされることはないと確信しています)

検出されない場合 電池を取り外した後

4

3 に答える 3

2

あなたの設定は有効に見えますが、少し欠陥があります。両方のフォアグラウンド スキャン構成を設定する必要があります。

beaconManager.setForegroundScanPeriod(2000l);
beaconManager.setForegroundBetweenScanPeriod(1100l);
//Update default time with the new one
beaconManager.updateScanPeriods();

または/およびバックグラウンド スキャン構成:

beaconManager.setBackgroundScanPeriod(2000l);
beaconManager.setBackgroundBetweenScanPeriod(1100l);
//Update default time with the new one
beaconManager.updateScanPeriods();

また、ビーコンの広告頻度はわかりますか?スキャン期間を 20 秒に増やしたとおっしゃいましたが、周波数に変更はありませんでした。

ところで、AltBeacon の logcat 出力も共有できますか? また、お使いのデバイスとモデルは何ですか? そして、どの Android バージョンが実行されていますか? そして、どの AltBeacon ライブラリのバージョンを使用していますか?

お使いのデバイスが Lollipop を実行している場合は、次の行を試して、結果をお知らせください:

BeaconManager.setAndroidLScanningDisabled(true);

また、一部のデバイスでは Bluetooth スキャンに干渉するため、WiFi がオンになっている場合は、WiFi をオフにしてみてください。

ところで、申し訳ありませんが、これは答えというよりはコメントに似ていますが、コメントも待ち望んでいました:)。

于 2015-03-20T08:50:54.820 に答える
2

問題は、頻繁にアドバタイズされるビーコンと、短すぎるカスタム バックグラウンド スキャン間隔の組み合わせです。

ビーコンは 2 秒ごとに 1 回だけアドバタイズしているようです。これは、ログに記録された 2 つの後続の検出タイムスタンプが最も近いためです。これは送信頻度が低いことが問題であり、カスタム設定によって悪化します。

ライブラリが適切に動作するためには、バックグラウンド スキャン期間がビーコン送信期間の少なくとも 5 倍である必要があります。これは、ラジオ ノイズのためにすべての bluetooth パケットが受信されないためです。送信期間の 5 倍の間隔を持つということは、各バックグラウンド スキャン サイクルでパケットを受信する機会が 5 回あることを意味し、ライブラリが 1 つを見逃す可能性はほとんどありません。

デフォルトのライブラリ設定では、バックグラウンド スキャン期間が 10 秒に設定されています。これは、2 秒に 1 回しか送信されないビーコンを検出する可能性が非常に高く、誤った領域の出口が非常にまれになるのに十分な値です。

推奨事項:

  1. バックグラウンド スキャン期間を少なくともデフォルトの 10 秒に変更します。 バッテリーを節約するには、スキャン間隔もおそらく長くする必要があります。短くする正当な理由がない限り、デフォルトの 5 分が妥当な選択です。それでも終了イベントが発生する場合は、バックグラウンド スキャン期間をさらに長くします。

  2. より頻繁にアドバタイズする別のビーコンを使用します。 ライブラリをこれらのビーコンで動作させることはできるはずですが、更新頻度はそれほど高くなく、Locate などのアプリでは定期的に検出のドロップアウトが表示されます。アプリで距離推定を行う場合は、10Hz 以上で送信するビーコンが必要です。アプリで距離推定を行わない場合でも、1Hz 以上で送信するビーコンを使用する必要があります。そうしないと、このような問題が発生する可能性が高くなります。

これが問題であることをどうやって知ることができますか?

以下のログの抜粋からわかるように、前回の検出から 10 秒経過しているため、15:50:52 に誤った領域の終了が発生しています。10 秒間検出がない場合、次にスキャン サイクルが停止したときに領域終了イベントが発生します。そのため、スキャン サイクルがビーコン送信をキャプチャするのに十分な長さであることを十分に確認する必要があります。カスタム設定では、後続の 3 回のスキャン サイクルで検出を逃すと、領域が終了します。

03-26 15:49:49.533: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:49:55.567: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:01.624: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:08.898: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:11.315: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:17.380: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:21.010: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:26.440: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:30.066: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:33.108: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:36.120: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:39.745: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:41.573: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7

03-26 15:50:52.415: D/MonitorState(28596): We are newly outside the region because the lastSeenTime of 1427365241573 was 10841 seconds ago, and that is over the expiration duration of 10000
03-26 15:50:52.415: D/BeaconService(28596): found a monitor that expired: id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
03-26 15:50:52.415: D/Callback(28596): attempting callback via intent: ComponentInfo{com.credencys.mycarline/org.altbeacon.beacon.BeaconIntentProcessor}

03-26 15:50:54.879: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:50:56.705: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:51:00.940: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:51:03.348: D/BeaconService(28596): beacon detected : id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: 1 id3: 7
03-26 15:51:03.349: D/BeaconService(28596): looking for ranging region matches for this beacon
03-26 15:51:03.842: D/CycledLeScanner(28596): Waiting to stop scan cycle for another 1000 milliseconds
03-26 15:51:04.730: D/MonitoringAltBeaconService(28596): didExitRegion id1: cbb7c628-a321-4cf6-934d-37dbfa335735 id2: null id3: null
于 2015-03-21T15:18:53.460 に答える