Android藍牙通訊

Android爲藍牙設備之間的通訊封裝好了一些調用接口,使得實現Android的藍牙通訊功能並不困難。可經過UUID使兩個設備直接創建鏈接。html

具體步驟:java

1. 獲取BluetoothAdapter實例,註冊一個BroadcastReceiver監聽藍牙掃描過程當中的狀態變化服務器

 

?
1
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
?
1
2
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
?
1
 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
 
             // When discovery finds a device
             if (BluetoothDevice.ACTION_FOUND.equals(action))
             {
                 // Get the BluetoothDevice object from the Intent
                 // 經過EXTRA_DEVICE附加域來獲得一個BluetoothDevice設備
                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 
                 // If it's already paired, skip it, because it's been listed already
                 // 若是這個設備是未曾配對過的,添加到list列表
                 if (device.getBondState() != BluetoothDevice.BOND_BONDED)
                 {
                     list.add( new ChatMessage(device.getName() + "\n" + device.getAddress(), false ));
                     clientAdapter.notifyDataSetChanged();
                     mListView.setSelection(list.size() - 1 );
                 }
             // When discovery is finished, change the Activity title
             }
             else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
             {
                 setProgressBarIndeterminateVisibility( false );
                 if (mListView.getCount() == 0 )
                 {
                     list.add( new ChatMessage( "沒有發現藍牙設備" , false ));
                     clientAdapter.notifyDataSetChanged();
                     mListView.setSelection(list.size() - 1 );
                 }
             }
         }
     };

 

2. 打開藍牙(enable),並設置藍牙的可見性(能夠被其它設備掃描到,客戶端是主動發請求的,可不設置,服務端必須設置可見)。socket

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        if (mBluetoothAdapter != null ) {
     if (!mBluetoothAdapter.isEnabled()) {
         // 發送打開藍牙的意圖,系統會彈出一個提示對話框
         Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
         startActivityForResult(enableIntent, RESULT_FIRST_USER);
         
         // 設置藍牙的可見性,最大值3600秒,默認120秒,0表示永遠可見(做爲客戶端,可見性能夠不設置,服務端必需要設置)
         Intent displayIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
         displayIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0 );
         startActivity(displayIntent);
         
         // 直接打開藍牙
         mBluetoothAdapter.enable();
     }
}

 

3. 掃描,startDiscovery()方法是一個很耗性能的操做,在掃描以前能夠先使用getBondedDevices()獲取已經配對過的設備(可直接鏈接),避免沒必要要的消耗。ide

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   private void scanDevice() {
     // TODO Auto-generated method stub
     if (mBluetoothAdapter.isDiscovering()) {
         mBluetoothAdapter.cancelDiscovery();
     } else {
         
         // 每次掃描前都先判斷一下是否存在已經配對過的設備
         Set<bluetoothdevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
         if (pairedDevices.size() > 0 ) {
             for (BluetoothDevice device : pairedDevices) {
                 list.add( new ChatMessage(device.getName() + "\n" + device.getAddress(), true ));
             }
         } else {
                 list.add( new ChatMessage( "No devices have been paired" , true ));
                 clientAdapter.notifyDataSetChanged();
                 mListView.setSelection(list.size() - 1 );
          }             
              /* 開始搜索 */
              mBluetoothAdapter.startDiscovery();
     }
}</bluetoothdevice>

 

4. 經過Mac地址發送鏈接請求,在這以前必須使用cancelDiscovery()方法中止掃描。性能

 

?
1
2
3
4
         mBluetoothAdapter.cancelDiscovery();
 
// 經過Mac地址去嘗試鏈接一個設備
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(BluetoothMsg.BlueToothAddress);

 

5. 經過UUID使兩個設備之間創建鏈接。網站

客戶端:主動發請求ui

 

?
1
2
3
4
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString( "00001101-0000-1000-8000-00805F9B34FB" ));
                
// 經過socket鏈接服務器,這是一個阻塞過程,直到鏈接創建或者鏈接失效
socket.connect();

 

服務端:接受一個請求spa

 

?
1
2
3
4
5
6
7
BluetoothServerSocket mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
                    UUID.fromString( "00001101-0000-1000-8000-00805F9B34FB" ));      
            
/* 接受客戶端的鏈接請求 */
// 這是一個阻塞過程,直到創建一個鏈接或者鏈接失效
// 經過BluetoothServerSocket獲得一個BluetoothSocket對象,管理這個鏈接
BluetoothSocket socket = mServerSocket.accept();

 

6. 經過InputStream/outputStream讀寫數據流,已達到通訊目的。.net

 

?
1
2
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
?
1
2
3
4
5
6
7
InputStream is = null ;
try {
     is = socket.getInputStream();
} catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
}

 

7. 關閉全部線程以及socket,並關閉藍牙設備(disable)。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
         if (mClientThread != null ) {
     mClientThread.interrupt();
     mClientThread = null ;
}
if (mReadThread != null ) {
     mReadThread.interrupt();
     mReadThread = null ;
}
try {
     if (socket != null ) {
         socket.close();
         socket = null ;
     }
} catch (IOException e) {
     // TODO: handle exception
}
?
1
2
3
4
5
6
         if (mBluetoothAdapter != null ) {
     mBluetoothAdapter.cancelDiscovery();
     // 關閉藍牙
     mBluetoothAdapter.disable();
}
unregisterReceiver(mReceiver);


主要步驟就是這些,爲了可以更好的理解,我將服務器端和客戶端的代碼分開來寫了兩個程序,下載地址:http://download.csdn.net/detail/visionliao/8417235

 

結伴旅遊,一個免費的交友網站:www.jieberu.com

推推族,免費得門票,遊景區:www.tuituizu.com

相關文章
相關標籤/搜索