網站首頁 編程語言 正文
本文要實現的是在 android 8.0 的平臺上,藍牙遙控器與TV自動配對,具體就是在TV端打開配對界面,TV端開始搜索遠程藍牙設備,按下遙控器按鍵讓藍牙遙控器進入對碼模式,此時藍牙遙控器就能作為一個遠程藍牙設備被發現,TV端掃描到這個遠程藍牙設備(藍牙遙控器),就會自動進行配對連接。
話不多說,直接上代碼分析。
public class RcConnectActivity extends Activity { ? ? ?? ?private static final String TAG = "RcConnectActivity"; ?? ??? ?private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); ?? ? ? ?private BluetoothDevice mBluetoothDevice; ?? ??? ?private BluetoothReceiver mBluetoothReceiver = null; ?? ??? ?private boolean isConnected = false; ?? ? ?? ? ? ?@Override ?? ? ? ?protected void onCreate(Bundle savedInstanceState) { ?? ??? ??? ?Log.d(TAG, "onCreate"); ?? ? ? ? ? ?super.onCreate(savedInstanceState); ?? ? ? ? ? ?setContentView(R.layout.rc_connect); ?? ??? ??? ?registerReceiver(); ?? ??? ??? ?if (mBluetoothAdapter != null) { ?? ??? ??? ??? ?if (mBluetoothAdapter.isEnabled()) { ?? ??? ??? ??? ??? ?mBluetoothAdapter.startDiscovery(); ?? ??? ??? ??? ??? ?Log.d(TAG, "mBluetoothAdapter.startDiscovery"); ?? ??? ??? ??? ?} else { ?? ??? ??? ??? ??? ?mBluetoothAdapter.enable(); ?? ??? ??? ??? ??? ?Log.d(TAG, "mBluetoothAdapter.enable"); ?? ??? ??? ??? ?} ?? ??? ??? ?} else { ?? ??? ??? ??? ?Toast.makeText(this, R.string.bluetooth_tip, Toast.LENGTH_SHORT).show(); ?? ??? ??? ?} ?? ? ? ?}
首先我們要注冊一個廣播接收器,用來接收藍牙掃描搜索配對過程中一些藍牙相關的廣播,以便進行相對應的操作。
public void registerReceiver() { ?? ??? ?Log.d(TAG, "registerReceiver"); ? ? ? ? IntentFilter filter = new IntentFilter(); ? ? ? ? filter.addAction(BluetoothDevice.ACTION_FOUND); ? ? ? ? filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); ? ? ? ? filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); ? ? ? ? filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); ?? ??? ?mBluetoothReceiver = new BluetoothReceiver(); ? ? ? ? registerReceiver(mBluetoothReceiver, filter); ? ? }
BluetoothDevice.ACTION_FOUND 也就是 android.bluetooth.device.action.FOUND,當發現遠程藍牙設備的時候,系統就會發出這條廣播。接收這條廣播需要以下權限。
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED:當藍牙連接狀態改變時,就會發送此廣播。
BluetoothAdapter.ACTION_STATE_CHANGED:也就是 android.bluetooth.adapter.action.STATE_CHANGED 當本地藍牙適配器的狀態改變時,比如打開藍牙或者關閉藍牙的時候,就會發送此廣播。
BluetoothAdapter.ACTION_DISCOVERY_FINISHED:當本地藍牙適配器完成設備掃描搜索過程的時候,就會發送此廣播。
注冊完廣播接著就是通過 BluetoothAdapter.getDefaultAdapter() 來獲取本地藍牙適配器,如果硬件不支持藍牙的話,那么返回值為null。如果能獲取到,證明TV端是有可用的藍牙模塊,接著通過 isEnabled() 這個方法來判斷TV端的藍牙模塊是否已經打開并且可以使用,相當于 getBluetoothState() == STATE_ON 。如果已經打開藍牙,那么就可以通過 startDiscovery() 進行掃描藍牙設備,否則就通過 enable() 來打開藍牙。
startDiscovery() 需要<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
這個權限。
private class BluetoothReceiver extends BroadcastReceiver { ? ? ? ? @Override ? ? ? ? public void onReceive(Context context, Intent intent) { ?? ??? ??? ? ?? ??? ??? ?String action = intent.getAction();? ?? ??? ??? ?Log.d(TAG, "action = " + action); ?? ??? ??? ?if(BluetoothDevice.ACTION_FOUND.equals(action)){? ?? ??? ??? ??? ?mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); ?? ??? ??? ??? ?Log.d(TAG, "find device : " + "[ "+ mBluetoothDevice.getName() +" ]" + ":" + mBluetoothDevice.getAddress()); ?? ??? ??? ??? ? ?? ??? ??? ??? ?if (mBluetoothDevice.getName() == null || !mBluetoothDevice.getName().equals("RCSP")) { ?? ??? ??? ??? ??? ?return; ?? ??? ??? ??? ?} else? ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?if (mBluetoothDevice.getBondState() == BluetoothDevice.BOND_NONE) { ?? ??? ??? ??? ??? ??? ?Log.d(TAG, "attemp to bond: " + "[ " + mBluetoothDevice.getName() + " ]"); ?? ??? ??? ??? ??? ??? ?try { ?? ??? ??? ??? ??? ??? ??? ?mBluetoothDevice.createBond(); ?? ??? ??? ??? ??? ??? ??? ?isConnected = true; ?? ??? ??? ??? ??? ??? ?} catch (Exception e) { ?? ??? ??? ??? ??? ??? ??? ?e.printStackTrace(); ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?}? ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ?} ?? ??? ??? ?} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { ?? ??? ??? ??? ?int status = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0); ?? ??? ??? ??? ?if (BluetoothAdapter.STATE_ON == status) { ?? ??? ??? ??? ??? ?mBluetoothAdapter.startDiscovery(); ?? ??? ??? ??? ??? ?Log.d(TAG, "mBluetoothAdapter.startDiscovery---STATE_ON"); ?? ??? ??? ??? ?} ?? ??? ??? ?} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { ?? ??? ??? ??? ?if (!isConnected) { ?? ??? ??? ??? ??? ?mBluetoothAdapter.startDiscovery(); ?? ??? ??? ??? ??? ?Log.d(TAG, "mBluetoothAdapter.startDiscovery---ACTION_DISCOVERY_FINISHED"); ?? ??? ??? ??? ?} ?? ??? ??? ?} else if (BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { ? ? ? ? ? ? ? ? int newState = intent.getExtras().getInt(BluetoothProfile.EXTRA_STATE); ? ? ? ? ? ? ? ? switch (newState) { ? ? ? ? ? ? ? ? ? ? case BluetoothProfile.STATE_CONNECTING: ? ? ? ? ? ? ? ? ? ? ? ? Log.d(TAG, "CONNECTING"); ?? ??? ??? ??? ??? ??? ?Toast.makeText(context, R.string.bluetooth_connecting, Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case BluetoothProfile.STATE_CONNECTED: ?? ??? ??? ??? ??? ??? ?Log.d(TAG, "CONNECTED"); ?? ??? ??? ??? ??? ??? ?Toast.makeText(context, R.string.bluetooth_connected, Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? RcConnectActivity.this.finish(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ?? ??? ??? ?}?? ? ? ? ? ? } ? ? }
流程分析:
1、如果TV端的藍牙模塊已經打開,那么就執行 startDiscovery(),否則通過 enable() 打開藍牙,此時會接收到 BluetoothAdapter.ACTION_STATE_CHANGED 這條廣播。藍牙有四種狀態,分別是STATE_OFF、STATE_TURNING_ON、STATE_ON、STATE_TURNING_OFF。當藍牙狀態為STATE_ON,表示藍牙已經打開并且已經準備就緒,此時才可以進行startDiscovery(),否則 startDiscovery() 會返回false,無法掃描搜索遠程藍牙設備。
2、掃描搜索到遠程設備之后,判斷是不是目標設備,目標設備藍牙遙控器的名字為 RCSP 。如果 getName() 獲取到的名字為null,或者不是 RCSP,直接 return,不進行任何操作。android 8.0 要對 getName() 為 null 進行處理,不然程序會運行出錯。如果搜索到目標設備,通過 createBond() 方法,實現自動配對。
3、startDiscovery() 會進行大約12秒的掃描搜索,有可能此時我們的目標設備還沒有進入對碼模式,還不能被TV端發現,從而也無法自動配對。當掃描搜索完成之后,會發送 BluetoothAdapter.ACTION_DISCOVERY_FINISHED 這條廣播,此時我們在判斷目標設備是否已經配對連接,如果沒有,再次調用 startDiscovery() 進行掃描搜索。
4、當目標設備在進行自動配對的時候,我們通過接收BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED 這條廣播,來判斷目標設備的狀態,并用 Toast 提示配對是否成功。
原文鏈接:https://blog.csdn.net/lojotee/article/details/103693201
相關推薦
- 2024-01-27 Rosetta error:bad input問題(解決)
- 2022-08-26 C語言數據結構之隊列的定義與實現_C 語言
- 2023-02-05 k8s?與docker空間使用分析與清理方法_docker
- 2022-08-16 python切片操作方法的實例總結_python
- 2023-08-15 類對象數組抽取對象指定屬性重新組成新的類對象數組
- 2022-05-13 類實例化 對象的內存模型 及 內存占用分析
- 2022-05-06 linux/mac上如何查看公網ip
- 2021-11-03 C++趣味算法之偵探推理_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支