私たちが作成したデバイスで Bluetooth を使用して話すことを目的とした Android Bluetooth アプリを開発しています。Android 3 以降のほとんどのデバイスですべてが正常に機能するようになりましたが、Android 2.3.x (これは最小要件です) では動作しないようです。他の人のように振る舞う。Huawei Ascend P1 でも同じ動作を再現しました。
何が起こるかというと、Android 側ではすべてが正常に動作し、デバイスに接続し、ペアリングされていない場合はペアリング要求が行われ、インとアウトストリームの両方を取得しますが、それらを使用すると、自分自身に話しかけているように動作しますループバック。出力ストリームに書き込まれたものはすべて、入力ストリームで読み取られます。もちろん、デバイスには何も表示されません (Android フォンが接続されていることさえ認識していないようです)。
これが私のソースからのコードサンプルです(ほとんどはAndroidのドキュメントに記載されているとおりです):
接続スレッド:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
btSpeaking = true;
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
tmp = device.createInsecureRfcommSocketToServiceRecord(BluetoothUuid.declareUuid.getUuid());
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
mConnected = new ConnectedThread(mmSocket);
mConnected.start();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
スレッドを読む:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
WSLog.e(tag, e.getMessage(), e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
try {
writeSocket(RESET, empty);
} catch (IOException e1) {
return;
}
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
for (int size = 0; size < framesize;) {
int read = mmInStream.read(frame, size, frame.length - size);
if (read < 0) {
return;
}
size = size + read;
}
} catch (IOException e) {
return;
}
}
}
書き込みソケット:
private void writeSocket(byte comm, byte[] data) throws IOException {
ByteBuffer bf = ByteBuffer.allocate(1 + data.length);
bf.put(PROTO);
bf.put(comm);
bf.put(data);
mmOutStream.write(bf.array());
}
明らかに間違ったことをしていないことを本当に願っていますが、なぜうまくいかないのかわからなかったので、助けを求めるしかありませんでした。
ありがとう、マーティン