1. 程式人生 > >Android藍芽搜尋裝置,向其傳送資料並接收

Android藍芽搜尋裝置,向其傳送資料並接收

通過藍芽傳輸資料Socket類似。在網路中使用SocketServerSocket控制客戶端和服務端的資料讀寫。而藍芽通訊也由客戶端和服務端Socket來完成。藍芽客戶端SocketBluetoothSocket,藍芽服務端SocketBluetoothServerSocket。這兩個類都在包中

無論是BluetoothSocket,還是BluetoothServerSocket,都需要一個UUID(全域性唯一識別符號,UniversallyUnique Identifier).格式如下:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

UUID的格式被分成5段,其中中間3段的字元數相同,都是4,第1段是8個字元,最後一段是12個字元。所以UUID實際上是一個8-4-4-4-12的字串。

UUID相當於Socket的埠,而藍芽地址相當於Socket的IP。

效果圖:

搜尋裝置:


向一個裝置傳送資料

另一臺裝置收到了資訊,並顯示出來了:


——————————————————————————————————————

值得注意的是在建立連線的時候,裝置、輸出流、介面等變數需要是全域性變數,否則方法執行完,就斷開連線了。然後進行第二次傳送資料就接收不到了。

下面我們就來做這個demo吧,在測試的時候需要手動開啟藍芽,如果需要自動開啟藍芽請檢視我上一篇部落格。

首先,必不可少的就是新增兩個藍芽許可權:

[java] view plain copy  print?
  1. <uses-permission android:name="android.permission.BLUETOOTH"/>  
  2.     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>  


佈局檔案,由一個搜尋按鈕和一個listview組成,用於顯示搜到的裝置

activity_main.xml:

[java] view plain
 copy  print?
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     android:layout_width="fill_parent"
  3.     android:layout_height="fill_parent"
  4.     android:orientation="vertical" >  
  5.     <Button  
  6.         android:layout_width="fill_parent"
  7.         android:layout_height="wrap_content"
  8.         android:onClick="onClick_Search"
  9.         android:text="搜尋" />  
  10.     <ListView  
  11.         android:id="@+id/lvDevices"
  12.         android:layout_width="fill_parent"
  13.         android:layout_height="wrap_content" />  
  14. </LinearLayout>  

程式碼檔案

MainActivity.Java:

[java] view plain copy  print?
  1. package com.oak.learnbluetoothsocket;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.io.OutputStream;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7. import java.util.Set;  
  8. import java.util.UUID;  
  9. import android.os.Bundle;  
  10. import android.os.Handler;  
  11. import android.os.Message;  
  12. import android.app.Activity;  
  13. import android.bluetooth.BluetoothAdapter;  
  14. import android.bluetooth.BluetoothDevice;  
  15. import android.bluetooth.BluetoothServerSocket;  
  16. import android.bluetooth.BluetoothSocket;  
  17. import android.content.BroadcastReceiver;  
  18. import android.content.Context;  
  19. import android.content.Intent;  
  20. import android.content.IntentFilter;  
  21. import android.view.View;  
  22. import android.widget.AdapterView;  
  23. import android.widget.AdapterView.OnItemClickListener;  
  24. import android.widget.ArrayAdapter;  
  25. import android.widget.ListView;  
  26. import android.widget.Toast;  
  27. publicclass MainActivity extends Activity implements OnItemClickListener {  
  28.     // 獲取到藍芽介面卡
  29.     private BluetoothAdapter mBluetoothAdapter;  
  30.     // 用來儲存搜尋到的裝置資訊
  31.     private List<String> bluetoothDevices = new ArrayList<String>();  
  32.     // ListView元件
  33.     private ListView lvDevices;  
  34.     // ListView的字串陣列介面卡
  35.     private ArrayAdapter<String> arrayAdapter;  
  36.     // UUID,藍芽建立連結需要的
  37.     privatefinal UUID MY_UUID = UUID  
  38.             .fromString("db764ac8-4b08-7f25-aafe-59d03c27bae3");  
  39.     // 為其連結建立一個名稱
  40.     privatefinal String NAME = "Bluetooth_Socket";  
  41.     // 選中傳送資料的藍芽裝置,全域性變數,否則連線在方法執行完就結束了
  42.     private BluetoothDevice selectDevice;  
  43.     // 獲取到選中裝置的客戶端串列埠,全域性變數,否則連線在方法執行完就結束了
  44.     private BluetoothSocket clientSocket;  
  45.     // 獲取到向裝置寫的輸出流,全域性變數,否則連線在方法執行完就結束了
  46.     private OutputStream os;  
  47.     // 服務端利用執行緒不斷接受客戶端資訊
  48.     private AcceptThread thread;  
  49.     @Override
  50.     protectedvoid onCreate(Bundle savedInstanceState) {  
  51.         super.onCreate(savedInstanceState);  
  52.         setContentView(R.layout.activity_main);  
  53.         // 獲取到藍芽預設的介面卡
  54.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
  55.         // 獲取到ListView元件
  56.         lvDevices = (ListView) findViewById(R.id.lvDevices);  
  57.         // 為listview設定字元換陣列介面卡
  58.         arrayAdapter = new ArrayAdapter<String>(this,  
  59.                 android.R.layout.simple_list_item_1, android.R.id.text1,  
  60.                 bluetoothDevices);  
  61.         // 為listView繫結介面卡
  62.         lvDevices.setAdapter(arrayAdapter);  
  63.         // 為listView設定item點選事件偵聽
  64.         lvDevices.setOnItemClickListener(this);  
  65.         // 用Set集合保持已繫結的裝置
  66.         Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();  
  67.         if (devices.size() > 0) {  
  68.             for (BluetoothDevice bluetoothDevice : devices) {  
  69.                 // 儲存到arrayList集合中
  70.                 bluetoothDevices.add(bluetoothDevice.getName() + ":"
  71.                         + bluetoothDevice.getAddress() + "\n");  
  72.             }  
  73.         }  
  74.         // 因為藍芽搜尋到裝置和完成搜尋都是通過廣播來告訴其他應用的
  75.         // 這裡註冊找到裝置和完成搜尋廣播
  76.         IntentFilter filter = new IntentFilter(  
  77.                 BluetoothAdapter.ACTION_DISCOVERY_FINISHED);  
  78.         registerReceiver(receiver, filter);  
  79.         filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);  
  80.         registerReceiver(receiver, filter);  
  81.         // 例項接收客戶端傳過來的資料執行緒
  82.         thread = new AcceptThread();  
  83.         // 執行緒開始
  84.         thread.start();  
  85.     }  
  86.     publicvoid onClick_Search(View view) {  
  87.         setTitle("正在掃描...");  
  88.         // 點選搜尋周邊裝置,如果正在搜尋,則暫停搜尋
  89.         if (mBluetoothAdapter.isDiscovering()) {  
  90.             mBluetoothAdapter.cancelDiscovery();  
  91.         }  
  92.         mBluetoothAdapter.startDiscovery();  
  93.     }  
  94.     // 註冊廣播接收者
  95.     private BroadcastReceiver receiver = new BroadcastReceiver() {