Android4.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);
    }
版权声明:本文博客原创文章。博客,未经同意,不得转载。
Android4.4 蓝牙源代码段分析的更多相关文章
- ZT  Android4.2蓝牙基础架构学习
		Android4.2蓝牙基础架构学习 分类: Jellybean Bluetooth Bluetooth 2013-10-13 23:58 863人阅读 评论(3) 收藏 举报 androidblue ... 
- 《Android系统源代码情景分析》连载回忆录:灵感之源
		上个月,在花了一年半时间之后,写了55篇文章,分析完成了Chromium在Android上的实现,以及Android基于Chromium实现的WebView.学到了很多东西,不过也挺累的,平均不到两个 ... 
- FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)
		===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ... 
- FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU
		===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ... 
- FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU
		===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ... 
- FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分
		===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ... 
- x264源代码简单分析:滤波(Filter)部分
		===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ... 
- x264源代码简单分析:x264_slice_write()
		===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ... 
- x264源代码简单分析:编码器主干部分-2
		===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ... 
随机推荐
- restrictkeyword
			今天在移植ffmpeg到opencore时出现一个编译错误: /libavcodec/dsputil.c:545: error: expected ';', ',' or ')' before 'bl ... 
- WPF DataGrid_SelectChanged获取单元内容
			private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { ... 
- freemarker 里 ?? 和 ? 都是什么意思
			??是推断对象是否为空,比如:<#if object??>object对象不为空(即object存在)</#if> ?后面要加keyword,比如:<#if object ... 
- oracle12c(oracle12.1.0.1.0)安装指南--实测OEL5.9(RH5)
			[root@oel ora12c]# uname -a Linux oel 2.6.39-300.26.1.el5uek #1 SMP Thu Jan 3 18:31:38 PST 2013 x86_ ... 
- VS2010不能编译SQLServer2005的Microsoft.SQLServer.ManagedDTS.dll的解决方法
			VS2010不能编译SQLServer2005的Microsoft.SQLServer.ManagedDTS.dll是最近碰到的一个疑难杂症问题,通过查询微软社区和一些英文资料找到了解决方法,同事说之 ... 
- Vue.js学习与理解
			Vue.js(读音 /vjuː/, 类似于 view)是一个构建数据驱动的 web 界面的库.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. Vue.js 自身不 ... 
- Google jsAPI托管你的js库
			来看一段JS: <script type="text/javascript" src="http://www.google.com/jsapi">& ... 
- php定时运行任务(windows7)
			1:自己写的php档,下面是我的一些php档 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzE2MDAyNA==/font/5a6L5L2T/f ... 
- 聊聊并发(六)——ConcurrentLinkedQueue的实现原理分析
			1. 引言 在并发编程中我们有时候需要使用线程安全的队列.如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把 ... 
- Eclipse正确导入第三方project
			前言 昨晚,在不同的Android做出最终的在线测试时间,在其他平台上正常升级的提示突然报告出来"java.lang.NoClassDefFoundError"误.拉什adb lo ... 
