成功連線至藍牙後
每部裝置
CANNOT TRANSLATE
BluetoothSocket
。您現在可以
可在裝置間分享資訊。使用 BluetoothSocket
時,系統會採用
轉移資料的程序如下:
取得
InputStream
和 處理傳輸作業的OutputStream
經由通訊端getInputStream()
和getOutputStream()
、 。使用下列指令將資料讀取及寫入串流
read(byte[])
和write(byte[])
。
當然,還有實作細節需要考量。我們特別準備
使用專屬執行緒從串流讀取及寫入資料。
這一點非常重要,因為 read(byte[])
和 write(byte[])
方法皆有
就會發出封鎖呼叫。read(byte[])
方法會遭到封鎖,直到有元件出現為止
從串流中讀取資料write(byte[])
方法通常不會封鎖,但這會導致
可以禁止遠端裝置未呼叫 read(byte[])
時使用流量控制
並讓中繼緩衝區變滿因此
應在執行緒中分配主要迴圈,以便從 InputStream
讀取。
您可以在執行緒中使用獨立的公開方法,開始寫入
OutputStream
。
範例
以下範例說明如何在兩個裝置之間轉移資料 已透過藍牙連線:
private const val TAG = "MY_APP_DEBUG_TAG"
// Defines several constants used when transmitting messages between the
// service and the UI.
const val MESSAGE_READ: Int = 0
const val MESSAGE_WRITE: Int = 1
const val MESSAGE_TOAST: Int = 2
// ... (Add other message types here as needed.)
class MyBluetoothService(
// handler that gets info from Bluetooth service
private val handler: Handler) {
private inner class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() {
private val mmInStream: InputStream = mmSocket.inputStream
private val mmOutStream: OutputStream = mmSocket.outputStream
private val mmBuffer: ByteArray = ByteArray(1024) // mmBuffer store for the stream
override fun run() {
var numBytes: Int // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
while (true) {
// Read from the InputStream.
numBytes = try {
mmInStream.read(mmBuffer)
} catch (e: IOException) {
Log.d(TAG, "Input stream was disconnected", e)
break
}
// Send the obtained bytes to the UI activity.
val readMsg = handler.obtainMessage(
MESSAGE_READ, numBytes, -1,
mmBuffer)
readMsg.sendToTarget()
}
}
// Call this from the main activity to send data to the remote device.
fun write(bytes: ByteArray) {
try {
mmOutStream.write(bytes)
} catch (e: IOException) {
Log.e(TAG, "Error occurred when sending data", e)
// Send a failure message back to the activity.
val writeErrorMsg = handler.obtainMessage(MESSAGE_TOAST)
val bundle = Bundle().apply {
putString("toast", "Couldn't send data to the other device")
}
writeErrorMsg.data = bundle
handler.sendMessage(writeErrorMsg)
return
}
// Share the sent message with the UI activity.
val writtenMsg = handler.obtainMessage(
MESSAGE_WRITE, -1, -1, mmBuffer)
writtenMsg.sendToTarget()
}
// Call this method from the main activity to shut down the connection.
fun cancel() {
try {
mmSocket.close()
} catch (e: IOException) {
Log.e(TAG, "Could not close the connect socket", e)
}
}
}
}
public class MyBluetoothService {
private static final String TAG = "MY_APP_DEBUG_TAG";
private Handler handler; // handler that gets info from Bluetooth service
// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
public static final int MESSAGE_READ = 0;
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_TOAST = 2;
// ... (Add other message types here as needed.)
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer; // mmBuffer store for the stream
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();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
mmBuffer = new byte[1024];
int numBytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
while (true) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = handler.obtainMessage(
MessageConstants.MESSAGE_READ, numBytes, -1,
mmBuffer);
readMsg.sendToTarget();
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
}
// Call this from the main activity to send data to the remote device.
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
// Share the sent message with the UI activity.
Message writtenMsg = handler.obtainMessage(
MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
writtenMsg.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Error occurred when sending data", e);
// Send a failure message back to the activity.
Message writeErrorMsg =
handler.obtainMessage(MessageConstants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString("toast",
"Couldn't send data to the other device");
writeErrorMsg.setData(bundle);
handler.sendMessage(writeErrorMsg);
}
}
// Call this method from the main activity to shut down the connection.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the connect socket", e);
}
}
}
}
建構函式取得必要的串流後,執行緒會等待資料
通過 InputStream
。當 read(byte[])
傳回下列來源的資料時
在串流中,資料會透過成員傳送到主要活動
父項類別中的 Handler
。討論串
然後等待從 InputStream
讀取更多位元組。
如要傳送傳出資料,您需要從主執行緒呼叫執行緒的 write()
方法
活動並傳入要傳送的位元組。這個方法會呼叫 write(byte[])
來
傳送資料到遠端裝置。如果
呼叫時擲回 IOException
write(byte[])
,執行緒會傳送浮動式訊息至主要活動,說明
裝置無法將指定位元組傳送至另一端的使用者
(已連線) 裝置。
執行緒的 cancel()
方法可讓您隨時終止連線
關閉 BluetoothSocket
。完成後一律呼叫這個方法
並且使用藍牙連線
如需藍牙 API 的使用示範,請參閱 Bluetooth Chat 範例 應用程式 。