Android 4.3 Bluetooth Low Energyが不安定


189

現在、Bluetooth Low Energyを使用するアプリケーションを開発しています(Nexus 4でテスト中)。Android 4.3で公式のBLE APIを使い始めた後、初めてデバイスを接続した後、そのデバイスまたは他のデバイスに正常に接続/通信することができないことに気付きました。

ここのガイドに従って、問題なくデバイスに接続し、サービスと特性をスキャンし、通知の読み取り/書き込み/受信を行うことができます。ただし、切断して再接続した後、サービス/特性をスキャンしたり、読み取り/書き込みを完了したりできないことがあります。これがなぜ起こっているのかを示すログに何も見つかりません。

これが発生したら、アプリケーションをアンインストールし、Bluetoothを無効にして、電話が再稼働する前に再起動する必要があります。

デバイスが切断されているときはいつでも、必ずBluetoothGattオブジェクトでclose()を呼び出し、それをnullに設定します。洞察はありますか?


編集:
ログダンプ:これらのログについて、私は自分の電話をルート化し、/ etc / bluetooth / bt_stack.conf内の関連アイテムのトレースレベルを上げました

接続の成功 -電話を再起動してアプリをインストールした後の最初の試行。接続、すべてのサービス/特性の検出、読み取り/書き込みができます。

失敗した試行1-これは、上記の正常な接続から切断した後の次の試行です。特性を見つけることができたようですが、最初の読み取り試行でnull値が返され、その後すぐに切断されました。

失敗した試み2-サービス/特性を発見することさえできない例。


編集2:
接続しようとしているデバイスは、TIのCC2541チップに基づいています。私はTI SensorTag(これもCC2541に基づく)を入手して遊んでみたところ、TIが昨日、SensorTagのAndroidアプリをリリースしことを発見しました。ただし、このアプリには同じ問題があります。これを他の2つのNexus 4でテストしましたが、同じ結果が得られました。SensorTagへの接続は1回目または2回目は成功していますが、(ログによると)その後のサービスの検出に失敗し、あらゆる種類のクラッシュを引き起こしています。この特定のチップに問題があるのか​​と思い始めています。


起動時から問題が発生するまで、電話の完全なログを投稿してください。
AAnkit 2013

3
リークしたGoogleエディションのAndroid 4.3がインストールされたSamsung Galaxy S4を使用しています。接続/切断を何度も繰り返した後、サービスを発見すると、ランダムに129(GATT_INTERNAL_ERROR)を取得し、ステータス133(GATT_ERROR)のonConnectionStateChangeを取得します。state= BluetoothProfile.DEVICE_DISCONNECTED。
reTs 2013

1
1回か2回、短期間に複数のステータス129と133のコールバックを受け取り、デバイスを再起動するまでBluetoothGattCallbackでコールバックを受信できませんでした(ただし、スキャンは問題ありません)。
reTs 2013

1
私がTIチップを使用している約10のデバイス(申し訳ありませんが、モデルがわからない)とNordicチップを備えた1つのデバイスでテストしていることを忘れてください。Nordicチップを搭載したデバイスはエラーを報告しません(ただし、問題がTI固有であることを証明するには不十分です)
reTs

1
この問題がSamsung Galaxy S5(G900VVRU2BOG5G900VVRU2BOA8の両方のビルドバージョン)にまだ存在していることを確認できます。[設定]> [アプリケーションマネージャ]> [すべて]> [Bluetooth]からデータを消去すると、しばらくは動作します。
IronBlossom

回答:


184

重要な実装のヒント

(おそらく、Android OSの更新により、これらのヒントの一部は不要になります。)

  1. Android 4.3を搭載したNexus 4などの一部のデバイスは、既存のgattインスタンスを使用して接続するのに45秒以上かかります。回避策:切断時に常にgattインスタンスを閉じ、接続するたびにgattの新しいインスタンスを作成します。
  2. 電話することを忘れないでください android.bluetooth.BluetoothGatt#close()
  3. 内部 onLeScan(..)新しいスレッドを開始し、接続します。理由:Android 4.3搭載のSamsung Galaxy S3の同じスレッドBluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)で呼び出された場合、常に失敗します(少なくともビルドJSS15J.I9300XXUGMK6の場合)
  4. ほとんどのデバイスは広告をフィルタリングします
  5. android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) 特定のサービスUUIDをフィルターするパラメーターと一緒に使用ないでください。これは、Android 4.3を搭載したSamsung Galaxy S3では完全に機能しなくなり、一般に128ビットUUID機能しないためです。
  6. Gattは常に一度に1つのコマンドを処理できます。複数のコマンドが次々と呼び出された場合、gatt実装の同期的な性質により、最初のコマンドはキャンセルされます。
  7. Android 5を搭載した最新のデバイスでも、WifiがBluetoothに干渉し、その逆も同様であることがよくあります。最後の手段として、Bluetoothを安定させるためにWi-Fiをオフにします。

