2016-07-29 86 views
3

通常の状況では正常にBLEデバイスに接続できます。私がしたいのは、デバイスへの接続が失われたり、確立された接続が失われたりするなど、異常な状況を処理することです。Android:BLE接続の捕捉に失敗/切断しますか?

私はCyPress BLEモジュールを使用していますこれをテストし、私がやっているテストの1つは、モジュールから電力を取り除くことです。ただし、onConnectionStateChangeは呼び出されません。私がそれに反応するのは成功した接続だけです。接続しようとして何時間も過ごし、明らかにあきらめることはありません。私は、接続の試みの遅延キャンセルを行うだろうが、(私が知っている)BluetoothDeviceの接続試行をキャンセルする方法はありません!私が言う限り、バッテリーが消耗するまで試し続けます。

ここで、私のonConnectionStateChangeは、Gattコールバックの内部にあります。私はどのような種類の接続状態の変更を含むコールバックを捕まえてログに記録しようとしていることに注意してください。これはコードがアクティビティ自体にないことに注意してください。それはシングルトンによって保持されるオブジェクト内にあります。

@Override 
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 
     mGatt = gatt; 
     Logy.CallPrint(LOGY_ENABLE, CLASSNAME, "Status: "+status+ " Newstate: "+newState); 
     switch(status) 
     { 
      case BluetoothGatt.GATT_SUCCESS: 
       mReconnectAttempts = MAX_ATTEMPTS; 

       if(newState == BluetoothGatt.STATE_CONNECTED) 
       { 
        DispatchEvent(Event.Type.BT_ON_CONNECT); 
        bIsConnected = true; 
        gatt.discoverServices(); 
       } else if (newState == BluetoothGatt.STATE_DISCONNECTED) 
       { 
        DispatchEvent(Event.Type.BT_ON_DISCONNECT); 
        bIsConnected = false; 
       } 
       break; 
      default: 
       if(newState == BluetoothGatt.STATE_DISCONNECTED) 
       { 
        bIsConnected = false; 
        if(mReconnectAttempts > 0) 
        { // if we have attempts left, auto attempt to reconnect 
         DispatchEvent(Event.Type.BT_RECONNECTING); 
         mReconnectAttempts--; 
         gatt.connect(); 
         bIsConnected = false; 
        } 
        else 
        { 
         mReconnectAttempts = MAX_ATTEMPTS; 
         DispatchEvent(Event.Type.BT_ON_CONNECT_FAIL); 
         bIsConnected = false; 
        } 
       } else { 
        Logy.CallPrint(LOGY_ENABLE, CLASSNAME, "onConnectionStateChange: Failed?"); 
       } 
     } 

     super.onConnectionStateChange(gatt, status, newState); 
    } 

が切断を検出することができない(私は複数のアクティビティ間の接続を維持したいことは)私はアプリがBLEデバイスに接続されて示すプログレスダイアログを見せるように、他の場所で私のコードでは問題です。さて、このダイアログは "On Connect Fail"というイベントが決して投げられないので、決して消えません。

を失った接続が考慮される前に2つのデータ・パケットPDUを受信間の最大時間を定義するパラメータ:

答えて

6

は、私が何を探していることBluetooth LE specificationsに従ってされBluetooth Supervision timeoutだと思いますAndroidのデフォルトSupervision timeooutは20秒に設定されています(Androidバージョン&デバイスに応じて異なります)。たとえば、hereは、Android 5.1のSupervision Timeoutの値です。

は、このパラメータを設定するには何のAPIはありませんので、あなたは20秒で、あなたのBLEモジュール

2

まず電源をオフにした後の状態BluetoothGatt.STATE_DISCONNECTEDonConnectionStateChangeコールバックを取得する(Androidのバージョン&デバイスに応じて)待機する必要があります、確立された接続が切断された場合、スーパーバイザのタイムアウトが経過すると切断状態変更イベントが発生するはずです。それ以外の場合、Androidにバグがあります。

これで接続試行について説明します。

connectGattでBluetoothGattオブジェクトを作成し、auto connectパラメータをtrueに指定するか、既存のBluetoothGattオブジェクトでconnectメソッドを実行すると、電話機は常にデバイスに接続しようとする状態になります。 gattオブジェクトの切断または終了を呼び出すまで何らかの理由で切断された場合は、デバイスに再接続してください。

しばらくして接続を中止したい場合は、起動時にgattオブジェクトの切断を呼び出すタイマーを設定します(これがもう必要ない場合は閉じる)。

また、newStateが切断されたときのonConnectionStateChangeのstatusパラメータは、明確に定義されていません。古いAndroidバージョンでは通常0または133、新しいバージョンではしばしばBluetooth規格の切断理由のエラーコードが含まれています。

また、以前は接続された状態変更イベントが発生していない切断状態変更イベントが発生した場合、内部Bluetoothスタックで何か問題が発生したことを示します(通常、タイムアウト後に状態変更イベントを切断する)。その後、gattオブジェクトを閉じて後でやり直すことをお勧めします。

+0

私の関心事は、あなたがBluetoothDeviceしか持っておらず、それを接続している期間です。切断を呼び出すBluetoothGattはありません。長い間「デバイスに接続しようとしました」という後にonConnectionStateChangeは呼び出されません。また、これが長すぎる場合でもconnectonの試行をキャンセルする明白な方法はありませんでした。別のデバイスとの接続を開始することによって、他のデバイスとのこの前回の接続試行も最終的には完了します。 –

4

この回答はEmilからの回答に沿っています。

私は、Android 6.0.1(Marshmellow:API23)を再生モトG4上で実行されている単一の活動でのテストアプリをコード化された私は、いくつかのログを投稿するつもりだったレアードのBL600

に基づいており、周辺機器を - しかし、彼らフォーマットはあまりうまくいかないので、結果を説明します。


はいつものように、周辺機器は、アドバタイズと中央がスキャン、およびデバイスのインスタンスを得ます。

質問の形式は、最初の接続が行われている方法を正確に述べるが、のは、それは「自動接続」で偽であると仮定することはできません

mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback); 

(これはテストで使用される接続の唯一のスタイルです質問で述べたように、これは、BluetoothGattのインスタンスを与え、

アプリ)が、イベントはその後、コールバックによる非同期に報告され、 が、どの接続イベントがあっても前にdisconnect()を呼び出すためにBluetoothGattのインスタンスもあります発生した。

disconnect()状態のためのAPIドキュメント - 確立された接続「

BluetoothGatt.disconnect() を切断した後、特に一部、または現在進行中の接続の試みをキャンセルします。

はGATTのリソースを解放するには、切断した後、テストアプリケーションはまた、常に

mBluetoothGatt.close();

は、ここではいくつかの異なるシナリオ

  1. device.connectGatt()されるコール - 周辺広告 - 接続が確立された後、mBluetoothGatt.disconnect()およびclose()が続きます。

    結果:これは正常な正常接続であり、中央デバイスはコード内の接続を閉じます。コールバックイベントは期待どおりに受信されます。 Centralがコードを切断すると、基盤となるBluetoothサービスが切断され、PeripheralがDisconnectionイベントを取得します。

  2. device.connectGatt() - 周辺広告 - 接続メニュ - に続いてペリフェラルをオフにしました。

    結果:これは正常な接続です。期待通りにコールバックイベントが発生し、続いて接続がPeripheralによって破損しました。ペリフェラルは、BleGapSvcInitでの優先接続のタイムアウトを示し、これは接続パラメータアップデートでCentralによって確認されます。 Peripheralが接続を切断すると、Connection監督タイムアウト直後にCentralでDisconnectionイベントが発生します。 (監視のタイムアウトが8秒と4秒で繰り返されます)。

  3. device.connectGatt() - ただし、周辺機器が広告を停止したため、接続試行がタイムアウトすることができました。

    結果:(これは質問の特定のシナリオです)30秒後に、電話機のBluetoothサービスの接続タイムアウトがおそらく の場合、新しい接続状態が切断されたことを示すonConnectionStateChangeイベントがあります。 )ステータス133. mBluetoothGatt.close()を呼び出すことを覚えていなければ、インターフェイスリークが発生し、次のクライアントインターフェイスで後で接続が行われます。

  4. device.connectGatt() - 周辺機器はまだ宣伝されていますが、接続はmBluetoothGatt.disconnect()およびclose()を使用して200ms後にキャンセルされました。

    結果:(このケースは実際のアプリケーションでは起こりそうにない場合、最も興味深いものでした) 実際に周辺機器に接続したことがあります。接続を見た後、切断されました。アプリケーションが コールバックのこれらのイベントを参照していない場合でも。時には、アプリケーションに関する限り、アプリケーションは切断され、基本的なBluetooth電話サービス が周辺機器に接続されていて、タイムアウトするまで私のテストで数分間接続されました。 - BTサービス、つまりペリフェラルをオフにしました。

+0

#4は私の人生を非常に困難にしています。私は一度に最大7つのデバイスに接続しています。その多くを使用している場合は、10のうち1つが常に発生します。これらのすべてのタイプがここに記載されているのを見てうれしいです。 –

関連する問題