界面:
继承关系:
package com.android.settings.connecteddevice;
public class ConnectedDeviceDashboardFragment extends DashboardFragment{}
->
package com.android.settings.dashboard;
public abstract class DashboardFragment extends SettingsPreferenceFragment
implements
SettingsDrawerActivity.CategoryListener,
Indexable,
SummaryLoader.SummaryConsumer {}
->
package com.android.settings;
public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceFragment
implements DialogCreatable {}
->
package com.android.settings.core;
public abstract class InstrumentedPreferenceFragment extends ObservablePreferenceFragment
implements Instrumentable {}
->
package com.android.settings.core.lifecycle;
public abstract class ObservablePreferenceFragment extends PreferenceFragment {}
->
package android.support.v14.preference;
public abstract class PreferenceFragment extends Fragment implements
PreferenceManager.OnPreferenceTreeClickListener,
PreferenceManager.OnDisplayPreferenceDialogListener,
PreferenceManager.OnNavigateToScreenListener,
DialogPreference.TargetFragment {}
生命周期:
onAttach(Context context)
onCreate(Bundle savedInstanceState)
新增:onCreatePreferences(Bundle savedInstanceState, String rootKey)
onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
onViewCreated(View view, Bundle savedInstanceState)
onActivityCreated(Bundle savedInstanceState)
onStart()
onResume()
onPause()
onStop()
onDestroyView()
在onAttach(Context context)方法中设置Controller
DashboardFragment.class
private final Map<Class, PreferenceController> mPreferenceControllers = new ArrayMap<>();
@Override
public void onAttach(Context context) {
super.onAttach(context);
....
List<PreferenceController> controllers = getPreferenceControllers(context);
if (controllers == null) {
controllers = new ArrayList<>();
}
mPlaceholderPreferenceController =
new DashboardTilePlaceholderPreferenceController(context);
controllers.add(mPlaceholderPreferenceController);
for (PreferenceController controller : controllers) {
addPreferenceController(controller);
}
}
protected void addPreferenceController(PreferenceController controller) {
mPreferenceControllers.put(controller.getClass(), controller);
}
在onCreatePreferences(Bundle savedInstanceState, String rootKey)方法中设置PreferenceScreen数据:
ConnectedDeviceDashboardFragment.class
protected int getPreferenceScreenResId() {
return R.xml.connected_devices;
}
R.xml.connected_devices:
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/connected_devices_dashboard_title">
<!-- 蓝牙-->
<com.android.settings.widget.MasterSwitchPreference
android:fragment="com.android.settings.bluetooth.BluetoothSettings"
android:key="toggle_bluetooth"
android:title="@string/bluetooth_settings_title"
android:icon="@drawable/ic_settings_bluetooth"
android:order="-7"/>
<!-- NFC-->
<SwitchPreference
android:key="toggle_nfc"
android:title="@string/nfc_quick_toggle_title"
android:icon="@drawable/ic_nfc"
android:summary="@string/nfc_quick_toggle_summary"
android:order="-5"/>
<!-- Android Bean-->
<com.android.settingslib.RestrictedPreference
android:fragment="com.android.settings.nfc.AndroidBeam"
android:key="android_beam_settings"
android:title="@string/android_beam_settings_title"
android:icon="@drawable/ic_android"
android:order="-4"/>
<!-- USB-->
<Preference
android:key="usb_mode"
android:title="@string/usb_pref"
android:icon="@drawable/ic_usb"
android:order="-3">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.deviceinfo.UsbModeChooserActivity"/>
</Preference>
<PreferenceCategory
android:key="dashboard_tile_placeholder"
android:order="50"/>
</PreferenceScreen>
解析R.xml.connected_devices绑定Controller
DashboardFragment.class
onCreatePreferences(Bundle savedInstanceState, String rootKey)
refreshAllPreferences(getLogTag());
private void displayResourceTiles() {
//添加 xml
final int resId = getPreferenceScreenResId();
if (resId <= 0) {
return;
}
//解析xml
addPreferencesFromResource(resId);
//绑定 controller
final PreferenceScreen screen = getPreferenceScreen();
Collection<PreferenceController> controllers = mPreferenceControllers.values();
// xml中的item与controller建立联系
for (PreferenceController controller : controllers) {
controller.displayPreference(screen);
}
}
PreferenceFragment.class
public void addPreferencesFromResource(@XmlRes int preferencesResId) {
requirePreferenceManager();
setPreferenceScreen(
mPreferenceManager.inflateFromResource(mStyledContext, preferencesResId, getPreferenceScreen())
);
}
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
onUnbindPreferences();
mHavePrefs = true;
if (mInitDone) {
postBindPreferences();
}
}
}
PreferenceManager.class
public boolean setPreferences(PreferenceScreen preferenceScreen) {
if (preferenceScreen != mPreferenceScreen) {
if (mPreferenceScreen != null) {
mPreferenceScreen.onDetached();
}
mPreferenceScreen = preferenceScreen;
return true;
}
return false;
}
Preference初始化
package com.android.settings.widget;
public class MasterSwitchPreference extends TwoTargetPreference {}
package com.android.settingslib;
public class TwoTargetPreference extends Preference {}
package android.support.v7.preference;
public class Preference implements Comparable<Preference> {}
connected_devices.xml
<!-- 蓝牙item-->
<com.android.settings.widget.MasterSwitchPreference
android:fragment="com.android.settings.bluetooth.BluetoothSettings"
android:key="toggle_bluetooth"
android:title="@string/bluetooth_settings_title"
android:icon="@drawable/ic_settings_bluetooth"
android:order="-7"/>
MasterSwitchPreference.class
public MasterSwitchPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
// <Switch />
protected int getSecondTargetResId() {
return R.layout.preference_widget_master_switch;
}
TwoTargetPreference.class
public TwoTargetPreference(Context context) {
super(context);
init();
}
private void init() {
setLayoutResource(R.layout.preference_two_target);
final int secondTargetResId = getSecondTargetResId();
if (secondTargetResId != 0) {
setWidgetLayoutResource(secondTargetResId);
}
Preference.class
public Preference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
mContext = context;
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.Preference, defStyleAttr, defStyleRes);
mIconResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_icon,
R.styleable.Preference_android_icon, 0);
mKey = TypedArrayUtils.getString(a, R.styleable.Preference_key,
R.styleable.Preference_android_key);
mTitle = TypedArrayUtils.getText(a, R.styleable.Preference_title,
R.styleable.Preference_android_title);
mSummary = TypedArrayUtils.getText(a, R.styleable.Preference_summary,
R.styleable.Preference_android_summary);
mOrder = TypedArrayUtils.getInt(a, R.styleable.Preference_order,
R.styleable.Preference_android_order, DEFAULT_ORDER);
mFragment = TypedArrayUtils.getString(a, R.styleable.Preference_fragment,
R.styleable.Preference_android_fragment);
mLayoutResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_layout,
R.styleable.Preference_android_layout, R.layout.preference);
mWidgetLayoutResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_widgetLayout,
R.styleable.Preference_android_widgetLayout, 0);
mEnabled = TypedArrayUtils.getBoolean(a, R.styleable.Preference_enabled,
R.styleable.Preference_android_enabled, true);
mSelectable = TypedArrayUtils.getBoolean(a, R.styleable.Preference_selectable,
R.styleable.Preference_android_selectable, true);
mPersistent = TypedArrayUtils.getBoolean(a, R.styleable.Preference_persistent,
R.styleable.Preference_android_persistent, true);
mDependencyKey = TypedArrayUtils.getString(a, R.styleable.Preference_dependency,
R.styleable.Preference_android_dependency);
mAllowDividerAbove = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerAbove,
R.styleable.Preference_allowDividerAbove, mSelectable);
mAllowDividerBelow = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerBelow,
R.styleable.Preference_allowDividerBelow, mSelectable);
if (a.hasValue(R.styleable.Preference_defaultValue)) {
mDefaultValue = onGetDefaultValue(a, R.styleable.Preference_defaultValue);
} else if (a.hasValue(R.styleable.Preference_android_defaultValue)) {
mDefaultValue = onGetDefaultValue(a, R.styleable.Preference_android_defaultValue);
}
mShouldDisableView =
TypedArrayUtils.getBoolean(a, R.styleable.Preference_shouldDisableView,
R.styleable.Preference_android_shouldDisableView, true);
mHasSingleLineTitleAttr = a.hasValue(R.styleable.Preference_singleLineTitle);
if (mHasSingleLineTitleAttr) {
mSingleLineTitle = TypedArrayUtils.getBoolean(a, R.styleable.Preference_singleLineTitle,
R.styleable.Preference_android_singleLineTitle, true);
}
mIconSpaceReserved = TypedArrayUtils.getBoolean(a, R.styleable.Preference_iconSpaceReserved,
R.styleable.Preference_android_iconSpaceReserved, false);
a.recycle();
}
Preference绑定数据
在
public class PreferenceGroupAdapter extends RecyclerView.Adapter<PreferenceViewHolder>
implements Preference.OnPreferenceChangeInternalListener,
PreferenceGroup.PreferencePositionCallback {}
中调用
@Override
public void onBindViewHolder(PreferenceViewHolder holder, int position) {
final Preference preference = getItem(position);
preference.onBindViewHolder(holder);
}
MasterSwitchPreference.class
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
final View widgetView = holder.findViewById(android.R.id.widget_frame);
if (widgetView != null) {
widgetView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mSwitch != null && !mSwitch.isEnabled()) {
return;
}
setChecked(!mChecked);
if (!callChangeListener(mChecked)) {
setChecked(!mChecked);
} else {
persistBoolean(mChecked);
}
}
});
}
mSwitch = (Switch) holder.findViewById(R.id.switchWidget);
if (mSwitch != null) {
mSwitch.setContentDescription(getTitle());
mSwitch.setChecked(mChecked);//false
mSwitch.setEnabled(mEnableSwitch);//true
}
}
TwoTargetPreference.class
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
final View divider = holder.findViewById(R.id.two_target_divider);
final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
final boolean shouldHideSecondTarget = shouldHideSecondTarget();
if (divider != null) {
divider.setVisibility(shouldHideSecondTarget ? View.GONE : View.VISIBLE);
}
if (widgetFrame != null) {
widgetFrame.setVisibility(shouldHideSecondTarget ? View.GONE : View.VISIBLE);
}
}
Preference.class
public void onBindViewHolder(PreferenceViewHolder holder) {
//item的点击事件
holder.itemView.setOnClickListener(mClickListener);
绑定xml中的数据
....
}
Preference的点击事件
Preference.class
private final View.OnClickListener mClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
performClick(v);
}
};
@RestrictTo(LIBRARY_GROUP)
protected void performClick(View view) {
performClick();
}
@RestrictTo(LIBRARY_GROUP)
public void performClick() {
if (!isEnabled()) {
return;
}
//1.子类重写
onClick();
//2.Preference.OnPreferenceClickListener
if (mOnClickListener != null && mOnClickListener.onPreferenceClick(this)) {
return;
}
//3.PreferenceManager.OnPreferenceTreeClickListener
PreferenceManager preferenceManager = getPreferenceManager();
if (preferenceManager != null) {
PreferenceManager.OnPreferenceTreeClickListener listener = preferenceManager
.getOnPreferenceTreeClickListener();
//把当前的Preference回调给调用者
if (listener != null && listener.onPreferenceTreeClick(this)) {
return;
}
}
//4.Intent启动
if (mIntent != null) {
Context context = getContext();
context.startActivity(mIntent);
}
}
protected void onClick() {
}
PreferenceManager.OnPreferenceTreeClickListener在PreferenceFragment.class中实现
PreferenceFragment.class
@Override
public void onStart() {
super.onStart();
//添加点击事件
mPreferenceManager.setOnPreferenceTreeClickListener(this);
mPreferenceManager.setOnDisplayPreferenceDialogListener(this);
}
@Override
public void onStop() {
super.onStop();
//移除点击事件
mPreferenceManager.setOnPreferenceTreeClickListener(null);
mPreferenceManager.setOnDisplayPreferenceDialogListener(null);
}
/**
* {@inheritDoc}
*/
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (preference.getFragment() != null) {
boolean handled = false;
//getCallbackFragment()在v17 LeanbackPreference中实现
if (getCallbackFragment() instanceof OnPreferenceStartFragmentCallback) {
handled = ((OnPreferenceStartFragmentCallback) getCallbackFragment())
.onPreferenceStartFragment(this, preference);
}
//PreferenceFragment.OnPreferenceStartFragmentCallback在SettingsActivity中实现
if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback) {
handled = ((OnPreferenceStartFragmentCallback) getActivity())
.onPreferenceStartFragment(this, preference);
}
return handled;
}
return false;
}
SettingsActivity.class
//xml中配置的Fragment
@Override
public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
startPreferencePanel(caller, pref.getFragment(), pref.getExtras(), -1, pref.getTitle(),
null, 0);
//返回true消费当前事件
return true;
}
PreferenceManager的传递:
PreferenceManager.class在PreferenceFragment.class的onCreate(...)方法初始化,然后通过xml解析,传递给顶层的PreferenceScreen。
PreferenceInflater.class在PreferenceManager.class的inflateFromResource(...)方法初始化。然后解析xml生成Preference。
解析方法调用顺序:
inflate(...)->rInflate(...)<->rInflate(...),在rInflate(...)中会向PreferenceScreen.class添加Preference.class,调用PreferenceGroup.class中的addItemFromInflater(...)->addPreference(...),
PreferenceGroup.class
public boolean addPreference(Preference preference) {
...
//获取Group的的PreferenceManager
final PreferenceManager preferenceManager = getPreferenceManager();
...
//将PreferenceManager传递给子Preference
preference.onAttachedToHierarchy(preferenceManager, id);
...
return true;
}
蓝牙Preference:
BluetoothMasterSwitchPreferenceController.class初始化
package com.android.settings.bluetooth;
public class BluetoothMasterSwitchPreferenceController extends PreferenceController
implements OnSummaryChangeListener,
LifecycleObserver, OnResume, OnPause, OnStart, OnStop {}
->
package com.android.settings.core;
public abstract class PreferenceController extends AbstractPreferenceController{}
->
package com.android.settingslib.core;
public abstract class AbstractPreferenceController {}
在ConnectedDeviceDashboardFragment.class的List<PreferenceController> getPreferenceControllers(...)方法中初始化
final BluetoothMasterSwitchPreferenceController bluetoothPreferenceController =
new BluetoothMasterSwitchPreferenceController(
context,
Utils.getLocalBtManager(context));
//构造方法
@VisibleForTesting
public BluetoothMasterSwitchPreferenceController(
Context context,
LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils) {
super(context);
//初始化
mBluetoothManager = bluetoothManager;
mSummaryUpdater = new BluetoothSummaryUpdater(mContext, this, mBluetoothManager);
mRestrictionUtils = restrictionUtils;
}
@Override
public boolean isAvailable() {
return true;
//Preference与Controller绑定时调用
AbstractPreferenceController.class
public void displayPreference(PreferenceScreen screen) {
if (isAvailable()) {
//BluetoothMasterSwitchPreferenceController未实现
if (this instanceof Preference.OnPreferenceChangeListener) {
final Preference preference = screen.findPreference(getPreferenceKey());
preference.setOnPreferenceChangeListener(
(Preference.OnPreferenceChangeListener) this);
}
} else {
removePreference(screen, getPreferenceKey());
}
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
//根据key="toggle_bluetooth"找到item
mBtPreference = (MasterSwitchPreference) screen.findPreference(KEY_TOGGLE_BLUETOOTH);
mBluetoothEnabler = new BluetoothEnabler(
mContext,
new MasterSwitchController(mBtPreference),
FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(),
mBluetoothManager,
MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE,
mRestrictionUtils);
}
LocalBluetoothManager初始化:
package com.android.settings.bluetooth;
Utils.class
public static LocalBluetoothManager getLocalBtManager(Context context) {
return LocalBluetoothManager.getInstance(context, mOnInitCallback);
}
private static final BluetoothManagerCallback mOnInitCallback = new BluetoothManagerCallback() {
@Override
public void onBluetoothManagerInitialized(Context appContext,
LocalBluetoothManager bluetoothManager) {
//只是set listener
com.android.settingslib.bluetooth.Utils.setErrorListener(mErrorListener);
}
};
package com.android.settingslib.bluetooth;
LocalBluetoothManager.class
public static synchronized LocalBluetoothManager getInstance(Context context,
BluetoothManagerCallback onInitCallback) {
if (sInstance == null) {
//adapter
LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
if (adapter == null) {
return null;
}
// This will be around as long as this process is
//只要这个过程存在,它就会存在
Context appContext = context.getApplicationContext();
//manager
sInstance = new LocalBluetoothManager(adapter, appContext);
if (onInitCallback != null) {
onInitCallback.onBluetoothManagerInitialized(appContext, sInstance);
}
}
return sInstance;
}
public interface BluetoothManagerCallback {
void onBluetoothManagerInitialized(Context appContext,
LocalBluetoothManager bluetoothManager);
}
private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
mContext = context;
mLocalAdapter = adapter;
//1。
mCachedDeviceManager = new CachedBluetoothDeviceManager(context, this);
//2.蓝牙广播事件管理
mEventManager = new BluetoothEventManager(
mLocalAdapter,
mCachedDeviceManager,
context);
//3。
mProfileManager = new LocalBluetoothProfileManager(
context,
mLocalAdapter,
mCachedDeviceManager,
mEventManager);
}
LocalBluetoothAdapter.class
package com.android.settingslib.bluetooth;
static synchronized LocalBluetoothAdapter getInstance() {
if (sInstance == null) {
//package android.bluetooth;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
//包装成LocalBluetoothAdapter
sInstance = new LocalBluetoothAdapter(adapter);
}
}
return sInstance;
}
//构造函数
private LocalBluetoothAdapter(BluetoothAdapter adapter) {
mAdapter = adapter;
}
BluetoothAdapter.class
package android.bluetooth;
public static synchronized BluetoothAdapter getDefaultAdapter() {
if (sAdapter == null) {
IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
if (b != null) {
//获取IBluetoothManager
IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
//包装成BluetoothAdapter
sAdapter = new BluetoothAdapter(managerService);
} else {
Log.e(TAG, "Bluetooth binder is null");
}
}
return sAdapter;
}
BluetoothAdapter(IBluetoothManager managerService) {
if (managerService == null) {
throw new IllegalArgumentException("bluetooth manager service is null");
}
try {
//写锁
mServiceLock.writeLock().lock();
mService = managerService.registerAdapter(mManagerCallback);
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.writeLock().unlock();
}
mManagerService = managerService;
mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
mToken = new Binder();
}
final private IBluetoothManagerCallback mManagerCallback =
new IBluetoothManagerCallback.Stub() {
public void onBluetoothServiceUp(IBluetooth bluetoothService) {
....
}
public void onBluetoothServiceDown() {
....
}
public void onBrEdrDown() {
....
}
};
CachedBluetoothDeviceManager.class
package com.android.settingslib.bluetooth;
CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
mContext = context;
mBtManager = localBtManager;
}
BluetoothEventManager.class
package com.android.settingslib.bluetooth;
BluetoothEventManager(LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
Context context) {
mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mAdapterIntentFilter = new IntentFilter();
mProfileIntentFilter = new IntentFilter();
//广播Action 和 Handler 缓存
mHandlerMap = new HashMap<String, Handler>();
mContext = context;
// 自定义广播
// Bluetooth on/off broadcasts
addHandler(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedHandler());
// Generic connected/not broadcast
addHandler(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED,
new ConnectionStateChangedHandler());
// 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());
addHandler(BluetoothDevice.ACTION_ALIAS_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());
mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler);
}
interface Handler {
void onReceive(Context context, Intent intent, BluetoothDevice device);
}
//Handler 非 android.os.Handler
private void addHandler(String action, Handler handler) {
mHandlerMap.put(action, handler);
mAdapterIntentFilter.addAction(action);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@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);
}
}
};
LocalBluetoothProfileManager.class
package com.android.settingslib.bluetooth;
LocalBluetoothProfileManager(Context context,
LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
BluetoothEventManager eventManager) {
mContext = context;
mLocalAdapter = adapter;
mDeviceManager = deviceManager;
mEventManager = eventManager;
mUsePbapPce = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
// MAP Client is typically used in the same situations as PBAP Client
//MAP客户机通常与PBAP客户机在相同的情况下使用
mUseMapClient = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
// pass this reference to adapter and event manager (circular dependency)
//将此引用传递给适配器和事件管理器(循环依赖项)
mLocalAdapter.setProfileManager(this);
mEventManager.setProfileManager(this);
ParcelUuid[] uuids = adapter.getUuids();
// uuids may be null if Bluetooth is turned off
if (uuids != null) {
updateLocalProfiles(uuids);
}
// Always add HID and PAN profiles
mHidProfile = new HidProfile(context, mLocalAdapter, mDeviceManager, this);
addProfile(mHidProfile, HidProfile.NAME,
BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
mPanProfile = new PanProfile(context);
addPanProfile(mPanProfile, PanProfile.NAME,
BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
if (DEBUG) Log.d(TAG, "Adding local MAP profile");
if (mUseMapClient) {
mMapClientProfile = new MapClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
addProfile(mMapClientProfile, MapClientProfile.NAME,
BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
} else {
mMapProfile = new MapProfile(mContext, mLocalAdapter, mDeviceManager, this);
addProfile(mMapProfile, MapProfile.NAME,
BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
}
//Create PBAP server profile, but do not add it to list of profiles
// as we do not need to monitor the profile as part of profile list
mPbapProfile = new PbapServerProfile(context);
if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
}
BluetoothSummaryUpdater.class初始化:
package com.android.settings.bluetooth;
public final class BluetoothSummaryUpdater extends SummaryUpdater implements BluetoothCallback {}
//构造函数
public BluetoothSummaryUpdater(Context context, OnSummaryChangeListener listener,
LocalBluetoothManager bluetoothManager) {
super(context, listener);
mBluetoothManager = bluetoothManager;
mBluetoothAdapter = mBluetoothManager != null
? mBluetoothManager.getBluetoothAdapter() : null;
}
//OnSummaryChangeListener的回调函数
@Override
public void onSummaryChanged(String summary) {
if (mBtPreference != null) {
mBtPreference.setSummary(summary);
}
}
RestrictionUtils.class初始化:
public class RestrictionUtils {
public RestrictionUtils() {}
/**
* Utility method to check if user restriction is enforced on the current user.
*检查当前用户是否受到用户限制的实用方法。
*
It helps with testing - override it to avoid calling static method which calls system
* API.
* 它有助于测试——覆盖它以避免调用调用系统API的静态方法。
*/
public EnforcedAdmin checkIfRestrictionEnforced(Context context, String restriction) {
return RestrictedLockUtils.checkIfRestrictionEnforced(
context, restriction, UserHandle.myUserId());
}
}
package com.android.settings.bluetooth;
BluetoothEnabler.class初始化
package com.android.settings.bluetooth;
public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchChangeListener{}
public BluetoothEnabler(Context context, SwitchWidgetController switchWidget,
MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
int metricsEvent, RestrictionUtils restrictionUtils) {
mContext = context;
mMetricsFeatureProvider = metricsFeatureProvider;
//处理switch
mSwitchWidget = switchWidget;
mSwitch = mSwitchWidget.getSwitch();
mSwitchWidget.setListener(this);
mValidListener = false;
mMetricsEvent = metricsEvent;
if (manager == null) {
// Bluetooth is not supported
mLocalAdapter = null;
mSwitchWidget.setEnabled(false);
} else {
mLocalAdapter = manager.getBluetoothAdapter();
}
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mRestrictionUtils = restrictionUtils;
}
BluetoothMasterSwitchPreferenceController.class生命周期
public void onResume() {
mSummaryUpdater.register(true);
}
@Override
public void onPause() {
mSummaryUpdater.register(false);
}
//mSummaryUpdater.register(true)
@Override
public void register(boolean listening) {
if (mBluetoothAdapter == null) {
return;
}
if (listening) {
mEnabled = mBluetoothAdapter.isEnabled();
//蓝牙连接状态
mConnectionState = mBluetoothAdapter.getConnectionState();
notifyChangeIfNeeded();
//蓝牙事件监听
mBluetoothManager.getEventManager().registerCallback(this);
/*
public interface BluetoothCallback {
void onBluetoothStateChanged(int bluetoothState);
void onScanningStateChanged(boolean started);
void onDeviceAdded(CachedBluetoothDevice cachedDevice);
void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState);
void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state);
}
* */
} else {
mBluetoothManager.getEventManager().unregisterCallback(this);
}
}
/**
* Notifies the listener when there is update in summary
* 在摘要中有更新时通知侦听器
*/
protected void notifyChangeIfNeeded() {
String summary = getSummary();
//状态改变
if (!TextUtils.equals(mSummary, summary)) {
mSummary = summary;
if (mListener != null) {
mListener.onSummaryChanged(summary);
}
}
}
@Override
public String getSummary() {
if (!mEnabled) {
return mContext.getString(R.string.bluetooth_disabled);
}
switch (mConnectionState) {
case BluetoothAdapter.STATE_CONNECTED:
return getConnectedDeviceSummary();
case BluetoothAdapter.STATE_CONNECTING:
return mContext.getString(R.string.bluetooth_connecting);
case BluetoothAdapter.STATE_DISCONNECTING:
return mContext.getString(R.string.bluetooth_disconnecting);
default:
return mContext.getString(R.string.disconnected);
}
}
Preference.class
package android.support.v7.preference;
public void setSummary(CharSequence summary) {
if ((summary == null && mSummary != null)
|| (summary != null && !summary.equals(mSummary))) {
mSummary = summary;
notifyChanged();
}
}
protected void notifyChanged() {
if (mListener != null) {
mListener.onPreferenceChange(this);
}
}
interface OnPreferenceChangeInternalListener {
void onPreferenceChange(Preference preference);
void onPreferenceHierarchyChange(Preference preference);
void onPreferenceVisibilityChange(Preference preference);
}
PreferenceGroupAdapter.class
package android.support.v7.preference;
public class PreferenceGroupAdapter extends RecyclerView.Adapter<PreferenceViewHolder>
implements Preference.OnPreferenceChangeInternalListener,
PreferenceGroup.PreferencePositionCallback {}
@Override
public void onPreferenceChange(Preference preference) {
final int index = mPreferenceList.indexOf(preference);
// If we don't find the preference, we don't need to notify anyone
if (index != -1) {
// Send the pref object as a placeholder to ensure the view holder is recycled in place
//通知RecyclerView刷新指定item
notifyItemChanged(index, preference);
}
}
@Override
public void onStart() {
if (mBluetoothEnabler != null) {
mBluetoothEnabler.resume(mContext);
}
}
@Override
public void onStop() {
if (mBluetoothEnabler != null) {
mBluetoothEnabler.pause();
}
}
BluetoothEnabler.class
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;
}
/**
* Enforces user restrictions disallowing Bluetooth (or its configuration) if there are any.
*强制用户禁止蓝牙(或其配置),如果有的话。
* @return if there was any user restriction to enforce.
* 如果需要执行任何用户限制。
*/
@VisibleForTesting
boolean maybeEnforceRestrictions() {
EnforcedAdmin admin = mRestrictionUtils.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_BLUETOOTH);
if (admin == null) {
admin = mRestrictionUtils.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH);
}
mSwitchWidget.setDisabledByAdmin(admin);
if (admin != null) {
mSwitchWidget.setChecked(false);
if (mSwitch != null) {
mSwitch.setEnabled(false);
mSwitch.setChecked(false);
}
}
return admin != null;
}
/**
* If admin is not null, disables the switch.
* Otherwise, keep it enabled.
*
* 如果admin不为空,则禁用开关。否则,保持启用。
*/
public void setDisabledByAdmin(EnforcedAdmin admin) {
setSwitchEnabled(admin == null);
}
public void setSwitchEnabled(boolean enabled) {
mEnableSwitch = enabled;
if (mSwitch != null) {
mSwitch.setEnabled(enabled);
}
}
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);
}
}
private void setChecked(boolean isChecked) {
if (isChecked != mSwitchWidget.isChecked()) {
// set listener to null, so onCheckedChanged won't be called
// if the checked status on Switch isn't changed by user click
if (mValidListener) {
mSwitchWidget.stopListening();
}
mSwitchWidget.setChecked(isChecked);
if (mValidListener) {
mSwitchWidget.startListening();
}
}
}