BluetoothSettings
设置 选项中 蓝牙开关的按钮。在settings代码中。
代码路径(packages\apps\Settings\src\com\android\settings\bluetooth\)
BluetoothSettings
//android8.0\packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothSettings.java
public final class BluetoothSettings extends DeviceListPreferenceFragment implements Indexable {
...
}
这个类,是蓝牙设置中的主界面。
我们通过这个类来完善对settings中蓝牙相关代码以及类的认识。
蓝牙开关
我们分析一下蓝牙开关按钮都做了什么操作。
//android8.0\packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothSettings.java
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
/* Don't auto start scan if screen reconstructs due to frozen screen*/
mInitialScanStarted = (savedInstanceState != null);
mInitiateDiscoverable = true;
final SettingsActivity activity = (SettingsActivity) getActivity();
mSwitchBar = activity.getSwitchBar();
//打开开关
mBluetoothEnabler = new BluetoothEnabler(activity, new SwitchBarController(mSwitchBar),
mMetricsFeatureProvider, Utils.getLocalBtManager(activity),
MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
mBluetoothEnabler.setupSwitchController();
}
BluetoothSettings.java是settings中蓝牙相对比较重要的类。在初始化(onActivityCreated)的时候,进行打开开关操作。
调用BluetoothEnabler来开启开关。
BluetoothEnabler构造方法
我们进入BluetoothEnabler的构造方法来看看都做了什么操作。
E:\android8.0\packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothEnabler.java
public BluetoothEnabler(Context context, SwitchWidgetController switchWidget,
MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
int metricsEvent, RestrictionUtils restrictionUtils) {
mContext = context;
mMetricsFeatureProvider = metricsFeatureProvider;
//ui选择控件
mSwitchWidget = switchWidget;
mSwitch = mSwitchWidget.getSwitch();
mSwitchWidget.setListener(this);
mValidListener = false;
mMetricsEvent = metricsEvent;
if (manager == null) {
// 蓝牙不支持。通过判断manager是否为空。
mLocalAdapter = null;
mSwitchWidget.setEnabled(false);
} else {
//1.1
//支持蓝牙的时候,是通过manager获取.
//这个manger是LocalBluetoothManager,这个类是为本地的蓝牙接口适配器,为应用提供接口,同时调用BluetoothAdapter的接口,起到应用和底层的适配作用。
mLocalAdapter = manager.getBluetoothAdapter();
}
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mRestrictionUtils = restrictionUtils;
}
1.1 LocalBluetoothManager
LocalBluetoothManager类将bluetooth api的接口封装。
public class LocalBluetoothManager {
private static final String TAG = "LocalBluetoothManager";
/** Singleton instance. */
private static LocalBluetoothManager sInstance;
private final Context mContext;
/** If a BT-related activity is in the foreground, this will be it. */
private Context mForegroundActivity;
private final LocalBluetoothAdapter mLocalAdapter;
private final CachedBluetoothDeviceManager mCachedDeviceManager;
/** The Bluetooth profile manager. */
private final LocalBluetoothProfileManager mProfileManager;
/** The broadcast receiver event manager. */
private final BluetoothEventManager mEventManager;
/**
获取一个示例
*/
public static synchronized LocalBluetoothManager getInstance(Context context,
BluetoothManagerCallback onInitCallback) {
if (sInstance == null) {
LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
if (adapter == null) {
return null;
}
// This will be around as long as this process is
Context appContext = context.getApplicationContext();
sInstance = new LocalBluetoothManager(adapter, appContext);
if (onInitCallback != null) {
onInitCallback.onBluetoothManagerInitialized(appContext, sInstance);
}
}
return sInstance;
}
//构造方法中new 了几个相关的manager来得到getxxxmanager。
private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
mContext = context;
mLocalAdapter = adapter;
//负责管理蓝牙的缓存(已配对的设备和搜索到的设备)主要都保存在List<CachedBluetoothDevice> mCachedDevices中
mCachedDeviceManager = new CachedBluetoothDeviceManager(context, this);
//接收广播,分发底层发出的event。一般android中定义eventxxx类其实就是传递的类。
mEventManager = new BluetoothEventManager(mLocalAdapter,
mCachedDeviceManager, context);
//蓝牙配置协议管理 例如A2dpProfile HeadsetProfile OppProfile PbapClientProfile有个印象即可。后续会进行详细讲解。
mProfileManager = new LocalBluetoothProfileManager(context,
mLocalAdapter, mCachedDeviceManager, mEventManager);
}
...
}
这个类的代码很少,用一个单例模式。构造方法中new出3个相应的xxxmanager。并且提供了3个方法来获取xxxmanager。
getCachedDeviceManager,getProfileManager,getEventManager。
获取mLocalAdapter有什么用?
BluetoothEnabler的handleStateChanged方法
我们先看看bluetootheabler的的handleStateChanged方法
// BluetoothEnabler.java
void handleStateChanged(int state) {
switch (state) {
case BluetoothAdapter.STATE_TURNING_ON:
mSwitchWidget.setEnabled(false);
break;
case BluetoothAdapter.STATE_ON:
setChecked(true);
mSwitchWidget.setEnabled(true);
break;
case BluetoothAdapter.STATE_TURNING_OFF:
mSwitchWidget.setEnabled(false);
break;
case BluetoothAdapter.STATE_OFF:
setChecked(false);
mSwitchWidget.setEnabled(true);
break;
default:
setChecked(false);
mSwitchWidget.setEnabled(true);
}
}
这个方法在onresume中被调用
BluetoothEnabler.java
public void resume(Context context) {
if (mContext != context) {
mContext = context;
}
maybeEnforceRestrictions();
if (mLocalAdapter == null) {
mSwitchWidget.setEnabled(false);
return;
}
// Bluetooth state is not sticky, so set it manually
handleStateChanged(mLocalAdapter.getBluetoothState());
mSwitchWidget.startListening();
mContext.registerReceiver(mReceiver, mIntentFilter);
mValidListener = true;
}
我们也就清楚了,进入这个bluetoothEnabler类后。onresume方法来进行获取状态。
传入的参数是
mLocalAdapter.getBluetoothState()
也就是我们之前分析的构造方法中 //1.1
//1.1
mLocalAdapter = manager.getBluetoothAdapter();
的用处。
已配对设备,可用设备
蓝牙打开后,会出现已经配对设备,可用设备。
//android8.0\packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothSettings.java
@Override
void addPreferencesForActivity() {
addPreferencesFromResource(R.xml.bluetooth_settings);
final Context prefContext = getPrefContext();
//已经配对设备列表
mPairedDevicesCategory = new PreferenceCategory(prefContext);
mPairedDevicesCategory.setKey(KEY_PAIRED_DEVICES);
mPairedDevicesCategory.setOrder(1);
//可用设备列表
getPreferenceScreen().addPreference(mPairedDevicesCategory);
mAvailableDevicesCategory = new BluetoothProgressCategory(prefContext);
mAvailableDevicesCategory.setSelectable(false);
mAvailableDevicesCategory.setOrder(2);
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
mMyDevicePreference = mFooterPreferenceMixin.createFooterPreference();
mMyDevicePreference.setSelectable(false);
setHasOptionsMenu(true);
}