在上一篇中有介紹了Wifi與網(wǎng)絡(luò)連接處理
站在用戶的角度思考問題,與客戶深入溝通,找到麻江網(wǎng)站設(shè)計與麻江網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、國際域名空間、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋麻江地區(qū)。
Android開發(fā)之WiFi與網(wǎng)絡(luò)連接處理
下面,來繼續(xù)說說Android中藍(lán)牙的基本使用。
Bluetooth是目前使用的最廣泛的無線通訊協(xié)議之一,主要針對短距離設(shè)備通訊(10米),常用于連接耳機、鼠標(biāo)和移動通訊設(shè)備等。
值得一提的是:
android4.2新增了部分新功能,但是對于Bluetooth熟悉的人或許開始頭疼了,那就是Android4.2引入了一個新的藍(lán)牙協(xié)議棧針BLE。谷歌和Broadcom之間的合作,開發(fā)新的藍(lán)牙協(xié)議棧,取代了基于堆棧的Bluez。因此市場上出現(xiàn)了老設(shè)備的兼容問題,很多藍(lán)牙設(shè)備在android4.2手機上不能正常使用。
BluetoothAdapter簡單點來說就是代表了本設(shè)備(手機、電腦等)的藍(lán)牙適配器對象。
first:we need permission
要操作藍(lán)牙,先要在AndroidManifest.xml里加入權(quán)限
**下面來看看如何使用藍(lán)牙。 **↓↓↓****
Demo已就緒:
返回值:如果設(shè)備具備藍(lán)牙功能,返回BluetoothAdapter 實例;否則,返回null對象。
打開藍(lán)牙設(shè)備的方式:
1.直接調(diào)用函數(shù)enable()去打開藍(lán)牙設(shè)備 ;
2.系統(tǒng)API去打開藍(lán)牙設(shè)備,該方式會彈出一個對話框樣式的Activity供用戶選擇是否打開藍(lán)牙設(shè)備。
注意: 1.如果藍(lán)牙已經(jīng)開啟,不會彈出該Activity界面。2.在目前大多數(shù)Android手機中,是不支持在飛行模式下開啟藍(lán)牙的。如果藍(lán)牙已經(jīng)開啟,那么藍(lán)牙的開關(guān) ,狀態(tài)會隨著飛行模式的狀態(tài)而發(fā)生改變。
1. 搜索藍(lán)牙設(shè)備
使用BluetoothAdapter的startDiscovery()方法來搜索藍(lán)牙設(shè)備
startDiscovery()方法是一個異步方法,調(diào)用后會立即返回。該方法會進(jìn)行對其他藍(lán)牙設(shè)備的搜索,該過程會持續(xù)12秒。該方法調(diào)用后,搜索過程實際上是在一個System Service中進(jìn)行的,所以可以調(diào)用cancelDiscovery()方法來停止搜索(該方法可以在未執(zhí)行discovery請求時調(diào)用)。
系統(tǒng)開始搜索藍(lán)牙設(shè)備
^( *  ̄(oo) ̄ ) ^ 系統(tǒng)會發(fā)送以下三個廣播:
2.掃描設(shè)備
3.定義廣播接收器接收搜索結(jié)果
4.注冊廣播
獲取附近的藍(lán)牙設(shè)備
第一步建立連接:首先Android sdk(2.0以上版本)支持的藍(lán)牙連接是通過BluetoothSocket建立連接,服務(wù)端BluetoothServerSocket和客戶端(BluetoothSocket)需指定同樣的UUID,才能建立連接,因為建立連接的方法會阻塞線程,所以服務(wù)器端和客戶端都應(yīng)啟動新線程連接。
(這里的服務(wù)端和客戶端是相對來說的)
兩個藍(lán)牙設(shè)備之間的連接,則必須實現(xiàn)服務(wù)端與客戶端的機制。
當(dāng)兩個設(shè)備在同一個RFCOMM channel下分別擁有一個連接的BluetoothSocket,這兩個設(shè)備才可以說是建立了連接。
服務(wù)端設(shè)備與客戶端設(shè)備獲取BluetoothSocket的途徑是不同的。
1,服務(wù)端設(shè)備是通過accepted一個incoming connection來獲取的,
2,客戶端設(shè)備則是通過打開一個到服務(wù)端的RFCOMM channel來獲取的。
服務(wù)端
通過調(diào)用BluetoothAdapter的listenUsingRfcommWithServiceRecord(String, UUID)方法來獲取BluetoothServerSocket(UUID用于客戶端與服務(wù)端之間的配對)
客戶端
調(diào)用BluetoothService的createRfcommSocketToServiceRecord(UUID)方法獲取BluetoothSocket(該UUID應(yīng)該同于服務(wù)端的UUID)。
調(diào)用BluetoothSocket的connect()方法(該方法為block方法),如果UUID同服務(wù)端的UUID匹配,并且連接被服務(wù)端accept,則connect()方法返回。
數(shù)據(jù)傳遞,通過以上操作,就已經(jīng)建立的BluetoothSocket連接了,數(shù)據(jù)傳遞無非是通過流的形式
獲取流
該類就是關(guān)于遠(yuǎn)程藍(lán)牙設(shè)備的一個描述。通過它可以和本地藍(lán)牙設(shè)備---BluetoothAdapter連接通信。
好多東西我也不知道怎么描述,下面給出Demo:
剛好有剛學(xué)習(xí)的小伙伴問我ListView怎么用,那我就用ListView。
源碼:
RairDemo
GitHub:
Coding:
藍(lán)牙掃描的目的在于發(fā)現(xiàn)設(shè)備或者接收設(shè)備廣播,設(shè)備包括經(jīng)典藍(lán)牙設(shè)備和BLE藍(lán)牙設(shè)備,這兩種設(shè)備的掃描方式不同。
對于經(jīng)典藍(lán)牙設(shè)備,掃描是通過調(diào)用startDiscovery接口,返回的結(jié)果是通過BroadcastReceiver接收的,可以獲取設(shè)備MAC地址,名稱以及RSSI。
startDiscovery是個異步調(diào)用,會立即返回。如果不調(diào)用cancelDiscovery主動停止掃描的話,最多掃描12s。
廣播主要監(jiān)聽以下幾個Action:
BluetoothDevice.ACTION_FOUND
BluetoothAdapter.ACTION_DISCOVERY_STARTED
BluetoothAdapter.ACTION_DISCOVERY_FINISHED
另外要注意startDiscovery返回的設(shè)備不包括已配對設(shè)備,如要獲取已配對設(shè)備,需要額外調(diào)用getBondedDevices。
對于BLE藍(lán)牙設(shè)備,掃描是通過調(diào)用startLeScan接口,返回的結(jié)果是通過onLeScan回調(diào),除了獲得設(shè)備MAC地址,名稱及RSSI之外還能獲取設(shè)備廣播,廣播是以byte數(shù)組的形式表示的。
較新的Android版本提供了新的掃描接口,可更靈活地配置掃描策略,詳情可參考官網(wǎng)文檔,此處不再贅述。
一,需要打開以下權(quán)限
android.permission.BLUETOOTH
android.permission.ACCESS_COARSE_LOCATION
android.permission.BLUETOOTH_ADMIN
android.permission.ACCESS_FINE_LOCATION
另外還要注意動態(tài)權(quán)限問題,在Android 6.0(targetSdkVersion=23)之后,需要動態(tài)申請獲取用戶位置的權(quán)限,不然獲取不到設(shè)備掃描結(jié)果。
二,startDiscovery在大多數(shù)手機上是可以同時發(fā)現(xiàn)經(jīng)典藍(lán)牙和Ble的,但是startDiscovery的回調(diào)無法返回BLE的廣播,所以無法通過廣播識別設(shè)備,且startDiscovery掃描BLE的效率比startLeScan低很多。所以在實際應(yīng)用中,還是startDiscovery和startLeScan分開掃,前者掃經(jīng)典藍(lán)牙,后者掃低功耗藍(lán)牙。
三,startLeScan() 的時候,在onLeScan() 中不能做耗時操作,特別是周圍的BLE設(shè)備多的時候,容易導(dǎo)致底層堵塞,如果有耗時操作請丟到子線程中去處理。如解析廣播識別設(shè)備等操作可能會較耗時。
四,實踐中發(fā)現(xiàn)同樣一個設(shè)備,有的手機很容易就掃出來了,有的手機很難掃出來。這種情況建議可以多掃幾次,每次掃描時間短一點。
android藍(lán)牙自動配對連接的具體代碼如下:
1. 獲取藍(lán)牙適配器BluetoothAdapter blueadapter=BluetoothAdapter.getDefaultAdapter();
如果BluetoothAdapter 為null,說明android手機沒有藍(lán)牙模塊。
2. 判斷藍(lán)牙模塊是否開啟,blueadapter.isEnabled() true表示已經(jīng)開啟,false表示藍(lán)牙并沒啟用。
3. 啟動配置藍(lán)牙可見模式,即進(jìn)入可配對模式Intent in=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);
startActivity(in); ,200就表示200秒。
4. 獲取藍(lán)牙適配器中已經(jīng)配對的設(shè)備SetBluetoothDevice device=blueadapter.getBondedDevices();
當(dāng)然,還需要在androidManifest.xml中聲明藍(lán)牙的權(quán)限
uses-permission android:name="android.permission.BLUETOOTH" /
uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /
5.自動配對設(shè)置Pin值
static public boolean autoBond(Class btClass, BluetoothDevice device, String strPin)
throws Exception {
Method autoBondMethod = btClass.getMethod("setPin", new Class[] { byte[].class });
Boolean result = (Boolean) autoBondMethod
.invoke(device, new Object[] { strPin.getBytes() });
return result;
}
6.開始配對請求
static public boolean createBond(Class btClass, BluetoothDevice device) throws Exception {
Method createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
android獲取藍(lán)牙bluetooth的信號強度步驟如下:
在oncreate方法里面增加 注冊掃描廣播 public void onCreate(Bundle savedInstanceState) { // 注冊開始發(fā)現(xiàn)廣播。 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED); this.registerReceiver(mReceiver, filter); } 2.新建BroadcastReceiver廣播對象,并實現(xiàn)里面的onreceive方法,在onreceive得到rssi(信號強度)。 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //當(dāng)設(shè)備開始掃描時。 if (BluetoothDevice.ACTION_FOUND.equals(action)) { //從Intent得到blueDevice對象 BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device.getBondState() != BluetoothDevice.BOND_BONDED) { //信號強度。 short rssi = intent.getExtras().getShort( BluetoothDevice.EXTRA_RSSI); } } } };
送上我遲來的答案,不知你這條幫助是哪年留下的,我是通過手機看到你的求助,但是卻看不到你是那年留下的問題,能看到下面有人在15年的答復(fù),估計應(yīng)該是5年之前的問題了,即便能幫助到你也是作用不大了。我這有一款A(yù)PP可以看到你手機上曾經(jīng)連接過的所有藍(lán)牙設(shè)備的MAC地址,只要是你手機曾連接過的設(shè)備,就全部都能看到Mac地址,APP名為
Walkie-Talkie via Bluetooth
只可惜我看到你的求助太遲了,已相隔5年之久,若當(dāng)時看到多好啊一定會幫得到你^_^