設置藍牙設備 尋找局域網內可能或者匹配的設備 鏈接設備 設備之間的傳輸數據
首先經過調用靜態方法getDefaultAdapter()獲取藍牙適配器BluetoothAdapter,假設返回爲空,則沒法繼續執行了。好比:java
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
其次,調用isEnabled()來查詢當前藍牙設備的狀態,假設返回爲false,則表示藍牙設備沒有開啓。接下來你需要封裝一個ACTION_REQUEST_ENABLE請求到intent裏面,調用startActivityForResult()方法使能藍牙設備。好比:android
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
使用BluetoothAdapter類裏的方法。你可以查找遠端設備(大概十米之內)或者查詢在你手機上已經匹配(或者說綁定)的其它設備了。編程
固然需要肯定對方藍牙設備已經開啓或者已經開啓了「被發現使能」功能(對方設備是可以被發現的是你可以發起鏈接的前提條件)。假設該設備是可以被發現的。會反饋回來一些對方的設備信息,比方名字、MAC地址等。利用這些信息,你的設備就可以選擇去向對方初始化一個鏈接。數組
假設你是第一次與該設備鏈接,那麼一個配對的請求就會本身主動的顯示給用戶。當設備配對好以後,他的一些基本信息(主要是名字和MAC)被保存下來並可以使用藍牙的API來讀取。使用已知的MAC地址就可以對遠端的藍牙設備發起鏈接請求。
匹配好的設備和鏈接上的設備的不一樣點:匹配好僅僅是說明對方設備發現了你的存在,並擁有一個共同的識別碼。並且可以鏈接。鏈接上:表示當前設備共享一個RFCOMM信道並且二者之間可以交換數據。markdown
也就是是說藍牙設備在創建RFCOMM信道以前。必須是已經配對好了的。app
在創建鏈接以前你必須先查詢配對好了的藍牙設備集以便選取一個設備進行通訊。好比你可以你可以查詢所有配對的藍牙設備,並使用一個數組適配器將其打印顯示出來:oop
Set<BluetoothDevice> pairedDevices =mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
//Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
創建一個藍牙鏈接僅僅需要MAC地址就已經足夠。post
掃描設備,僅僅需要調用startDiscovery()方法,這個掃描的過程大概持續是12秒,應用程序爲了ACTION_FOUND動做需要註冊一個BroadcastReceiver來接受設備掃描到的信息。對於每一個設備。系統都會廣播ACTION_FOUND動做。 spa
// 用ACTION_FOUND爲action註冊廣播接收器
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// 發現設備
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 從Intent中獲取藍牙設備
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 加入名字和地址到設備適配器中
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
//註冊廣播接收器
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); //在onDestroy時記得註銷廣播接收器
假設你想使你的設備可以被其它設備發現,將ACTION_REQUEST_DISCOVERABLE動做封裝在intent中並調用startActivityForResult(Intent, int)方法就可以了。它將在不使你應用程序退出的狀況下使你的設備可以被發現。缺省狀況下的使能時間是120秒,固然你可以可以經過加入EXTRA_DISCOVERABLE_DURATION字段來改變使能時間(最大不超過300秒)好比:線程
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
執行該段代碼以後,系統會彈出一個對話框來提示你啓動設備使能被發現(此過程當中假設你的藍牙功能沒有開啓。系統會幫你開啓),並且假設你準備對該遠端設備發現一個鏈接,你不需要開啓設備被發現功能。因爲該功能僅僅是在你的應用程序做爲server端的時候才需要。
在應用程序中,想創建兩個藍牙設備之間的鏈接,必須實現client和server端的代碼(因爲不論什麼一個設備都必須可以做爲服務端或者client)。
一個開啓服務來監聽。一個發起鏈接請求(使用server端設備的MAC地址)。
當他們都擁有一個藍牙套接字在同一RFECOMM信道上的時候。可以以爲他們之間已經鏈接上了。服務端和client經過不一樣的方式或其它們的藍牙套接字。當一個鏈接監聽到的時候,服務端獲取到藍牙套接字。
當客戶可打開一個FRCOMM信道給server端的時候,client獲取到藍牙套接字。
注意:在此過程當中,假設兩個藍牙設備尚未配對好的。android系統會經過一個通知或者對話框的形式來通知用戶。
RFCOMM鏈接請求會在用戶選擇以前堵塞。
當你想要鏈接兩臺設備時,一個必須做爲服務端(經過持有一個打開的BluetoothServerSocket),目的是監聽外來鏈接請求,當監聽到之後提供一個鏈接上的BluetoothSocket給client。當client從BluetoothServerSocket獲得BluetoothSocket之後就可以銷燬BluetoothServerSocket,除非你還想監聽不少其它的鏈接請求。
創建服務套接字和監聽鏈接的基本步驟:
首先經過調用listenUsingRfcommWithServiceRecord(String, UUID)方法來獲取BluetoothServerSocket對象,參數String表明了該服務的名稱,UUID表明了和client鏈接的一個標識(128位格式的字符串ID,至關於PIN碼),UUID必須兩方匹配才幹夠創建鏈接。
其次調用accept()方法來監聽可能到來的鏈接請求,當監聽到之後,返回一個鏈接上的藍牙套接字BluetoothSocket。
最後,在監聽到一個鏈接之後。需要調用close()方法來關閉監聽程序。(通常藍牙設備之間是點對點的傳輸)
注意:accept()方法不該該放在主Acitvity裏面,因爲它是一種堵塞調用(在沒有監聽到鏈接請求以前程序就一直停在那裏)。
解決方法是新建一個線程來管理。
好比:
爲了初始化一個與遠端設備的鏈接,需要先獲代替表該設備的一個BluetoothDevice對象。經過BluetoothDevice對象來獲取BluetoothSocket並初始化鏈接。詳細步驟:
使用BluetoothDevice對象裏的方法createRfcommSocketToServiceRecord(UUID)來獲取BluetoothSocket。UUID就是匹配碼。而後,調用connect()方法來。假設遠端設備接收了該鏈接,他們將在通訊過程當中共享RFFCOMM信道,並且connect返回。
注意:conncet()方法也是堵塞調用,通常創建一個獨立的線程中來調用該方法。
在設備discover過程當中不該該發起鏈接connect()。這樣會明顯減慢速度以致於鏈接失敗。且傳輸數據完畢僅僅有調用close()方法來關閉鏈接,這樣可以節省系統內部資源。
當設備鏈接上之後,每一個設備都擁有各自的BluetoothSocket。
就可以實現設備之間數據的共享了。
首先經過調用getInputStream()和getOutputStream()方法來獲取輸入輸出流。
而後經過調用read(byte[]) 和write(byte[]).方法來讀取或者寫數據。
實現細節:覺得讀取和寫操做都是堵塞調用,需要創建一個專用線程來管理。
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permissionandroid:name="android.permission.BLUETOOTH" />