最近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);

    }

版权声明:本文博客原创文章。博客,未经同意,不得转载。

Android4.4 蓝牙源代码段分析的更多相关文章

  1. ZT Android4.2蓝牙基础架构学习

    Android4.2蓝牙基础架构学习 分类: Jellybean Bluetooth Bluetooth 2013-10-13 23:58 863人阅读 评论(3) 收藏 举报 androidblue ...

  2. 《Android系统源代码情景分析》连载回忆录:灵感之源

    上个月,在花了一年半时间之后,写了55篇文章,分析完成了Chromium在Android上的实现,以及Android基于Chromium实现的WebView.学到了很多东西,不过也挺累的,平均不到两个 ...

  3. FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  4. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  5. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  6. FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  7. x264源代码简单分析:滤波(Filter)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  8. x264源代码简单分析:x264_slice_write()

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  9. x264源代码简单分析:编码器主干部分-2

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

随机推荐

  1. codechef Little Elephant and Permutations题解

    The Little Elephant likes permutations. This time he has a permutation A[1], A[2], ..., A[N] of numb ...

  2. Java实现BASE64编解码器

    Java实现BASE64编解码器 笔者:chszs,转载注明.博客首页:http://blog.csdn.net/chszs BASE64和其它类似的编码算法通经常使用于转换二进制数据为文本数据,其目 ...

  3. Red Gate系列之七 SQL Search 1.1.6.1 Edition SQL查询分析工具使用教程

    原文:Red Gate系列之七 SQL Search 1.1.6.1 Edition SQL查询分析工具使用教程 Red Gate系列之七 SQL Search 1.1.6.1 Edition SQL ...

  4. [网络]_[0基础]_[使用putty备份远程数据]

    场景: 1. putty是windows上訪问linux服务的免费client之中的一个.用它来ssh到远程server备份数据是常见的做法(在没做好自己主动备份机制前), 通过putty界面尽管也不 ...

  5. 【buildroot-2011.11】You may have to install &#39;g++&#39; on your build machine

    buildroot - 2011.11 当进行交叉编译.例如像以下错误提及演示: "You may have to install 'g++' on your build machine&q ...

  6. 【原创】纯OO:从设计到编码写一个FlappyBird (六)

    第五部分请看这里 终于到了最后一个部分了! 这里使用SimpleJudge类来实现Judge接口. 首先是SimpleJudge需要的实例变量: 0.final LinkedList<Pilla ...

  7. POJ 2586:Y2K Accounting Bug(贪心)

    Y2K Accounting Bug Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10024 Accepted: 4990 D ...

  8. Oracle 工艺结构

    Oracle工艺结构 这个过程是动态创建,完毕任务后就消亡:而程序是静态的实体,程序是能够复制.编辑的.进程强调的是运行过程,而程序不过指令的有序集合:进程在内存中,程序在外存中. ORACLE分为用 ...

  9. linux基础知识1

    1. 硬盘分区 分区类型:主分区,扩展分区.逻辑分区: 分区规则: 一个硬盘仅仅能有1到4个主分区: 一个硬盘仅仅能有1个扩展分区: 一个硬盘的主分区和扩展分区最多仅仅能有4个. 扩展分区仅仅能用来包 ...

  10. 用AsyncTask实现多线程

    前言 在Android应用开发中,有时我们需要实现任务的同步.Android里的AsyncTask类可以帮我们更好地管理线程同步(异步方式),就像Thread类能做的,不过用法比Thread更简单. ...