随州制作网站摄影公司网站
- 作者: 五速梦信息网
- 时间: 2026年04月20日 08:25
当前位置: 首页 > news >正文
随州制作网站,摄影公司网站,军事新闻最新消息中国南海今天,网站技术蓝牙是Android设备中非常常见的一个feature#xff0c;设备厂家可以用BT来做RC、连接音箱、设备本身做Sink等常见功能。如果一些设备不需要BT功能#xff0c;Android也可以通过配置来disable此模块#xff0c;方便厂家为自己的设备做客制化。APP操作设备的蓝牙功能#xff…蓝牙是Android设备中非常常见的一个feature设备厂家可以用BT来做RC、连接音箱、设备本身做Sink等常见功能。如果一些设备不需要BT功能Android也可以通过配置来disable此模块方便厂家为自己的设备做客制化。APP操作设备的蓝牙功能一般是通过标准API-BluetoothAdapter实现这里我们先不关心具体API的实现flow先来了解Bluetooth framework的启动过程这样可以为后面介绍一些BT 常见flow做铺垫。
我们都知道Android的主要系统服务都是在system_server中启动的BT也不例外 // Skip Bluetooth if we have an emulator kernel// TODO: Use a more reliable check to see if this product should// support Bluetooth - see bug 988521if (isEmulator) {Slog.i(TAG, No Bluetooth Service (emulator));} else if (mFactoryTestMode FactoryTest.FACTORY_TEST_LOW_LEVEL) {Slog.i(TAG, No Bluetooth Service (factory test));} else if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {Slog.i(TAG, No Bluetooth Service (Bluetooth Hardware Not Present));} else {traceBeginAndSlog(StartBluetoothService);mSystemServiceManager.startService(BluetoothService.class);traceEnd();}
在SystemServer中BT framework启动的起点以服务启动的形式表现这在Android中非常常见我们可以通过配置feature xml文件来表明系统当前是否支持蓝牙在一些没有蓝牙模组的设备上就可以去掉hardware feature bluetooth的声明这样设备启动时就不会启动BT framework相关的模块了
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.javaclass BluetoothService extends SystemService {private BluetoothManagerService mBluetoothManagerService;public BluetoothService(Context context) {super(context);//创建BluetoothManagerService的实例mBluetoothManagerService new BluetoothManagerService(context);}……..Overridepublic void onBootPhase(int phase) {if (phase SystemService.PHASE_SYSTEM_SERVICES_READY) {//将BluetoothManagerService实例发布到系统中这样就可以Context根据BT的service名去获取它的Binder代理操作API了publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,mBluetoothManagerService);} else if (phase SystemService.PHASE_ACTIVITY_MANAGER_READY) {//此时系统应该启动到一个比较晚的阶段了可以使用AMS去Bind需要的Service了mBluetoothManagerService.handleOnBootPhase();}}……..
}
BluetoothManagerService构造过程中跟开机flow中自动enable bt相关的主要是mEnableExternal这个flag BluetoothManagerService(Context context) {mHandler new BluetoothHandler(IoThread.get().getLooper());//创建内部处理msg的handlermContext context;mPermissionReviewRequired context.getResources().getBoolean(com.android.internal.R.bool.config_permissionReviewRequired);mCrashes 0;mBluetooth null;mBluetoothBinder null;mBluetoothGatt null;mBinding false;mUnbinding false;mEnable false;mState BluetoothAdapter.STATE_OFF;mQuietEnableExternal false;//false表示此次enable需要触发auto connect device和保存状态,BluetoothAdapter::enableNoAutoConnect()可以改变此状态mEnableExternal false;mAddress null;mName null;mErrorRecoveryRetryCounter 0;mContentResolver context.getContentResolver();// Observe BLE scan only mode settings change.registerForBleScanModeChange();mCallbacks new RemoteCallbackListIBluetoothManagerCallback();mStateChangeCallbacks new RemoteCallbackListIBluetoothStateChangeCallback();IntentFilter filter new IntentFilter();filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);//监听App通过接口修改BT local name的广播(对端设备搜索你显示的字符串)filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);//监听bt地址改变的广播filter.addAction(Intent.ACTION_SETTING_RESTORED);//监听当前设置需要restore回上一次设置的广播,此时需要重新保存name和addr为上一次的信息filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);mContext.registerReceiver(mReceiver, filter);loadStoredNameAndAddress();//从数据库中加载本机Bt的local name和addressif (isBluetoothPersistedStateOn()) {//查看上一次关机时,BT是否为enable状态;如果是,这次开机也需要enable BTif (DBG) {Slog.d(TAG, Startup: Bluetooth persisted state is ON.);}mEnableExternal true;//表明开机过程中需要enable BT}String airplaneModeRadios Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);if (airplaneModeRadios null || airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {mContentResolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,mAirplaneModeObserver);//监听Airplane mode改变,相应改变BT状态;这在TV plateform上基本没用}int systemUiUid -1;try {// Check if device is configured with no home screen, which implies no SystemUI.boolean noHome mContext.getResources().getBoolean(R.bool.config_noHomeScreen);if (!noHome) {systemUiUid mContext.getPackageManager().getPackageUidAsUser(com.android.systemui, PackageManager.MATCH_SYSTEM_ONLY,UserHandle.USER_SYSTEM);}Slog.d(TAG, Detected SystemUiUid: Integer.toString(systemUiUid));} catch (PackageManager.NameNotFoundException e) {// Some platforms, such as wearables do not have a system ui.Slog.w(TAG, Unable to resolve SystemUIs UID., e);}mSystemUiUid systemUiUid;}
它为true表明上一次关机前BT就是enable的这次开机也需要enable其他的主要是一些广播、数据库字段的初始化动作。
回到前面BluetoothService启动的过程当系统启动到合适的阶段就回调SystemService相应的函数当phase为PHASE_ACTIVITY_MANAGER_READY时调用到BMS::handleOnBootPhase()进行BT framework的启动 /*** Send enable message and set adapter name and address. Called when the boot phase becomes* PHASE_SYSTEM_SERVICES_READY.*/public void handleOnBootPhase() {if (DBG) {Slog.d(TAG, Bluetooth boot completed);}UserManagerInternal userManagerInternal LocalServices.getService(UserManagerInternal.class);userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);final boolean isBluetoothDisallowed isBluetoothDisallowed();if (isBluetoothDisallowed) {return;}if (mEnableExternal isBluetoothPersistedStateOnBluetooth()) {if (DBG) {Slog.d(TAG, Auto-enabling Bluetooth.);}sendEnableMsg(mQuietEnableExternal/默认false,表示此次enable需要自动连接device/保存enable状态/,BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,mContext.getPackageName());} else if (!isNameAndAddressSet()) {if (DBG) {Slog.d(TAG, Getting adapter name and address);}Message getMsg mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);mHandler.sendMessage(getMsg);}}
handleOnBootPhase()的内容比较单一根据一些flag判断是否需要enable BT而enable蓝牙这里是通过触发send msg实现 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {//发送MESSAGE_ENABLE msgmHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));addActiveLog(reason, packageName, true);mLastEnabledTime SystemClock.elapsedRealtime();}case MESSAGE_ENABLE:if (DBG) {Slog.d(TAG, MESSAGE_ENABLE( msg.arg1 ): mBluetooth mBluetooth);}mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);mEnable true;// Use service interface to get the exact statetry {mBluetoothLock.readLock().lock();if (mBluetooth ! null) { //开机第一次enable,值为nullint state mBluetooth.getState();if (state BluetoothAdapter.STATE_BLE_ON) {//大部分设备一般都不是ble only modeSlog.w(TAG, BT Enable in BLE_ON State, going to ON);mBluetooth.onLeServiceUp();persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);break;}}} catch (RemoteException e) {Slog.e(TAG, , e);} finally {mBluetoothLock.readLock().unlock();}mQuietEnable (msg.arg1 1);//此时为falseif (mBluetooth null) {//mBluetooth是后面绑定Bt apk中AdapterService时拿到的Binder代理对象;用以把操作bypass到BT核心框架中handleEnable(mQuietEnable);} else {//如果mBluetooth不是null,说明之前已经启动过了;此时是Restart flow,以MESSAGE_RESTART_BLUETOOTH_SERVICE触发//// We need to wait until transitioned to STATE_OFF and// the previous Bluetooth process has exited. The// waiting period has three components:// (a) Wait until the local state is STATE_OFF. This// is accomplished by waitForOnOff(false, true).// (b) Wait until the STATE_OFF state is updated to// all components.// © Wait until the Bluetooth process exits, and// ActivityManager detects it.// The waiting for (b) and © is accomplished by// delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE// message. On slower devices, that delay needs to be// on the order of (2 * SERVICE_RESTART_TIME_MS).//waitForOnOff(false, true);Message restartMsg mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);}break;
handleEnable()去Bind AdapterService拿到它的Binder句柄bindServiceAsUser如果服务端没有启动就会去启动服务端 private BluetoothServiceConnection mConnection new BluetoothServiceConnection();
……private class BluetoothServiceConnection implements ServiceConnection {public void onServiceConnected(ComponentName componentName, IBinder service) {String name componentName.getClassName();if (DBG) {Slog.d(TAG, BluetoothServiceConnection: name);}Message msg mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);if (name.equals(com.android.bluetooth.btservice.AdapterService)) {msg.arg1 SERVICE_IBLUETOOTH;} else if (name.equals(com.android.bluetooth.gatt.GattService)) {msg.arg1 SERVICE_IBLUETOOTHGATT;} else {Slog.e(TAG, Unknown service connected: name);return;}msg.obj service;mHandler.sendMessage(msg);}public void onServiceDisconnected(ComponentName componentName) {// Called if we unexpectedly disconnect.String name componentName.getClassName();if (DBG) {Slog.d(TAG, BluetoothServiceConnection, disconnected: name);}Message msg mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);if (name.equals(com.android.bluetooth.btservice.AdapterService)) {msg.arg1 SERVICE_IBLUETOOTH;} else if (name.equals(com.android.bluetooth.gatt.GattService)) {msg.arg1 SERVICE_IBLUETOOTHGATT;} else {Slog.e(TAG, Unknown service disconnected: name);return;}mHandler.sendMessage(msg);}}
……boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {ComponentName comp intent.resolveSystemService(mContext.getPackageManager(), 0);intent.setComponent(comp);if (comp null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {Slog.e(TAG, Fail to bind to: intent);return false;}return true;}
IBluetooth.class对于的Service声明在Bluetooth apk的manifest xml中AdapterService是真正的服务端
packages/apps/Bluetooth/AndroidManifest.xmlapplication android:name.btservice.AdapterAppandroid:iconmipmap/bt_shareandroid:persistentfalseandroid:labelstring/app_nameandroid:supportsRtltrueandroid:usesCleartextTrafficfalseandroid:directBootAwaretrueandroid:defaultToDeviceProtectedStoragetrueserviceandroid:processstring/processandroid:name .btservice.AdapterServiceintent-filteraction android:nameandroid.bluetooth.IBluetooth //intent-filter/service
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
public class AdapterService extends Service {private static final String TAG BluetoothAdapterService;public void onCreate() {super.onCreate();debugLog(onCreate());
去Bind AdapterService服务并拿到它的Binder句柄用以后面操作它的接口。AdapterService的初始化下篇再讲现在先回到BMS binder成功之后发送MESSAGE_BLUETOOTH_SERVICE_CONNECTED(arg1:SERVICE_IBLUETOOTH)的处理
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {if (DBG) {Slog.d(TAG, MESSAGE_BLUETOOTH_SERVICE_CONNECTED: msg.arg1);}IBinder service (IBinder) msg.obj; //保存Service的onBinder()句柄try {mBluetoothLock.writeLock().lock();if (msg.arg1 SERVICE_IBLUETOOTHGATT) {mBluetoothGatt IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));continueFromBleOnState();break;} // else must be SERVICE_IBLUETOOTH//Remove timeoutmHandler.removeMessages(MESSAGE_TIMEOUT_BIND);mBinding false;mBluetoothBinder service;mBluetooth IBluetooth.Stub.asInterface(Binder.allowBlocking(service));//再转成IBluetooth对象if (!isNameAndAddressSet()) {Message getMsg mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);mHandler.sendMessage(getMsg);if (mGetNameAddressOnly) {return;}}//Register callback objecttry {mBluetooth.registerCallback(mBluetoothCallback);//mBluetoothCallback用来监听BT的enable状态,如state_on/state_off的状态变化} catch (RemoteException re) {Slog.e(TAG, Unable to register BluetoothCallback, re);}//Inform BluetoothAdapter instances that service is upsendBluetoothServiceUpCallback();//Do enable requesttry {if (!mQuietEnable) {if (!mBluetooth.enable()) {//Service bind成功之后,call AdpaterService的enable()接口;做一些初始化动作,并向stack发送enable命令启动蓝牙Slog.e(TAG, IBluetooth.enable() returned false);}} else {if (!mBluetooth.enableNoAutoConnect()) {Slog.e(TAG, IBluetooth.enableNoAutoConnect() returned false);}}} catch (RemoteException e) {Slog.e(TAG, Unable to call enable(), e);}} finally {mBluetoothLock.writeLock().unlock();}if (!mEnable) {waitForOnOff(true, false);handleDisable();waitForOnOff(false, false);}break;} 主要操作
拿到bind服务的onBinder()句柄并转成IBluetooth类型 通过IBluetooth类型的obj调用enable()接口将flow转到AdapterService中做一些初始化、并向stack下enable bt的cmd 也要注意到如果BMS中和AdapterService的连接断掉了最终会通过MESSAGE_RESTART_BLUETOOTH_SERVICE msg去重新bind它这在场景可能是由于模组异常导致Bluetooth apk crash(会产生tombstone)与AdapterService的bind连接断掉这里触发Restart会导致重走一遍介绍的enable BT流程。
到此enable BT的flow就从BluetoothManagerService转到AdapterService中了实际上通过BluetoothAdapter下来的大部分API调用最终都是call到AdapterService再通过它下cmd给stack。
AdapterService是蓝牙框架中一个非常重要的服务它的启动和初始化部分我们下篇再单独介绍。
PS
可以看到BT启动过程中有两个常见到的flag
mEnable:它主要是用来标记系统运行时蓝牙状态的变化它有些时候时跟mEnableExternal值一致的。但如果蓝牙的状态是因为某些原因如stack崩溃导致蓝牙需要reset、重新启动时需要靠这个flag来标记这种case的enable/disable状态 mEnableExternal:它主要是记录通过用户手动操作导致的BT使能状态如通过蓝牙功能按钮来enable/disable BT packages/apps/Bluetooth/AndroidManifest.xml application android:name.btservice.AdapterApp android:iconmipmap/bt_share android:persistentfalse android:labelstring/app_name android:supportsRtltrue android:usesCleartextTrafficfalse android:directBootAwaretrue android:defaultToDeviceProtectedStoragetrue service android:processstring/process android:name .btservice.AdapterService intent-filter action android:nameandroid.bluetooth.IBluetooth / /intent-filter /service
- 上一篇: 随州网站优化什么软件做网站最好
- 下一篇: 遂昌赶街网站网站开发服务费记账
相关文章
-
随州网站优化什么软件做网站最好
随州网站优化什么软件做网站最好
- 技术栈
- 2026年04月20日
-
随州网站推广哪家专业深圳网页设计培训多少钱
随州网站推广哪家专业深圳网页设计培训多少钱
- 技术栈
- 2026年04月20日
-
随州网站建设哪家专业做男装比较好的网站
随州网站建设哪家专业做男装比较好的网站
- 技术栈
- 2026年04月20日
-
遂昌赶街网站网站开发服务费记账
遂昌赶街网站网站开发服务费记账
- 技术栈
- 2026年04月20日
-
遂宁市住房和城乡建设局网站哪些网站做的最好
遂宁市住房和城乡建设局网站哪些网站做的最好
- 技术栈
- 2026年04月20日
-
梭子手做鱼网站永康公司做网站
梭子手做鱼网站永康公司做网站
- 技术栈
- 2026年04月20日
