android bluetooth——藍芽的開啟、搜尋、配對與連線
android 的blt僅僅支援api 18 android4.3以上,有的功能甚至需要api 19 android4.4;
所以我們在做blt專案之前一定要清楚可用的版本範圍。
我要講述的是開啟blt大門的操作。這些操作就是如何開啟blt、如何搜尋到其他裝置、如何配對選中裝置、如何通過mac地址連線之前已經配對過的裝置以及連線成功的兩個(或一對多個)裝置如何通訊。
在學習blt知識前要先搞清楚,blt是如何讓兩個裝置之間通訊的。我們先來看一下基本步驟:
1,開啟blt。
——1)許可權
——2)監聽裝置是否開啟blt
——3)操作,開啟或者關閉blt
2,搜尋附近裝置&讓附近裝置搜尋到
——1)讓自身裝置可以被附近搜尋到,時間最長300s;(隨著api的逐漸升級可能不止300s,做了一定的優化處理)
——2)搜尋附近可連線的裝置;過時的api在介面中回撥搜尋結果,新的api則要求用廣播接收搜尋結果。(我們這裡使用廣播接收結果)
3,與目標裝置配對
——1)對於目標裝置進行配對,android系統本身會完成配對動作,並且將已經成功配對的裝置的mac地址儲存起來,以供下次進行自動配對使用。
——2)對進行配對過的裝置自動配對。這個動作也是系統幫我們完成的,我們只需要根據系統給我們的狀態來判斷這個是否已經配對就行了。
4,與成功配對的裝置進行連線
——1)如果要對成功配對的裝置進行連線,則必須先建立伺服器端。伺服器端建立只有會執行緒阻塞等待客戶端的連線。
——2)確保建立了伺服器端之後再建立客戶端。客戶端的連線過程也是執行緒阻塞的。知道連線成功後,伺服器端收到訊息,則表示配對裝置已連線成功。
5,注意事項:
——1)配對成功過的裝置無需再次配對,只需要從系統中拿到mac地址進行連線。這個根據系統返回的狀態值去判斷。
——2)搜尋附近裝置的操作是一個消耗記憶體的動作,我們務必在連線裝置‘之前‘停止搜尋。
——3)裝置的配對成功不代表連線成功。配對和連線是兩回事且配對在連線動作之前。
——4)當我們的程式明確指出“不需要blt操作了”的時候,及時反註冊blt廣播,停止blt連線,登出藍芽物件。而這個操作例如:程式退出、使用者無操作超時、邏輯不需要blt的連線了。
以上就是一個藍芽連線成功之後可以正常傳輸資訊的步驟。
接下來我們再來看看相應的步驟在程式碼邏輯中的代表。
1,許可權。
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
2,獲得藍芽管理物件。BluetoothManager的主要作用是從中得到我們需要的物件
//@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
//首先獲取BluetoothManager
BluetoothManager bluetoothManager=(BluetoothManager) context.getService(Context.BLUETOOTH_SERVICE);
3,獲得藍芽介面卡。藍芽介面卡是我們操作藍芽的主要物件,可以從中獲得配對過的藍芽集合,可以獲得藍芽傳輸物件等等
//獲取BluetoothAdapter
if (bluetoothManager != null)
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
3,註冊廣播來接收藍芽配對資訊。在藍芽開啟前呼叫
// 用BroadcastReceiver來取得搜尋結果
IntentFilter intent = new IntentFilter();
intent.addAction(BluetoothDevice.ACTION_FOUND);//搜尋發現裝置
intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//狀態改變
intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);//行動掃描模式改變了
intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//動作狀態發生了變化
context.registerReceiver(searchDevices, intent);
/**
* 藍芽接收廣播
*/
private BroadcastReceiver searchDevices = new BroadcastReceiver() {
//接收
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Bundle b = intent.getExtras();
Object[] lstName = b.keySet().toArray();
// 顯示所有收到的訊息及其細節
for (int i = 0; i < lstName.length; i++) {
String keyName = lstName[i].toString();
Log.e("bluetooth", keyName + ">>>" + String.valueOf(b.get(keyName)));
}
BluetoothDevice device;
// 搜尋發現裝置時,取得裝置的資訊;注意,這裡有可能重複搜尋同一裝置
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
onRegisterBltReceiver.onBluetoothDevice(device);
}
//狀態改變時
else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING://正在配對
Log.d("BlueToothTestActivity", "正在配對......");
onRegisterBltReceiver.onBltIng(device);
break;
case BluetoothDevice.BOND_BONDED://配對結束
Log.d("BlueToothTestActivity", "完成配對");
onRegisterBltReceiver.onBltEnd(device);
break;
case BluetoothDevice.BOND_NONE://取消配對/未配對
Log.d("BlueToothTestActivity", "取消配對");
onRegisterBltReceiver.onBltNone(device);
default:
break;
}
}
}
};
4,反註冊廣播和清楚藍芽連線。在不需要使用藍芽的時候呼叫
/**
* 反註冊廣播取消藍芽的配對
*
* @param context
*/
public void unregisterReceiver(Context context) {
context.unregisterReceiver(searchDevices);
if (mBluetoothAdapter != null)
mBluetoothAdapter.cancelDiscovery();
}
5,判斷當前裝置是否支援藍芽,如果支援則開啟藍芽
/**
* 判斷是否支援藍芽,並開啟藍芽
* 獲取到BluetoothAdapter之後,還需要判斷是否支援藍芽,以及藍芽是否開啟。
* 如果沒開啟,需要讓使用者開啟藍芽:
*/
public void checkBleDevice(Context context) {
if (mBluetoothAdapter != null) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(enableBtIntent);
}
} else {
Log.i("blueTooth", "該手機不支援藍芽");
}
}
6,搜尋藍芽。搜尋後新增到自定義的集合中以供自身程式的邏輯使用。注意:搜尋到的結果會在廣播中回撥過來,這裡不做回撥。若使用過時的介面,則在當前邏輯裡回撥結果。我們這裡使用廣播,不建議使用過時的方法。
/**
* 搜尋藍芽裝置
* 通過呼叫BluetoothAdapter的startLeScan()搜尋BLE裝置。
* 呼叫此方法時需要傳入 BluetoothAdapter.LeScanCallback引數。
* 因此你需要實現 BluetoothAdapter.LeScanCallback介面,BLE裝置的搜尋結果將通過這個callback返回。
* <p/>
* 由於搜尋需要儘量減少功耗,因此在實際使用時需要注意:
* 1、當找到對應的裝置後,立即停止掃描;
* 2、不要迴圈搜尋裝置,為每次搜尋設定適合的時間限制。避免裝置不在可用範圍的時候持續不停掃描,消耗電量。
* <p/>
* 如果你只需要搜尋指定UUID的外設,你可以呼叫 startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法。
* 其中UUID陣列指定你的應用程式所支援的GATT Services的UUID。
* <p/>
* 注意:搜尋時,你只能搜尋傳統藍芽裝置或者BLE裝置,兩者完全獨立,不可同時被搜尋。
*/
private boolean startSearthBltDevice(Context context) {
//開始搜尋裝置,當搜尋到一個裝置的時候就應該將它新增到裝置集合中,儲存起來
checkBleDevice(context);
//如果當前發現了新的裝置,則停止繼續掃描,當前掃描到的新裝置會通過廣播推向新的邏輯
if (getmBluetoothAdapter().isDiscovering())
stopSearthBltDevice();
Log.i("bluetooth", "本機藍芽地址:" + getmBluetoothAdapter().getAddress());
//開始搜尋
mBluetoothAdapter.startDiscovery();
//這裡的true並不是代表搜尋到了裝置,而是表示搜尋成功開始。
return true;
}
7,停止搜尋藍芽裝置
public boolean stopSearthBltDevice() {
//暫停搜尋裝置
if(mBluetoothAdapter!=null)
return mBluetoothAdapter.cancelDiscovery();
}
8,連線藍芽。注意:連線藍芽的前提是我們已經建立好了藍芽伺服器端。所以,這裡我們先建立藍芽伺服器
——1)先建立藍芽伺服器端
/**
* 這個操作應該放在子執行緒中,因為存線上程阻塞的問題
*/
public void run(Handler handler) {
//伺服器端的bltsocket需要傳入uuid和一個獨立存在的字串,以便驗證,通常使用包名的形式
BluetoothServerSocket bluetoothServerSocket = tmBluetoothAdapter.listenUsingRfcommWithServiceRecord("com.bluetooth.demo", BltContant.SPP_UUID);
while (true) {
try {
//注意,當accept()返回BluetoothSocket時,socket已經連線了,因此不應該呼叫connect方法。
//這裡會執行緒阻塞,直到有藍芽裝置連結進來才會往下走
socket = getBluetoothServerSocket().accept();
if (socket != null) {
BltAppliaction.bluetoothSocket = socket;
//回撥結果通知
Message message = new Message();
message.what = 3;
message.obj = socket.getRemoteDevice();
handler.sendMessage(message);
//如果你的藍芽裝置只是一對一的連線,則執行以下程式碼
getBluetoothServerSocket().close();
//如果你的藍芽裝置是一對多的,則應該呼叫break;跳出迴圈
//break;
}
} catch (IOException e) {
try {
getBluetoothServerSocket().close();
} catch (IOException e1) {
e1.printStackTrace();
}
break;
}
}
}
——2)在藍芽伺服器建立之後,再進行連線藍芽的操作。
/**
* 嘗試連線一個裝置,子執行緒中完成,因為會執行緒阻塞
*
* @param btDev 藍芽裝置物件
* @param handler 結果回撥事件
* @return
*/
private void connect(BluetoothDevice btDev, Handler handler) {
try {
//通過和伺服器協商的uuid來進行連線
mBluetoothSocket = btDev.createRfcommSocketToServiceRecord(BltContant.SPP_UUID);
if (mBluetoothSocket != null)
//全域性只有一個bluetooth,所以我們可以將這個socket物件儲存在appliaction中
BltAppliaction.bluetoothSocket = mBluetoothSocket;
//通過反射得到bltSocket物件,與uuid進行連線得到的結果一樣,但這裡不提倡用反射的方法
//mBluetoothSocket = (BluetoothSocket) btDev.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(btDev, 1);
Log.d("blueTooth", "開始連線...");
//在建立之前呼叫
if (getmBluetoothAdapter().isDiscovering())
//停止搜尋
getmBluetoothAdapter().cancelDiscovery();
//如果當前socket處於非連線狀態則呼叫連線
if (!getmBluetoothSocket().isConnected()) {
//你應當確保在呼叫connect()時裝置沒有執行搜尋裝置的操作。
// 如果搜尋裝置也在同時進行,那麼將會顯著地降低連線速率,並很大程度上會連線失敗。
getmBluetoothSocket().connect();
}
Log.d("blueTooth", "已經連結");
if (handler == null) return;
//結果回撥
Message message = new Message();
message.what = 4;
message.obj = btDev;
handler.sendMessage(message);
} catch (Exception e) {
Log.e("blueTooth", "...連結失敗");
try {
getmBluetoothSocket().close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
9,自動連線以往配對成功的裝置。注意:連線的前提是伺服器端已開啟,若沒開啟則進行8.1的操作
/**
* 嘗試配對和連線
*
* @param btDev
*/
public void createBond(BluetoothDevice btDev, Handler handler) {
if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {
//如果這個裝置取消了配對,則嘗試配對
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
btDev.createBond();
}
} else if (btDev.getBondState() == BluetoothDevice.BOND_BONDED) {
//如果這個裝置已經配對完成,則嘗試連線
connect(btDev, handler);
}
}
/**
* 獲得系統儲存的配對成功過的裝置,並嘗試連線
*/
public void getBltList() {
if (getmBluetoothAdapter() == null) return;
//獲得已配對的遠端藍芽裝置的集合
Set<BluetoothDevice> devices = getmBluetoothAdapter().getBondedDevices();
if (devices.size() > 0) {
for (Iterator<BluetoothDevice> it = devices.iterator(); it.hasNext(); ) {
BluetoothDevice device = it.next();
//自動連線已有藍芽裝置
createBond(device, null);
}
}
}
注意:外界只需要呼叫getBltList();方法即可進行自動連線。
10,輸入mac地址自動連線裝置。前提是系統原來連線過該地址。
/**
* 輸入mac地址進行自動配對
* 前提是系統儲存了該地址的物件
*
* @param address
*/
public void autoConnect(String address, Handler handler) {
if (getmBluetoothAdapter().isDiscovering()) getmBluetoothAdapter().cancelDiscovery();
BluetoothDevice btDev = getmBluetoothAdapter().getRemoteDevice(address);
connect(btDev, handler);
}
11,藍芽連線狀態。用於我們判斷該藍芽裝置是出於:未配對還是配對未連線還是已連線狀態
public String bltStatus(int status) {
String a = "未知狀態";
switch (status) {
case BluetoothDevice.BOND_BONDING:
a = "連線中";
break;
case BluetoothDevice.BOND_BONDED:
a = "連線完成";
break;
case BluetoothDevice.BOND_NONE:
a = "未連線/取消連線";
break;
}
return a;
}
11,藍芽點選事件。包括藍芽的開啟,關閉,被搜尋,斷開連線
/**
* 藍芽操作事件
*
* @param context
* @param status
*/
public void clickBlt(Context context, int status) {
switch (status) {
case BltContant.BLUE_TOOTH_SEARTH://搜尋藍芽裝置,在BroadcastReceiver顯示結果
startSearthBltDevice(context);
break;
case BltContant.BLUE_TOOTH_OPEN://本機藍芽啟用
if (getmBluetoothAdapter() != null)
getmBluetoothAdapter().enable();//啟用
break;
case BltContant.BLUE_TOOTH_CLOSE://本機藍芽禁用
if (getmBluetoothAdapter() != null)
getmBluetoothAdapter().disable();//禁用
break;
case BltContant.BLUE_TOOTH_MY_SEARTH://本機藍芽可以在300s內被搜尋到
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
context.startActivity(discoverableIntent);
break;
case BltContant.BLUE_TOOTH_CLEAR://本機藍芽關閉當前連線
try {
if (getmBluetoothSocket() != null)
getmBluetoothSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
到此,藍芽從開啟到連線的方法都寫完了。最後我們來總結一下。
當我們獲得到了bluetoothsocket物件的時候,我們就可以像使用socket程式設計一樣,讓兩個藍芽之間傳輸資料。甚至可以在程式內部監聽藍芽耳機的暫停/播放/音量鍵等的點選事件。
具體的藍芽操作,我將放在demo裡供大家學習。
demo下載
相關文章
- 已連線車載藍芽但放不了音樂 藍芽配對成功放不了音樂藍芽
- Android藍芽那點事——深入瞭解Android藍芽Bluetooth《進階篇》Android藍芽
- 藍芽耳機怎麼連線電腦?Win10系統電腦配對藍芽耳機的方法藍芽Win10
- BLE藍芽那些事—深入瞭解Android藍芽Bluetooth基礎篇藍芽Android
- Win10電腦怎麼連線藍芽耳機 win10怎麼藍芽耳機配對Win10藍芽
- 五十一、【Bluetooth藍芽模組】藍芽模組
- Android 開啟藍芽流程Android藍芽
- iOS藍芽開發 Bluetooth藍芽CoreBluetooth 藍芽中心裝置的實現 藍芽外設的實現 有DemoiOS藍芽
- 深入瞭解Android藍芽Bluetooth——《基礎篇》Android藍芽
- 電腦藍芽怎麼連線 電腦連線藍芽的方法藍芽
- 藍芽明明開著為什麼連線不上 藍芽接受器配對不成功的方法藍芽
- 藍芽(Bluetooth)音訊協議藍芽音訊協議
- 藍芽配對成功但沒有聲音怎麼辦 藍芽明明已連線但沒有聲音藍芽
- 藍芽滑鼠已配對為什麼沒反應 win10藍芽滑鼠已連線無反應藍芽Win10
- 手機藍芽搜尋不到裝置怎麼辦 藍芽裝置刪除後搜尋不到藍芽
- Win10系統顯示藍芽已配對但未連線的解決方法Win10藍芽
- 藍芽耳機怎麼連線手機 藍芽耳機連線手機的方法藍芽
- 華為freebuds耳機藍芽搜尋不到怎麼辦 華為freelace連線不上藍芽
- 藍芽Bluetooth技術小知識藍芽
- windows10無法搜尋到藍芽怎麼辦_windows10藍芽搜尋不到的解決方法Windows藍芽
- ArduinoUNO連線藍芽模組與安卓連線進行測距UI藍芽模組安卓
- 音響怎麼連線手機藍芽 音響連線手機藍芽的方法藍芽
- 關於藍芽bluetooth開發中遇到的DeadObjectException異常藍芽ObjectException
- 怎麼用手機藍芽連線電腦 手機藍芽連線電腦的步驟藍芽
- 小米盒子mini版無法連線藍芽遙控器怎麼辦?小米小盒子和藍芽遙控器配對方法藍芽
- 熊晨灃藍芽實戰--小程式藍芽連線2.0藍芽
- Macbook如何連線藍芽鍵盤?Mac藍芽
- win10搜尋不到藍芽耳機 win10檢測不到藍芽裝置Win10藍芽
- 臺式電腦藍芽在哪裡開啟 臺式電腦怎麼連線藍芽耳機音響設定藍芽
- 小愛音響怎麼使用藍芽連線手機 小愛音響連線手機藍芽的方法藍芽
- 如何實現藍芽配對方法混淆攻擊藍芽
- win10藍芽一直搜尋怎麼處理_win10藍芽一直在搜尋解決方法Win10藍芽
- win10藍芽功能怎麼開 win10系統如何連線藍芽耳機Win10藍芽
- win10系統如何連線羅技藍芽滑鼠 win10連線羅技藍芽滑鼠的步驟Win10藍芽
- Win10系統怎麼連線藍芽耳機 win10系統連線藍芽耳機的方法Win10藍芽
- 聯想無線滑鼠怎麼連線電腦連線藍芽藍芽
- 筆記本怎麼連線藍芽耳機 膝上型電腦連線藍芽裝置教程筆記藍芽
- 筆記本怎麼連藍芽耳機 筆記本連線藍芽耳機步驟筆記藍芽