系统设置之蓝牙模块分析

来源:互联网 发布:关于网络安全隐患论文 编辑:程序博客网 时间:2024/05/17 01:57

在蓝牙模块的开发中,许多的功能能够在普通的应用中实现,但是有些功能比如阻止/打开蓝牙可以被搜索,还是需要platform签名。。

首先,在系统设置界面,蓝牙等同于wifi模块,都是一个switch控件,所以控制蓝牙模块的就有一个BlueToothEnabler类,其中核心的方法就是BlueToothEnabler.OnCheckedChanged()方法。代码如下:

 @Override
    public void onSwitchChanged(Switch switchView, boolean isChecked) {
        // Show toast message if Bluetooth is not allowed in airplane mode
        if (isChecked &&
                !WirelessSettings.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
            Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
            // Reset switch to off
            switchView.setChecked(false);
        }


        if (mLocalAdapter != null) {
            mLocalAdapter.setBluetoothEnabled(isChecked);
        }
        mSwitch.setEnabled(false);
    }

public void setBluetoothEnabled(boolean enabled) {
        boolean success = enabled
                ? mAdapter.enable()
                : mAdapter.disable();


        if (success) {
            setBluetoothStateInt(enabled
                ? BluetoothAdapter.STATE_TURNING_ON
                : BluetoothAdapter.STATE_TURNING_OFF);
        } else {
            if (Utils.V) {
                Log.v(TAG, "setBluetoothEnabled call, manager didn't return " +
                        "success for enabled: " + enabled);
            }
   //发生了更改,异步刷新蓝牙状态
            syncBluetoothState();
        }
    }

// Returns true if the state changed; false otherwise.
    boolean syncBluetoothState() {
        int currentState = mAdapter.getState();
        if (currentState != mState) {
            setBluetoothStateInt(mAdapter.getState());
            return true;
        }
        return false;
    }

上面加粗的代码实现了蓝牙功能的开关。

setBluetoothStateInt方法将蓝牙信息存储到了本地,所以也可以从本地获取信息,蓝牙的设置过程中并非简单的使用了一个BlueToothAdapter对蓝牙进行控制,而是使用了本地存储技术,相当于缓存。

蓝牙的基本操作就是搜索附近的蓝牙并处理,

开始搜索:

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();
            }
        }
    }

在BlueToothSettings类中有一个updateContent方法,用于在打开蓝牙状态下开始搜索

接下来就是搜索结果的处理,处理的代码在BluetoothEventManager文件中实现。

 @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent
                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);


            Handler handler = mHandlerMap.get(action);
            if (handler != null) {
                handler.onReceive(context, intent, device);
            }

        }

具体的事项交由handler.onReceive完成,这些handler在前面的构造函数实现:

// Bluetooth on/off broadcasts
        addHandler(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedHandler());


        // Discovery broadcasts
        addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));
        addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));
        addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
        addHandler(BluetoothDevice.ACTION_DISAPPEARED, new DeviceDisappearedHandler());
        addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());


        // Pairing broadcasts
        addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
        addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());


        // Fine-grained state broadcasts
        addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
        addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());


        // Dock event broadcasts
        addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());


 void addHandler(String action, Handler handler) {
        mHandlerMap.put(action, handler);
        mAdapterIntentFilter.addAction(action);
    }

利用map将一个action和一个handler进行绑定

0 0
原创粉丝点击