Bluetooth 経由でデバイスに接続するプロジェクトがあります。BluetoothSocket.connect()
以前はかなり確実に機能していましたが、今では毎回呼び出しに失敗します。(まあ、私は 4 時間にわたって何千回も試行するうちに接続できました。)BluetoothSocket
デバイス自体を取得する際の一般的な変更を除いて、ほとんどのコードは API の標準サンプル チャット コードから取られています。 :
Method m = device.getClass().getMethod(
"createRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
aBluetoothSocket
が取得されると実行される対象のメソッドは次のとおりです。
public void run() {
setName("ConnectThread" + mSocketType);
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
mmSocket.connect();
} catch (Exception e) {
Log.e(TAG, "Connection to " + mmDevice.getName() + " at "
+ mmDevice.getAddress() + " failed:" + e.getMessage());
// Close the socket
try {
mmSocket.close();
} catch (Exception e2) {
Log.e(TAG, "unable to close() " + mSocketType
+ " socket during connection failure", e2);
}
connectionFailed(e.getMessage());
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothChatService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
関連するログ エントリ (呼び出し中に例外がキャッチされたときに出力されるconnect()
) は次のとおりです。
11-30 10:23:51.685: E/BluetoothChatService(2870): 00:06:66:42:8E:01 での ZYNO-700091 への接続に失敗しました: 読み取りに失敗しました。ソケットが閉じている可能性があります。読み取り ret: -1
このエラーは、ときどき発生していました。私は積極的な再接続システムを持っています - それは基本的に接続するまで何度も何度も接続を叩き、切断されると再び叩き始めます。そのため、接続スレッドを強制終了し、常にゼロから開始します。そこに問題がある可能性があると考えていました-おそらくマルチスレッドの問題か、ソケットのクリーンアップ/初期化の処理に問題があるかもしれません。ただし、その場合でも、接続試行が失敗するまでシステムが起動しないため、最初の接続試行が成功することを期待します。
例外をスローするソースコードを調べました。問題は、基礎となるInputStream
データがないことです。もちろん、それは本当の答えではなく、それに向けた一歩にすぎません。ストリームにデータがないのはなぜですか?
私は潜在的な問題についてオープンマインドを保とうとしています。私はBluetoothSocket
適切に取得していますか?以前は断続的な問題でしたが、現在はほぼ一定の問題であるという事実から、マルチスレッドが疑われますが、C++ と比較して Java では比較的単純なトピックです。さらに、このコードの大部分 (特に、スレッドの同期を処理する部分) は、サンプル コードから直接引用したものです。
反対側のデバイスは組み込みの Bluetooth デバイスであるため、その側から問題をデバッグできる見込みはあまりありません。
更新 ===========================
OSのアップグレードが原因である可能性があることに気づきました(Galaxy Nexus電話で実行しています-テストするためにいくつかあります)。だから私は4.0.4で新しい電話を開梱し、それはうまくいきました! それから戻って、両方とも 4.2 を実行している 2 台の元のテスト用電話でテストしました。奇妙なことに、今ではそれらの電話でも動作します。私はこれを再び機能させるために何かをしたと言いたいのですが、そうしませんでした。私はまだ当惑しており、本当に必要なときにこれが機能するのではないかと疑っています.
4.0.4 を使用して何らかの方法で接続すると、サーバー モジュールの状態が適切に設定され、4.2 デバイスを受け入れるようになる可能性があるのではないでしょうか? 暗闇の中でのショットだと思います...
更新 2 ===========================
ペアリングを解除して再ペアリングすると、デバイスが接続できることがわかりました。これは回避策ですが、何もしないよりはましです。