初心者向けチュートリアル

初心者にとってかなり良いエントリポイントは、次のビデオチュートリアルである可能性があります。Android向けBluetoothスマートアプリケーションの開発http://youtu.be/x1y4tEHDwk0

以下で説明する問題と回避策は、おそらくOSのアップデートによって修正されています

回避策:アプリを「安定させる」ことができます...

  1. ユーザーに「Bluetoothの再起動」の設定を提供します。その設定が有効になっている場合、BLEスタックの始まりが不安定になることを示すいくつかのポイントでBluetoothを再起動します。たとえば、startScanがfalseを返した場合などです。serviceDiscoveryが失敗した場合も良い点です。Bluetoothをオフにしてからオンにします。
  2. 「WiFiをオフにする」という別の設定を提供します。その設定が有効になっている場合、私のアプリは実行中にWifiをオフにします(その後、再びオンにします)

この回避策は、次の経験に基づいています...

  • Bluetoothを再起動すると、ほとんどの場合、BLEの問題を修正できます
  • Wifiをオフにすると、BLEスタックはより安定します。ただし、Wi-Fiがオンになっているほとんどのデバイスでも問題なく機能します。
  • Wifiをオフにした場合、Bluetoothを再起動すると、BLEスタックが完全に回復します。ほとんどの場合、デバイスを再起動する必要はありません。

33
グーグル、あなたはこれを今直さなければならない。この回避策(機能するので、私はプラスしました)はばかげています。
Chris Herbert

4
場合によっては、サービスディスカバリはステータス0(問題がないと仮定)で成功しますが、本質的に接続されていないか、または特性が検出されなかったため、特性読み取りはNULL値を生成します(ログにこれが表示されます:11-01 18:37: 32.131:WARN / BluetoothGatt(20119):未処理の例外:java.lang.NullPointerException)
Lo-Tan

2
@ Lo-Tan必要なサービスが含まれている場合は、サービスの検出後に常に確認します。また、サービスディスカバリで結果が得られた場合も、確信が持てません。コールバックを受け取らないこともあります。そこで、サービス検出にタイムアウトを適用しました。
OneWorld 2013年

2
私の経験は次のとおりです。SamsungS3(4.3)は、上記の段落2で説明したように、Gattクライアントを閉じた後に正常に再接続しました。Nexus 4&7(4.4.2)を使用している場合、BLアダプターを再起動しても接続が切断された後は再接続できませんでしたが、2分後に自動的に再接続できます
Konstantin Konopko

1
誰でもandroid.bluetooth.BluetoothGattが保留中のGATT操作PER DEVICEPER PROCESS、またはPERIOD(つまり、すべてのプロセスにわたって)を処理できるかどうかを確認できますか?PER DEVICEだと思いますが、この問題はごちゃごちゃしていて、そうでなければ驚かないでしょう。制限がPER DEVICEのみ​​の場合、複数の同時操作を処理できるOS /デバイスは、この問題がOSが各プロセスに渡すBluetoothAdapterインスタンスの弱い単純な実装が純粋に原因であることを証明しています(私が想定していた)すべてのプロセスにわたるシングルトン)。
swooby 2016年

18

WIFIをオフにする:

WIFIをオフにすると、特にGoogle Nexus(Nexus 7を使用)でBluetooth 4.0がより安定することも確認できます。

問題

私が開発しているアプリケーションには、WIFIと継続的なBluetooth LEスキャンの両方が必要です。そのため、WIFIをオフにすることは私には選択肢になりませんでした。

さらに、継続的なBluetooth LEスキャンが実際にWIFI接続を強制終了し、BLEスキャンがオンになるまでWIFIアダプターがどのWIFIネットワークにも再接続できなくなる可能性があることにも気付きました。(モバイルネットワークとモバイルインターネットについてはわかりません)。
これは間違いなく次のデバイスで起こりました:

  • ネクサス7
  • Motorola Moto G

ただし、WIFIをオンにしたBLEスキャンは、次の環境ではかなり安定しているように見えました。

  • サムスンS4
  • HTC One

私の回避策

