在蓝牙模块的开发中,许多的功能能够在普通的应用中实现,但是有些功能比如阻止/打开蓝牙可以被搜索,还是需要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进行绑定