首先说一下在修改蓝牙时所涉及到的目录,Android6.0的源码目录文件稍微有一些改动
相关文件位于以下几个目录,
1,\android\frameworks\base\core\java\android\bluetooth,该目录下存放有诸如BluetoothAdapter,BluetoothDevice,等一些底层文件,
2,\android\frameworks\base\packages\SettingsLib\src\com\android\settingslib\bluetooth,存放的是一些蓝牙协议,服务相关的文件
这些文件一般也不需要改动,除非需要新增一些蓝牙的通信协议,一般修改蓝牙的以下目录的文件
3,Z:\R3\android\packages\apps\Settings\src\com\android\settings\bluetooth
有关蓝牙的可检测性设置,可检测时间设置,界面UI布局,蓝牙的开关等等,均在该目录下设置
对所有蓝牙涉及到的文件目录有所了解后开始分析,不论是分析Android4.4.2.源码还是Android6.0源码逻辑方法是类似的,有什么疑问可参考我的有关Android4.4.2的源码的分析
Chapter One
蓝牙fragment为BluetoothSettings.java,先按覆写的方法进行分析,大体上过一遍
1,onActivityCreated中
mInitialScanStarted = (savedInstanceState != null);
mInitialScanStarted为boolean型的值,是蓝牙扫描开始的开关,在扫描前会判断该Boolean的值,若为true,则表示不需要进行蓝牙扫描,若为false,则表示可以进行扫描
如果蓝牙界面没有被销毁(比如蓝牙界面锁屏解锁后),也就是说有状态记录的话该值为true,则蓝牙没必要进行扫描
mInitiateDiscoverable = true;
mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
getListView().setEmptyView(mEmptyView);
mEmptyView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
final SettingsActivity activity = (SettingsActivity) getActivity();
mSwitchBar = activity.getSwitchBar();
mBluetoothEnabler = new BluetoothEnabler(activity, mSwitchBar);
mBluetoothEnabler.setupSwitchBar();
在Android6.0中的开关是自定义的一个ToggleButton+TextView,具体自定义会在另一篇博客中交代,在获取到switchBar以后将其传给BluetoothEnabler,该类专门用于处理两件事,
一是根据蓝牙的当前状态对switch进行更新,
void handleStateChanged(int state) {
switch (state) {
case BluetoothAdapter.STATE_TURNING_ON:
mSwitch.setEnabled(false);
break;
case BluetoothAdapter.STATE_ON:
setChecked(true);
mSwitch.setEnabled(true);
updateSearchIndex(true);
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
break;
case BluetoothAdapter.STATE_TURNING_OFF:
mSwitch.setEnabled(false);
break;
case BluetoothAdapter.STATE_OFF:
setChecked(false);
mSwitch.setEnabled(true);
updateSearchIndex(false);
break;
default:
setChecked(false);
mSwitch.setEnabled(true);
updateSearchIndex(false);
}
}
其实在这里可以看到在打开或者关闭蓝牙时,不仅是对switch进行设置操作,包括重新设置了蓝牙的可检测性,还有一个就是调用updateSearceIndex方法,用于更新数据的操作,在该方法中去更新跟蓝牙有关的一些数据,具体更新了什么数据,请稍待博客更新(不同于Android4.4.2)
二是,在switch开关滑动时对蓝牙的状态进行设
public void onSwitchChanged(Switch switchView, boolean isChecked) {
// Show toast message if Bluetooth is not allowed in airplane mode
if (isChecked &&
!WirelessUtils.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);
}
MetricsLogger.action(mContext, MetricsLogger.ACTION_BLUETOOTH_TOGGLE, isChecked);
if (mLocalAdapter != null) {
//在switch被check时去更新本地蓝牙状态(打开或者关闭)
mLocalAdapter.setBluetoothEnabled(isChecked);
}
//设置switch不可点击
mSwitch.setEnabled(false);
}
接下来回过头来接着分析BluetoothSetitngs.java,分析到这里onActivityCreated方法已经分析完毕,接下来继续
2,onConfigurationChanged方法
通过在Androidmanifest清单配置文件的activity节点下配置android:configChanges属性,则在activity形状(可以是size或者orientation )发生改变时会执行该方法。该方法可以避免activity的重新加载
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
3,addPreferencesForActivity方法
addPreferencesFromResource(R.xml.bluetooth_settings);
setHasOptionsMenu(true)
允许创建菜单
4,onResume方法
if (isUiRestricted()) {
setDeviceListGroup(getPreferenceScreen());
removeAllDevices();
mEmptyView.setText(R.string.bluetooth_empty_list_user_restricted);
return;
}
getActivity().registerReceiver(mReceiver, mIntentFilter);
if (mLocalAdapter.isEnabled() && mMyDevicePreference != null) {
mMyDevicePreference.setSummary(context.getResources().getString(
R.string.bluetooth_is_visible_message, mLocalAdapter.getName()));
}
-------------
updateContent(mLocalAdapter.getBluetoothState());
5,onCreateOptionsMenu方法
添加菜单
menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)//添加扫描菜单
.setEnabled(bluetoothIsEnabled && !isDiscovering)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
.setEnabled(bluetoothIsEnabled)//重命名设备
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);//显示接收到的文件
为preference添加点击事件,当点击已配对设备或者可用设备时首先停止扫描,然后判断是已配对设备还是可用设备,进而进行连接或者配对操作
mLocalAdapter.stopScanning();
super.onDevicePreferenceClick(btPreference);
7,onBluetoothStateChanged方法
当蓝牙状态发生改变时-----turn/off,会触发该方法,这是因为该方法继承与父类DeviceListPreferenceFragment,在BluetoothEventManager中对蓝牙状态改变进行了监听,当蓝牙状态改变时会调用该方法
if (BluetoothAdapter.STATE_ON == bluetoothState)
mInitiateDiscoverable = true;
updateContent(bluetoothState);
蓝牙状态改变时首先判断是否处于开启状态,如果处于开启状态,则将可检测性的开关打开
只要状态发生改变,都会对蓝牙界面的设备的preference进行更新
8,onScanningStateChanged方法
调用机制:在BluetoothEventManager方法中对蓝牙的扫描状态进行监听,当扫描状态发生改变时会调用该方法
if (getActivity() != null) {
getActivity().invalidateOptionsMenu();
}
9,onDeviceBondStateChanged方法
当配对状态发生改变时会调用该方法,清除设备列表,根据蓝牙的状态重新加载