您的位置:首页 > 产品设计 > UI/UE

Bluetooth 蓝牙打开流程

2016-05-03 11:43 489 查看
蓝牙的打开连接主要流程:

打开

检测

扫描

连接

一、打开(开启蓝牙BT Turn on Turn off)

(蓝牙的on/off由类BluetoothEnabler控制。)

打开过程涉及到的类:

BluetoothEnabler(on/off的控制界面,界面的点击和状态文字的显示)

BluetoothService(最主要的类,开启具体命令的线程进行enable,disable等操作)

LocalBluetoothManager(本机蓝牙设备管理,开启关闭,搜索等等,初始化BluetoothAdapter)

BluetoothAdapter(framework封装的类,提供本地蓝牙设备的配置,包括开启蓝牙,搜索周围蓝牙设备,设置本地蓝牙可见性;建立LocalBluetoothManager和BluetoothService的映射关系,主要是通过它调用BluetoothService的函数)

BluetoothEventRedirector(接收Bluetooth API 的广播和回调,并且将Settings中的UI线程上的事件分派到正确的类)

以下是结合google原生6.0代码作的简要分析

/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java

BluetoothEnabler.java里面的函数onSwitchChanged(Switch switchView, boolean isChecked)监听on/off的变化,通过mLocalAdapter.setBluetoothEnabled(isChecked);设置下去。

@Override
179    public void onSwitchChanged(Switch switchView, boolean isChecked) {
180        // Show toast message if Bluetooth is not allowed in airplane mode
181        if (isChecked &&
182                !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
183            Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
184            // Reset switch to off
185            switchView.setChecked(false);
186        }
187
188        MetricsLogger.action(mContext, MetricsLogger.ACTION_BLUETOOTH_TOGGLE, isChecked);
189
190        if (mLocalAdapter != null) {
191            mLocalAdapter.setBluetoothEnabled(isChecked);
192        }
193        mSwitch.setEnabled(false);
194    }


2.打开(关闭)操作成功后会有一个异步事件ACTION_STATE_CHANGED返回,异步事件由类BluetoothEventRedirector控制(接收广播,进行处理)。在收到ACTION_STATE_CHANGED异步事件后,还需要做update本地设备profile的事情,读取上次关闭前搜索到的蓝牙设备。

(1) ACTION_STATE_CHANGED: 定义在/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java中。

(2)通过LocalBluetoothManager.setBluetoothStateInt(int state)方法调到 CachedBluetoothDeviceManager.onBluetoothStateChanged方法来读取上次关闭之前搜索到device.

public synchronized void onBluetoothStateChanged(int bluetoothState) {
153        // When Bluetooth is turning off, we need to clear the non-bonded devices
154        // Otherwise, they end up showing up on the next BT enable
155        if (bluetoothState == BluetoothAdapter.STATE_TURNING_OFF) {
156            for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
157                CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
158                if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
159                    cachedDevice.setVisible(false);
160                    mCachedDevices.remove(i);
161                } else {
162                    // For bonded devices, we need to clear the connection status so that
163                    // when BT is enabled next time, device connection status shall be retrieved
164                    // by making a binder call.
165                    cachedDevice.clearProfileConnectionState();
166                }
167            }
168        }
169    }


(3)来开启EnableThread线程,进行打开操作,蓝牙的打开关闭属于异步操作。

注意:

在启动蓝牙的时候,要注意的地方是不能正常启动蓝牙的情况,因为正常启动的时候会返回BluetoothIntent.ENABLED_ACTION 这个Intent,当时当启动出现异常的时候是没有Intent返回的,android使用回调函数来解决这个问题。

二、是否可检测性(Discoverable)

蓝牙模式有两种模式:

SCAN_MODE_CONNECTABLE_DISCOVERABLE(可连接可发现)

SCAN_MODE_CONNECTABLE(可连接但不可发现)

蓝牙的discoverable mode由/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java控制,

128    public boolean onPreferenceClick(Preference preference) {
129        // toggle discoverability
130        mDiscoverable = !mDiscoverable;
131        setEnabled(mDiscoverable);
132        return true;
133    }


通过onPreferenceClick()方法,调用setEnabled(mDiscoverable);,然后调用到BluetoothAdapter.java里面的setScanMode () 方法

1133    /** @hide */
1134    public boolean setScanMode(int mode) {
1135        if (getState() != STATE_ON) return false;
1136        /* getDiscoverableTimeout() to use the latest from NV than use 0 */
1137        return setScanMode(mode, getDiscoverableTimeout());
1138    }


小结可检测性这里用到的类有:

BluetoothDiscoverableEnabler.java

BluetoothAdapter.java

LocalBluetoothManager

三、扫描蓝牙

在/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java里面调用方法startScanning() ,然后到/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java

里面的函数

public void startScanning(boolean force) {
151        // Only start if we're not already scanning
152        if (!mAdapter.isDiscovering()) {
153            if (!force) {
154                // Don't scan more than frequently than SCAN_EXPIRATION_MS,
155                // unless forced
156                if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
157                    return;
158                }
159
160                // If we are playing music, don't scan unless forced.
161                A2dpProfile a2dp = mProfileManager.getA2dpProfile();
162                if (a2dp != null && a2dp.isA2dpPlaying()) {
163                    return;
164                }
165            }
166
167            if (mAdapter.startDiscovery()) {//开始搜索
168                mLastScan = System.currentTimeMillis();
169            }
170        }
171    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: