蓝牙(二)蓝牙搜索、配对、连接

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pashanhu6402/article/details/79907306

1.搜索

从上一节我们可以知道,蓝牙状态发生了改变,并发生了回调。咱们就从回调开始。

DevicePickerFragment.java 用于蓝牙设置界面的蓝牙配置和管理

 @Override
    public void onBluetoothStateChanged(int bluetoothState) {
        super.onBluetoothStateChanged(bluetoothState);

        if (bluetoothState == BluetoothAdapter.STATE_ON) {
            mLocalAdapter.startScanning(false);
        }
    }

最终会回调到这个地方,具体怎么回调到这的暂时没去分析,我猜测应该是回调到这,如果有知道请不吝赐教。

好了,蓝牙搜索开始了

LocalBluetoothAdapter.java

public void startScanning(boolean force) {
        // Only start if we're not already scanning
        if (!mAdapter.isDiscovering()) {
            if (!force) {
                // Don't scan more than frequently than SCAN_EXPIRATION_MS,
                // unless forced
                if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
                    return;
                }

                // If we are playing music, don't scan unless forced.
                A2dpProfile a2dp = mProfileManager.getA2dpProfile();
                if (a2dp != null && a2dp.isA2dpPlaying()) {
                    return;
                }
            }

            if (mAdapter.startDiscovery()) {
                mLastScan = System.currentTimeMillis();
            }
        }
    

下面会调到BluetoothAdapter.startDiscovery()==>AdapterService.startDiscovery()==>AS.startDiscoveryNative()==>JNI里面的startDiscoveryNative()==>再下面就到hw里面和bluetooth.start_discovery(void),这些暂时就不分析了,有兴趣的可以自行分析。


2.连接/断开/配对/取消配对

还是从蓝牙设置界面讲起吧,当点击设置界面的某个蓝牙设备时会回调到DeviceListPreferenceFragment里面

@Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
            Preference preference) {
        if (KEY_BT_SCAN.equals(preference.getKey())) {
            mLocalAdapter.startScanning(true);
            return true;
        }

        if (preference instanceof BluetoothDevicePreference) {
            BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
            CachedBluetoothDevice device = btPreference.getCachedDevice();
            mSelectedDevice = device.getDevice();
            onDevicePreferenceClick(btPreference);
            return true;
        }

        return super.onPreferenceTreeClick(preferenceScreen, preference);
    }
void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
        btPreference.onClicked();
    }
==》
 void onClicked() {
        int bondState = mCachedDevice.getBondState();

        if (mCachedDevice.isConnected()) {
            askDisconnect();
        } else if (bondState == BluetoothDevice.BOND_BONDED) {
            mCachedDevice.connect(true);
        } else if (bondState == BluetoothDevice.BOND_NONE) {
            pair();
        }
    }

上面的逻辑里会根据不同的情况执行不同的逻辑,一目了然。

    1)配对

    

private void pair() {
        if (!mCachedDevice.startPairing()) {
            Utils.showError(getContext(), mCachedDevice.getName(),
                    R.string.bluetooth_pairing_error_message);
        }

注意了,开始拉红线配对了。配对之前,如果有已婚的,那么不好意思,必须拆开重新选择对象了偷笑

 public boolean startPairing() {
        // Pairing is unreliable while scanning, so cancel discovery
        if (mLocalAdapter.isDiscovering()) {
            mLocalAdapter.cancelDiscovery();
        }

        if (!mDevice.createBond()) {
            return false;
        }

        mConnectAfterPairing = true;  // auto-connect after pairing
        return true;
    }

==》BluetoothDevice.createBond()==>adapterservice.createBond()==>adapterservice.createBond()==>向状态机发送绑定消息==》BondStateMachine.createBond()==>AdapterService.createBondNative()==>JNI==>hw==>external,想了解的自行分析。借用一下图

 

配对完成之后,要干嘛?大家都是正经人,所以要去结婚然后再去开房了。所以当配对成功之后,肯定有一个事件提供给上面BluetoothEventManager

,接收到bond完成事件

private class BondStateChangedHandler implements Handler {
259        public void onReceive(Context context, Intent intent,
260                BluetoothDevice device) {
261            if (device == null) {
262                Log.e(TAG, "ACTION_BOND_STATE_CHANGED with no EXTRA_DEVICE");
263                return;
264            }
265            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
266                                               BluetoothDevice.ERROR);
267            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
268            if (cachedDevice == null) {
269                Log.w(TAG, "CachedBluetoothDevice for device " + device +
270                        " not found, calling readPairedDevices().");
271                if (!readPairedDevices()) {
272                    Log.e(TAG, "Got bonding state changed for " + device +
273                            ", but we have no record of that device.");
274                    return;
275                }
276                cachedDevice = mDeviceManager.findDevice(device);
277                if (cachedDevice == null) {
278                    Log.e(TAG, "Got bonding state changed for " + device +
279                            ", but device not added in cache.");
280                    return;
281                }
282            }
283
284            synchronized (mCallbacks) {
285                for (BluetoothCallback callback : mCallbacks) {
286                    callback.onDeviceBondStateChanged(cachedDevice, bondState);
287                }
288            }
289            cachedDevice.onBondingStateChanged(bondState);
290
291            if (bondState == BluetoothDevice.BOND_NONE) {
292                int reason = intent.getIntExtra(BluetoothDevice.EXTRA_REASON,
293                        BluetoothDevice.ERROR);
294
295                showUnbondMessage(context, cachedDevice.getName(), reason);
296            }
297        }
void onBondingStateChanged(int bondState) {
        if (bondState == BluetoothDevice.BOND_NONE) {
            mProfiles.clear();
            mConnectAfterPairing = false;  // cancel auto-connect
            setPhonebookPermissionChoice(ACCESS_UNKNOWN);
            setMessagePermissionChoice(ACCESS_UNKNOWN);
            setSimPermissionChoice(ACCESS_UNKNOWN);
            mMessageRejectionCount = 0;
            saveMessageRejectionCount();
        }

        refresh();

        if (bondState == BluetoothDevice.BOND_BONDED) {
            if (mDevice.isBluetoothDock()) {
                onBondingDockConnect();
            } else if (mConnectAfterPairing) {
                connect(false);
            }
            mConnectAfterPairing = false;
        }
    

请大家自己跟踪一下,下面我省略了一些逻辑。接下来会走到

synchronized void connectInt(LocalBluetoothProfile profile) {
        if (!ensurePaired()) {
            return;
        }
        if (profile.connect(mDevice)) {
            if (Utils.D) {
                Log.d(TAG, "Command sent successfully:CONNECT " + describe(profile));
            }
            return;
        }
        Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
    }
具体connect的蓝牙功能是什么就会通过相关的协议进行连接。

2)取消配对过程

与配对过程类似

 



3、连接与取消连接

1)       连接过程

 

2)       取消连接过程

和连接过程类似,略。

4、扫描

A、通过调用BluetoothAdapter的startDiscovery()方法告诉底层开始搜索;

B、底层发广播通知应用找到设备或者扫描状态变化,从而更新ui。

 

猜你喜欢

转载自blog.csdn.net/pashanhu6402/article/details/79907306
今日推荐