契機:有一家公司給我面試題,要我做個安卓藍牙籤到系統。雖然這家公司後面做法不地道,要了我的代碼不給我下文,但是經過幾天的學習,也算是接觸新知識。
首先介紹一下藍牙:它是一種支持設備短距離通信(一般10m內)的無線電技術。能在包括移動電話、PDA、無線耳機、筆記本電腦、相關外設等衆多設備之間進行無線信息交換。
優點:連接精確,方便。缺點:範圍短。
接着,就着我的代碼來實現如何開啓,搜索,連接藍牙設備。
1,首先,你要設置兩個權限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
這兩個權限有什麼用?它們能夠讓你啓動藍牙操作,比如你的藍牙能夠搜索和被搜索等等。
2,我們需要在我們的項目裏創建藍牙適配器。
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); if(btAdapter != null){ btAdapter.enable();//只要你的設備能夠支持藍牙,你就可以開啓藍牙設備 }
3,當然,如果你想讓你的藍牙設備可被搜索,你就應該開啓藍牙設備允許被搜索的意圖。
Intent allowIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); allowIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(allowIntent);
* ACTION_REQUEST_DISCOVERABLE //請求設備打開被搜索功能,如果你沒有打開藍牙設備,那麼系統也會發送對話框來讓你確認是否開啓藍牙設備。
* EXTRA_DISCOVERABLE_DURATION //你的藍牙設備可以被發現的時間段。在120秒--300秒之內。我查一些較舊的工具書,有說可以隨意設置的,但是在4.0版本以後的設備就是在120--300之內,4.0之前的版本是否可以隨意設置,我確實沒試驗過。歡迎指正。
4,好,接着就是註冊廣播來完成搜索設備和完成後又要怎麼做。
這一塊,我把這兩個廣播意圖註釋後再讓藍牙適配器去搜索藍牙設備,一個也搜索不出來。
由此可見這兩個廣播意圖的作用纔是讓藍牙設備去準備搜索前和搜索後的動作,缺少ACTION_FOUND這個動作,藍牙適配器不會去搜索設備,ACTION_DISCOVERY_FINISHED決定了搜索完設備後適配器怎麼做。
//註冊發現設備廣播以及完成搜索廣播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(receiver, filter); filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(receiver, filter);
//
private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //EXTRA_DEVICE 獲取到意圖中其他藍牙設備的常量,比如設備名,地址。 if (device.getBondState() != BluetoothDevice.BOND_BONDED) { //這個if的意思是如果你搜索的藍牙設備的信息和已經與你的設備綁定的藍牙設備不同的話,就去執行下面的操作:把這些信息保存到ArrayList容器裏,並更新一下顯示這些藍牙信息的適配器,但此適配器是與ListView搭配的適配器,不是藍牙適配器。 DeviceInfo curInfo = new DeviceInfo(device.getName(), device.getAddress()); deviceInfos.add(curInfo); mdAdapter.notifyDataSetChanged(); } } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { //這個就更好理解了,如果搜索完了,就彈個土司顯示一下而已。 Toast.makeText(MainActivity.this, "搜索結束或未搜索到設備", Toast.LENGTH_SHORT).show(); } } };
5,接着正式讓藍牙適配器去搜索周邊已經開啓的藍牙設備。
btAdapter.startDiscovery();
6,接着就是你把搜索到的藍牙設備保存到ArrayList容器並顯示到你的ListView上,這個不贅述。
/****/
/****/
/****/
接着我們來談談藍牙設備之間如何連接以及傳送數據。
1,首先要講講UUID。
什麼是UUID:
UUID含義是通用唯一識別碼 (Universally Unique Identifier),這 是一個軟件建構的標準,也是被開源軟件基金會 (Open Software Foundation, OSF) 的組織應用在分佈式計算環境 (Distributed Computing Environment, DCE) 領域的一部分。
說白了,就是打電話時你能看到電話號碼,你知道是誰打來的。
這裏用到的UUID是這個:
UUID CONNECTUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
2,連接和接受連接設備
你需要知道這兩個東西:
BluetoothServerSocket //藍牙服務監聽端口
BluetoothSocket //藍牙監聽端口
(1)要主動連接的設備的代碼如下:
try { BluetoothDevice remoteDevice = btAdapter.getRemoteDevice(CONNECTADDRESS); socket = remoteDevice.createRfcommSocketToServiceRecord(UUID.fromString(CONNECTUUID)); //利用UUID開啓一個藍牙監聽端口socket使它來連接已經找到的藍牙設備。 btAdapter.cancelDiscovery();//停止搜索設備,提高資源優化 socket.connect();//連接藍牙設備 //調用連接的方法後,你的應用處於暫停狀態直到你要連接的設備開啓與你的連接或取消連接。 } catch { //這裏可能會拋出異常,所以要try和catch。 }
(2)要接受連接的設備的代碼:
try { BluetoothServerSocket mServerSocket = bthAdapter.listenUsingRfcommWithServiceRecord(OUTCONNECTNAME, CONNECTUUID); //OUTCONNECTNAME,String類型的連接名字,相當與一個次要的標識,隨意填寫,不過建議不要用中文。CONNECTUUID這個UUID一定要跟連接這臺設備的UUID是一樣的,就像打電話,打過來的號碼明明是小王,說話的卻是不認識的,這樣就要考慮安全性了。其實UUID就是爲了連接安全而設置的。 } catch { //拋出異常 } try { BluetoothSocket mSocket = mServerSocket.accept(); //調用accept()方法兩臺要連接的設備就會匹配,連接,只要連接成功,我們就可以互相傳送數據,當然在連接過程中應用處於暫停狀態,除非你停止連接或連接出錯。 }
catch
{
//拋出異常
}
3.傳輸數據
其實當你已經知道怎麼匹配和連接,接下來你就已經知道如何傳送數據。
關於這一塊我就將代碼貼出來就好了,畢竟傳輸的也不是什麼大數據。
//傳送部分:
//獲取向另一部藍牙設備傳輸數據的outputStream對象
OutputStream os = socket.getOutputStream(); Date currDate = new Date(System.currentTimeMillis());//獲取當前時間 String timeNow = timeFormatter.format(currDate); String message = btAdapter.getName()+"-"+btAdapter.getAddress()+"-"+timeNow; os.write(message.getBytes()); os.close();//關流
//接受部分:
InputStream is = mSocket.getInputStream();//得到流 byte[] buffer = new byte[1024]; int len = 0; ByteArrayBuffer arraybuffer = new ByteArrayBuffer(8000); while((len = is.read(buffer)) != -1){ arraybuffer.append(buffer, 0, len); } is.close(); //裁剪傳過來的數據 String strdown = new String(arraybuffer.toByteArray(), 0,arraybuffer.length()); String[] downsplit = strdown.split("-");
好了,感謝你看到這裏。歡迎牛人指出其中的錯誤。