web-dev-qa-db-ja.com

BluetoothAdapterはBLEデバイスのスキャンを停止しません

私のアプリには開始ボタンと停止ボタンがあり、ユーザーが開始を押すとstartScanメソッドを呼び出します

bluetoothAdapter.getBluetoothLeScanner().startScan(getLeScanCallback());

ユーザーがstopを押すと、stopScanを呼び出しますが、何も実行されないようです。 BluetoothAdapterは新しいデバイスをスキャンし続けます。

bluetoothAdapter.getBluetoothLeScanner().stopScan(getLeScanCallback());

これが私のgetLeScanCallbackメソッドです:

private ScanCallback getLeScanCallback(){
    ScanCallback leScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            boolean duplicate = false;
            for(Device d : devices) {
                if(d.getAddress().equals(result.getDevice().getAddress()))
                    duplicate = true;
            }
            if(!duplicate) {
                Device device = new Device();
                device.setName(result.getDevice().getName());
                device.setAddress(result.getDevice().getAddress());
                device.setStatus(getString(R.string.disconnected));
                devices.add(device);
                deviceListAdapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
        }
    };

    return leScanCallback;
}

StopScan()が呼び出された後でも呼び出されます。何が間違っているのですか、言い換えれば、BLEデバイスのスキャンを停止する方法は?

10
user1852879

getLeScanCallbackを呼び出すたびに、ScanCallbackの新しいインスタンスが作成され、前のインスタンスへの参照が失われます。

stopScanは、渡したインスタンスに関係なく進行中のスキャンを停止しますが、それが(開始に使用したものとは異なる)インスタンスである場合、コールバックの古いインスタンスは削除されないため、停止する前に一部のイベントが配信されます。

19
RadekJ

スキャン結果はすぐには停止しませんが、最終的には停止します。フラッシュできる保留中の結果のキューがあります。

scanner.flushPendingScanResults();

しかし、それでも、ドキュメントは、見つかったものをすべてコールバックに送信することを明確にしています。これは、スキャンを停止した場合でも発生します。貧弱なAPI設計ですが、それが何であるかです。

スキャン結果を停止した後、スキャン結果を無視するフラグを設定するのが最も簡単だと思います。

5
spekary

コードに問題はありません。問題ないようです。おそらく、getLeScanCallback()メソッドに問題がありますか?

ScanCallbackを返すメソッドを使用する代わりに、メンバー変数として宣言してleScanCallback = new ScanCallback()を作成し、スキャンを停止しようとするときに、代わりにこのメンバー変数を参照することができます。

bluetoothAdapter.getBluetoothLeScanner().stopScan(leScanCallback);

サポートしているAndroid)のバージョンによっては、RajeshPanchalがLollipop以前に提案したstartLeScanメソッドとstopLeScanメソッドを追加する価値があるかもしれませんAndroidデバイス。

1
Mark O'Sullivan