zoukankan      html  css  js  c++  java
  • 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);
        }

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

  • 相关阅读:
    [daily][netcat] 在UNIX socket上使用netcat
    [emacs] emacs设置python code的indent
    [dev][python] 从python2进阶到python3你都需要了解什么
    [strongswan][autoconf][automake][cento] 在CentOS上编译strongswan git源码时遇到的autoconf问题
    [strongswan] strongswan是如何实现与xfrm之间的trap机制的
    对不可描述的软件安装sfbo插件
    [daily] 如何用emacs+xcscope阅读内核源码
    [daily] cscope
    [dev][ipsec] 什么是xfrm
    [dev][ipsec] netlink是什么
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4727889.html
Copyright © 2011-2022 走看看