web-dev-qa-db-ja.com

Androidフィルター付きのBLEデバイススキャンが機能していません

私はAndroid BLE(Bluetooth Low Energy)を使用しています。使用しているBLEデバイスのスキャンに問題があります。
startLeScan(UUID[] serviceUuids, BluetoothAdapter.LeScanCallback callback)メソッド
_startLeScan(BluetoothAdapter.LeScanCallback callback)が正常に動作している間。
フィルターを使用して特定のserviceUUIDをスキャンすると、コールバックが実行されません。私はsamsung galaxy s6でテストしています。
この問題がデバイス固有のものか、スキャン機能にバグがあるかどうかを知りたいです。

11
Akhilesh Kumar

私はそれがデバイス固有ではないと確信しています。まず第一に、IshArtが述べたように、Android 5.0以降のstartScanを使用する必要があります。

startScan(List<ScanFilter> filters, ScanSettings settings, ScanCallback callback)

私の経験では、MACアドレスを取得する場合、Scanfiltersの実装は正常に機能しますが、他のフィルターセットアップパラメーターは問題があります。

ScanFilter filter = new ScanFilter.Builder().setDeviceAddress(deviceMacAddress).build();
filters.add(filter);

それが選択肢にならない場合は、独自のフィルターを実装することもできます。 startScan()のフィルターリストを空のままにすると、すべてのフィルタリングが無視され、すべてが受信されます。次に、コールバックで独自のメソッドを記述して、結果が要件を満たしているかどうかを確認できます。

11
Chris

これは、Samsung Galaxy S6で見つかった特定の問題です。私は新しいスキャナーAPIを使用し、Android 5.0+。 S6に問題がある理由を知ってください。

回避策は、残念ながら、デバイスが検出された後、MACアドレスを手動でフィルタリングすることです。

更新

これにより、Galaxy S6で発生していた上記の問題が修正されました。

以前は、次のように2つの条件を同じScanFilterに追加していました(Kotlin)。

ScanFilter.Builder()
    .setServiceUuid(BluetoothBlind.Service.ParcelUUID)
    .setDeviceAddress(macAddress)
    .build()

条件を複数のフィルターに分割するように変更すると、修正されます。

ScanFilter.Builder()
    .setDeviceAddress(macAddress)
    .build()

ScanFilter.Builder()
    .setServiceUuid(BluetoothBlind.Service.ParcelUUID)
    .build()
3
Bryan Bryce

BLEフィルタースキャンの問題は既知の問題です。この問題およびその他のBLEの問題については、 https://github.com/iDevicesInc/SweetBlue/wiki/Android-BLE-Issues を参照してください。結論は簡単です。「すべてのデバイスをスキャンして、自分でフィルタリングする必要があります。」

2
p2pkit

2つのスキャン方法があります:

//Device scan callback Lollipop and above
    private ScanCallback generateScanCallback(){

        if(apiVersion> Build.VERSION_CODES.KitKat) {
            ScanCallback mScanCallback = new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);
                    final BluetoothDevice device = result.getDevice();
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.e(TAG, "running scan " + device.getAddress());
                            if (device.getAddress().equals(mDeviceAddress)) {
                                Log.e(TAG, "device founded, trying to connect");
                                scanLeDevice(false);
                                Intent gattServiceIntent = new Intent(mContext, BluetoothLeService.class);
                                mContext.bindService(gattServiceIntent, mServiceConnection, mContext.BIND_AUTO_CREATE);
                                mIndicationText.setText(mContext.getString(R.string.waiting));
                            }
                        }
                    });
                }
            };
            return mScanCallback;
        }
        return null;
    }


// Device scan callback KitKat and below.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
    new BluetoothAdapter.LeScanCallback() {

        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.e(TAG,"running scan "+device.getType());
                    if(device.getAddress().equals(mDeviceAddress)){
                        Log.e(TAG, "device founded, trying to connect");
                        scanLeDevice(false);
                        Intent gattServiceIntent = new Intent(mContext, BluetoothLeService.class);
                        mContext.bindService(gattServiceIntent, mServiceConnection, mContext.BIND_AUTO_CREATE);
                        mIndicationText.setText(mContext.getString(R.string.waiting));
                    }
                }
            });
        }
    };

そしてより:

if(apiVersion> Build.VERSION_CODES.KitKat) {
    scanner = mBluetoothAdapter.getBluetoothLeScanner();
    // Device scan callback Lollipop
    scanner.startScan(generateScanCallback());
} else {
    mBluetoothAdapter.startLeScan(mLeScanCallback);
}

必要に応じてスキャン方法をカスタマイズできますが、1つのAndroid 5以上ともう1つのAndroidOSの2つのスキャン方法があることを知っておく必要があります。

0
Fakher