首頁 > 軟體

Android 8.0實現藍芽遙控器自動配對

2022-08-17 14:00:51

本文要實現的是在 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 提示配對是否成功。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com