のスキャンBLE短期間3-4秒は、私は3~4秒のスキャンをOFFにします。その後、再びオンにします。

  • 明らかに、BLEデバイスに接続しているときは常にBLEスキャンをオフにします。
  • デバイスから切断すると、BLEを再起動し(アダプターをオフにしてからオンにします)、スタックをリセットしてからスキャンを再開します。
  • また、検出servicesまたはcharacteristics失敗したときにBLEをリセットします。
  • アプリが接続する必要のあるデバイスから広告データを取得すると(接続できずに500回と表示されます-これは約5〜10秒の広告です)、BLEを再度リセットします。

デバイスが切断された後にBLEを再起動するとのことですが、ユーザーがBluetooth接続を介してファイルを転送していたとしましょう。その後、あなたはいつでもそのBluetooth転送が失敗するようになります。
Rahul Rastogi、2015

1
「アダプターをオフにしてからオンにする」とはどういう意味ですか?
MarianPaździoch2015年

WifiとBluetoothが一緒になって、Moto Gでアプリのパフォーマンスが低下していることに同意します
。– Nigilan

@MarianPaździoch、「アダプターをオフにしてからオンにする」@ benkaはBluetoothAdapterを意味します
Anup

9

Nexusがデバイスとペア設定されていることを確認します。通信が正常に行われているかどうかは確認できませんが、再起動せずに複数回接続できます。最初の接続ではペアリングは必要ないようですが、その後のすべての試行では必要です。

再起動せずにサービスディスカバリとgatt読み取りおよび書き込みリクエストをテストするときに、この回答を数日で更新します。

編集:私はペアリングされていない場合に問題を引き起こしていた開発ファームウェアバージョン(私たちのセンサー)でテストしていたことがわかりました。最新の製品ファームウェアビルドは、2540および2541で正常に動作します。

編集:Nexus 7 2013では、WiFiをオフにすると接続がより安定することに気付きました。これが他の人に役立つかどうか知りたいのですが。

編集:私はそれをペアリングと逆に持っていたようです。ペアリングされていない場合、すべてが正常に動作します。ペアリング後、OPとまったく同じ症状が発生します。これがファームウェアまたはAndroid BLE APIに関連しているかどうかはまだわかりません。一度ペアリングすると、この投稿の 3bで説明されているバグのためにペアリングを解除できない場合があるため、これをテストする場合は注意してください。


手動でペアリングしたり再起動したりせずに、CC2541デバイスに一貫して接続および再接続しています。
dgel 2013

私の意見では、ペアリングは必要ありません。公式ドキュメントはペアリングについてもコメントしていません。ペアリングなしで、書き込み、読み取り、特性変更通知を実行することもできます。しかし、ほんの少しの間。再び不安定になりました... SAMSUNG BLE SKD v2.0もペアリングを必要とせず、非常に良好に動作しました。
OneWorld 2013

3
私は、確認することができ、それは無線LANをオフにした後、より安定します。誰もがそれを試すべきです。
OneWorld 2013

1
ペアリングが必要かどうかは、デバイスの実装によって異なります。nrf8002デバイスはペアリングを必要とし、Samsung 2.0および1.2 APIの両方がこれをサポートしました。公式のAPIサポートでペアリングの問題が発生しているようです。bleデバイスをペアリングした後、ペアリングを解除することはできないようです!
Chris Herbert、

2
ペアリングを解除できない場合の回避策があります。1)btメニューに移動し、ペアリング解除を選択し、エリアからbleデバイスを削除するか、電源を切ります。btメニューでbleデバイスを選択すると、ペアリングして失敗し、Bluetoothをリセットします。リセットすると、デバイスのペアリングが解除されます。
クリスハーバート

7

一部のモデルには欠陥がありますhttps : //code.google.com/p/android/issues/detail?id=180440

一方、私の場合の問題は、onDestroyメソッドで接続が適切に閉じられなかったことです。正しく閉じると、WiFiのオン/オフに関係なく、問題は発生しません。

btGatt.disconnect();
btGatt.close();

なぜclose必要なのですか?
IgorGanapolsky 2017

3
Bluetoothを複数回接続する場合は、正しいクローズ手順が重要です。私の経験では、別のUNBOUNDサービスでBle接続を実行して、手動で開始および停止できるようにするのが最適です。そして、mConnectedGatt.disconnect();を呼び出します。ble_device = null; あなたのinDestroy()で。私の場合、このパターンは問題なく安定して動作します。
medTech 2018年

4

私は同様の問題に直面していました。私の修正は

if (Build.VERSION.SDK_INT >= 23) {
  mBluetoothGatt = device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
} else {
  mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}

&切断後にcloseを呼び出します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.