Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Android 4.4 蓝牙源码部分分析

最近GOOGLE发布了Android4.4,看了一下源码;4.4的蓝牙打开流程这一部分还是有些变化的,从界面上看蓝牙开关就是设置settings里那个switch开关,widget开关当然也可以,起点不同后续的流程是一样的。先来看systemServer.java的代码,蓝牙服务开启的地方,真机情况下我们关心的是最后一个else分支。
 
if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
               Slog.i(TAG, "No Bluetooh Service (emulator)");
           } else if (factoryTest == SystemServer.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 if (disableBluetooth) {
               Slog.i(TAG, "Bluetooth Service disabled by config");
           } else {
               Slog.i(TAG, "Bluetooth Manager Service");
               bluetooth = new BluetoothManagerService(context);
               ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
           }
 看下bluetoothManagerService的构造方法,我们看三个地方, loadStoredNameAndAddress()是读取蓝牙打开默认名称的地方,isBluetoothPersistedStateOn()是判断是否已打开蓝牙的,如果已打开,后续操作要执行开启蓝牙的动作
 
BluetoothManagerService(Context context) {
       mHandler = new BluetoothHandler(IoThread.get().getLooper());
 
        mContext = context;
       mBluetooth = null;
       mQBluetooth = null;
       mBinding = false;
       mUnbinding = false;
       mEnable = false;
       mState = BluetoothAdapter.STATE_OFF;
       mQuietEnableExternal = false;
       mEnableExternal = false;
       mAddress = null;
       mName = null;
       mErrorRecoveryRetryCounter = 0;
       mContentResolver = context.getContentResolver();
       mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
       mQCallbacks = new RemoteCallbackList<IQBluetoothManagerCallback>();
       mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
       IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
       filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
       filter.addAction(Intent.ACTION_USER_SWITCHED);
       registerForAirplaneMode(filter);
       mContext.registerReceiver(mReceiver, filter);
       loadStoredNameAndAddress();
       if (isBluetoothPersistedStateOn()) {
           mEnableExternal = true;
       }
   }
 另外的registerForAirplaneMode方法,如下
 
private void registerForAirplaneMode(IntentFilter filter) {
       final ContentResolver resolver = mContext.getContentResolver();
       final String airplaneModeRadios = Settings.Global.getString(resolver,
               Settings.Global.AIRPLANE_MODE_RADIOS);
       final String toggleableRadios = Settings.Global.getString(resolver,
               Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
       boolean mIsAirplaneSensitive = airplaneModeRadios == null ? true :
               airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH);
       if (mIsAirplaneSensitive) {
           filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
       }
   }
 
其中
 
Settings.Global.getString(resolver,
               Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS)
 
获取到的值是在String文件中定义的,如:
 
<!-- Comma-separated list of bluetooth, wifi, and cell. -->
   <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi,nfc,wimax</string>
 表示如果开启飞行模式下,哪些服务将会被关闭。所以registerForAirplaneMode方法就是在如果蓝牙也受飞行模式影响,那么飞行模式的变化也将使蓝牙服务收到相应广播。
 
界面上开关就是BluetoothEnabler.java这个类了,而setBluetoothEnabled()则是具体开关动作。其中有开关的回调函数,代码如下:
 
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
       // Show toast message if Bluetooth is not allowed in airplane mode
       if (isChecked
               && (WifiSettings.needPrompt(mContext) || !WirelessSettings.isRadioAllowed(
                       mContext, Settings.Global.RADIO_BLUETOOTH))) {
           Toast.makeText(mContext, R.string.wifi_in_airplane_mode,
                   Toast.LENGTH_SHORT).show();
           // Reset switch to off
           buttonView.setChecked(false);
       }
 
        // shouldn"t setBluetoothEnabled(true) in airplane mode.
       if (mLocalAdapter != null) {
           if (isChecked && WifiSettings.needPrompt(mContext)) {
               return;
           }
           mLocalAdapter.setBluetoothEnabled(isChecked);
       }
       mSwitch.setEnabled(false);
   }Android 4.4.4 发布下载 http://www.linuxidc.com/Linux/2014-06/103467.htm最简单的Ubuntu Touch & Android 双系统安装方式 http://www.linuxidc.com/Linux/2014-01/94881.htm在Nexus上实现Ubuntu和Android 4.4.2 双启动 http://www.linuxidc.com/Linux/2014-05/101849.htmUbuntu 14.04 配置 Android SDK 开发环境 http://www.linuxidc.com/Linux/2014-05/101039.htm64位Ubuntu 11.10下Android开发环境的搭建(JDK+Eclipse+ADT+Android SDK详细) http://www.linuxidc.com/Linux/2013-06/85303.htmUbuntu 14.04 x64配置Android 4.4 kitkat编译环境的方法 http://www.linuxidc.com/Linux/2014-04/101148.htmUbuntu 12.10 x64 安装 Android SDK http://www.linuxidc.com/Linux/2013-03/82005.htm更多Android相关信息见Android 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=11本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-08/105325.htm