在AndroidSDK sample中給出了一個藍芽聊天的範例程式碼,本文只是略作修改變成一個簡單的伺服器和用戶端模式的應用,以適應在遊戲開發中一對一關聯的資料轉送。
由於遊戲中的藍芽設定在新線程中發生,所以採用Handler的方式將藍芽的狀態以及讀取資訊傳輸給顯示Activity。
1 開啟藍芽,包括xml中的配置:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH" />
//擷取藍芽適配器BluetoothAdapter btAdapter = BlueToothService.getInstance().getBtAdapter();//開啟藍芽if (!btAdapter.isEnabled()) { Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, ConstantsUtil.ENABLE_BLUETOOTH);}
2 在當前Activity中擷取藍芽開啟結果,並根據具體情況對藍芽進行處理
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case ConstantsUtil.ENABLE_BLUETOOTH: if (resultCode == Activity.RESULT_OK) { bluetoothProcess(PSystem.isServer); } else { finish(); } } }public void bluetoothProcess(boolean isServer) {BlueToothService.getInstance().setsHandler(mHandler);if (isServer) {//如果是藍芽伺服器,則需要開啟探索服務,並啟動藍芽伺服器if(btAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 180);startActivity(discoverableIntent);}BlueToothService.getInstance().start();} else {//如果是藍芽用戶端則掃描周圍可用的藍牙裝置blueToothNames = new ArrayList<String>();blutToothDevices = new ArrayList<BluetoothDevice>();//添加過濾器,並註冊廣播,用於監聽藍芽發現資訊IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);this.registerReceiver(mReceiver, filter);filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);this.registerReceiver(mReceiver, filter);//開始掃描doDiscovery();}}public void doDiscovery() { if (btAdapter.isDiscovering()) { btAdapter.cancelDiscovery(); } btAdapter.startDiscovery(); }
3 藍芽廣播接收器
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (BluetoothDevice.ACTION_FOUND.equals(action)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if(device.getName() != null && !device.getName().trim().equals("")) {blueToothNames.add(device.getName());blutToothDevices.add(device);}} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {btAdapter.cancelDiscovery();TestActivity.this.unregisterReceiver(this);}}};
4 以上是藍芽基本配置和發現。現在進行藍芽監聽和串連:
藍芽伺服器監聽代碼:
public void start() {BluetoothServerSocket serverSocket = null;try {serverSocket = btAdapter.listenUsingRfcommWithServiceRecord("JumpForMeApp", MY_UUID_SECURE);changeState(ConstantsUtil.BT_STATE_LISTEN);btSocket = serverSocket.accept();} catch (IOException e) {} finally {try {serverSocket.close();} catch (IOException e) {}} if(btSocket != null) {changeState(ConstantsUtil.BT_STATE_CONNECTED);}}
用戶端串連代碼:
public void connect(BluetoothDevice device) {try {btAdapter.cancelDiscovery();btSocket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);changeState(ConstantsUtil.BT_STATE_CONNECTING);btSocket.connect();} catch (IOException e) {}changeState(ConstantsUtil.BT_STATE_CONNECTED);}
5 利用藍芽進行訊息傳遞,建立新的線程來處理讀寫操作(見BluetoothChat Sample中的ConnectedThread):
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;try {tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch (IOException e) {Log.e(TAG, "temp sockets not created", e);}mmInStream = tmpIn;mmOutStream = tmpOut;}public void run() {byte[] buffer = new byte[1024];int bytes;while (true) {try {bytes = mmInStream.read(buffer);if(transHandler != null) {//通知數據傳輸處理器transHandler.sendMessage(transHandler.obtainMessage(ConstantsUtil.BT_READ, bytes, -1, buffer));}} catch (IOException e) {Log.e(TAG, "disconnected", e);break;}}}public void write(byte[] buffer) {try {mmOutStream.write(buffer);} catch (IOException e) {Log.e(TAG, "Exception during write", e);}}public void cancel() {try {mmSocket.close();} catch (IOException e) {Log.e(TAG, "close() of connect socket failed", e);}}}