iis服务器助手广告
返回顶部
首页 > 资讯 > 移动开发 >Android9.0 蓝牙开启流程
  • 136
分享到

Android9.0 蓝牙开启流程

Android蓝牙 2022-06-06 14:06:25 136人浏览 八月长安
摘要

第一次接触蓝牙,先从蓝牙的开启流程入手吧,借此顺便熟悉一下蓝牙的代码架构。 1、UI /packages/apps/Settings/src/c

第一次接触蓝牙,先从蓝牙的开启流程入手吧,借此顺便熟悉一下蓝牙的代码架构

1、UI

/packages/apps/Settings/src/com/Android/settings/bluetooth/BluetoothSwitchPreferenceController.java

public void onClick(View v) {
    // send users to scanning settings if they click on the link in the summary text
    new SubSettingLauncher(mContext)
            .setDestination(ScanningSettings.class.getName())
            .setSourceMetricsCateGory(MetricsProto.MetricsEvent.BLUETOOTH_FRAGMENT)
            .launch();
}

/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java

public boolean onSwitchToggled(boolean isChecked) {
    if (maybeEnforceRestrictions()) {
        triggerParentPreferenceCallback(isChecked);
        return true;
    }
    // Show toast message if Bluetooth is not allowed in airplane mode
    if (isChecked &&
            !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
        Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
        // Reset switch to off
        mSwitchController.setChecked(false);
        triggerParentPreferenceCallback(false);
        return false;
    }
    mMetricsFeatureProvider.action(mContext, mMetricsEvent, isChecked);
    if (mLocalAdapter != null) {
        boolean status = mLocalAdapter.setBluetoothEnabled(isChecked);
        // If we cannot toggle it ON then reset the UI assets:
        // a) The switch should be OFF but it should still be togglable (enabled = True)
        // b) The switch bar should have OFF text.
        if (isChecked && !status) {
            mSwitchController.setChecked(false);
            mSwitchController.setEnabled(true);
            mSwitchController.updateTitle(false);
            triggerParentPreferenceCallback(false);
            return false;
        }
    }
    mSwitchController.setEnabled(false);
    triggerParentPreferenceCallback(isChecked);
    return true;
}
2、framework

/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java

public boolean setBluetoothEnabled(boolean enabled) {
    boolean success = enabled
            ? mAdapter.enable()
            : mAdapter.disable();
    if (success) {
        setBluetoothStateInt(enabled
            ? BluetoothAdapter.STATE_TURNING_ON
            : BluetoothAdapter.STATE_TURNING_OFF);
    } else {
        if (Utils.V) {
            Log.v(TAG, "setBluetoothEnabled call, manager didn't return " +
                    "success for enabled: " + enabled);
        }
        syncBluetoothState();
    }
    return success;
}

/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java

@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
 public boolean enable() {
     if (isEnabled()) {
         if (DBG) {
             Log.d(TAG, "enable(): BT already enabled!");
         }
         return true;
     }
     try {
         return mManagerService.enable(ActivityThread.currentPackageName());
     } catch (RemoteException e) {
         Log.e(TAG, "", e);
     }
     return false;
 }

这个方法中的关键代码是“return mManagerService.enable();” mManagerService 对象是由IBluetoothManager 接口代码实现的,IBluetoothManager实际定义的是AIDL文件,对应的类就是 BluetoothManagerService 类,在路径 frameworks/base/core/java/android/bluetooth/BluetoothManagerService 下面 。

/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java

public boolean enable(String packageName) throws RemoteException {
    final int callingUid = Binder.getCallingUid();
    final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
    if (isBluetoothDisallowed()) {
        if (DBG) {
            Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
        }
        return false;
    }
    if (!callerSystem) {
        if (!checkIfCallerIsForegroundUser()) {
            Slog.w(TAG, "enable(): not allowed for non-active and non system user");
            return false;
        }
        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                "Need BLUETOOTH ADMIN permission");
        if (!isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
                callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
            return false;
        }
    }
    if (DBG) {
        Slog.d(TAG, "enable(" + packageName + "):  mBluetooth =" + mBluetooth + " mBinding = "
                + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
    }
    synchronized (mReceiver) {
        MQuietEnableExternal = false;
        mEnableExternal = true;
        // waive WRITE_SECURE_SETTINGS permission check
        sendEnableMsg(false,
                BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
    }
    if (DBG) {
        Slog.d(TAG, "enable returning");
    }
    return true;
}

方法中先判断是否是系统app操作蓝牙,检查是否有操作蓝牙的权限等,然后关键的代码是“sendEnableMsg(false)”,handler最后调用handleEnable方法处理该消息。

private void handleEnable(boolean quietMode) {
    mQuietEnable = quietMode;
    try {
        mBluetoothLock.writeLock().lock();
        if ((mBluetooth == null) && (!mBinding)) {
            //Start bind timeout and bind
            Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
            mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
            Intent i = new Intent(IBluetooth.class.getName());
            if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                    UserHandle.CURRENT)) {
                mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
            } else {
                mBinding = true;
            }
        } else if (mBluetooth != null) {
            //Enable bluetooth
            try {
                if (!mQuietEnable) {
                    if (!mBluetooth.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();
    }
}

这里通过AIDL的方式,调用Bluetooth App 中的AdapterService 。先绑定服务,然后注册Ibluetooth回调函数,之后调用enable方法方法开启蓝牙。所以之后就从Framworks 跳到 Bluetooth APP 中继续分析。

3、Bluetooth APP

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

public synchronized boolean enable(boolean quietMode) {
    enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
    // Enforce the user restriction for disallowing Bluetooth if it was set.
    if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) {
        debugLog("enable() called when Bluetooth was disallowed");
        return false;
    }
    debugLog("enable() - Enable called with quiet mode status =  " + quietMode);
    mQuietmode = quietMode;
    mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
    return true;
}
private class OffState extends BaseAdapterState {
    @Override
    int getStateValue() {
        return BluetoothAdapter.STATE_OFF;
    }
    @Override
    public boolean proceSSMessage(Message msg) {
        switch (msg.what) {
            case BLE_TURN_ON:
                transitionTo(mTurningBleOnState);
                break;
            default:
                infoLog("Unhandled message - " + messageString(msg.what));
                return false;
        }
        return true;
    }
}
private class TurningBleOnState extends BaseAdapterState {
    @Override
    int getStateValue() {
        return BluetoothAdapter.STATE_BLE_TURNING_ON;
    }
    @Override
    public void enter() {
        super.enter();
        sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
        mAdapterService.bringUpBle();
    }
    @Override
    public void exit() {
        removeMessages(BLE_START_TIMEOUT);
        super.exit();
    }
    @Override
    public boolean processMessage(Message msg) {
        switch (msg.what) {
            case BLE_STARTED:
                transitionTo(mBleOnState);
                break;
            case BLE_START_TIMEOUT:
                errorLog(messageString(msg.what));
                transitionTo(mTurningBleOffState);
                break;
            default:
                infoLog("Unhandled message - " + messageString(msg.what));
                return false;
        }
        return true;
    }
}

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

void bringUpBle() {
    debugLog("bleOnProcessStart()");
    if (getResources().getBoolean(
            R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) {
        Config.init(getApplicationContext());
    }
    mRemoteDevices.reset();
    mAdapterProperties.init(mRemoteDevices);
    debugLog("bleOnProcessStart() - Make Bond State Machine");
    mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
    mJniCallbacks.init(mBondStateMachine, mRemoteDevices);
    try {
        mBatteryStats.noteResetBleScan();
    } catch (RemoteException e) {
        Log.w(TAG, "RemoteException trying to send a reset to BatteryStats");
    }
    StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, -1, null,
            StatsLog.BLE_SCAN_STATE_CHANGED__STATE__RESET, false, false, false);
    //Start Gatt service
    setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
}

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java

private BondStateMachine(AdapterService service, AdapterProperties prop,
        RemoteDevices remoteDevices) {
    super("BondStateMachine:");
    addState(mStableState);
    addState(mPendinGCommandState);
    mRemoteDevices = remoteDevices;
    mAdapterService = service;
    mAdapterProperties = prop;
    mAdapter = BluetoothAdapter.getDefaultAdapter();
    setInitialState(mStableState);
}
private class StableState extends State {
    @Override
    public void enter() {
        infoLog("StableState(): Entering Off State");
    }
    @Override
    public boolean processMessage(Message msg) {
        BluetoothDevice dev = (BluetoothDevice) msg.obj;
        switch (msg.what) {
            case CREATE_BOND:
                OobData oobData = null;
                if (msg.getData() != null) {
                    oobData = msg.getData().getParcelable(OOBDATA);
                }
                createBond(dev, msg.arg1, oobData, true);
                break;
            case REMOVE_BOND:
                removeBond(dev, true);
                break;
            case BONDING_STATE_CHANGE:
                int newState = msg.arg1;
            
                if (newState == BluetoothDevice.BOND_BONDING) {
                    sendIntent(dev, newState, 0);
                    transitionTo(mPendingCommandState);
                } else if (newState == BluetoothDevice.BOND_NONE) {
                
                    sendIntent(dev, newState, 0);
                } else {
                    Log.e(TAG, "In stable state, received invalid newState: "
                            + state2str(newState));
                }
                break;
            case CANCEL_BOND:
            default:
                Log.e(TAG, "Received unhandled state: " + msg.what);
                return false;
        }
        return true;
    }
}

通过调用adapterService.enableNative()方法,开始调用JNI方法,进入C/C++层。adapterService.enableNative对应的cpp文件为
/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) {
  ALOGV("%s", __func__);
  if (!sBluetoothInterface) return JNI_FALSE;
  int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0);
  return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE
                                                             : JNI_FALSE;
}

通过调用“int ret = sBluetoothInterface->enable()”来驱动底层打开蓝牙开关。接下来就是C里面对打开蓝牙的实现。

4、蓝牙协议栈

/system/bt/btif/src/bluetooth.cc

static int enable(bool start_restricted) {
  LOG_INFO(LOG_TAG, "%s: start restricted = %d", __func__, start_restricted);
  restricted_mode = start_restricted;
  if (!interface_ready()) return BT_STATUS_NOT_READY;
  stack_manager_get_interface()->start_up_stack_async();
  return BT_STATUS_SUCCESS;
}

enable方法会调用start_up_stack_async方法,start_up_stack_async的实现在stack_manager.c 文件中:
/system/bt/btif/src/stack_manager.cc

static void start_up_stack_async(void) {
  thread_post(management_thread, event_start_up_stack, NULL);
}

通过thread_post异步event_start_up_stack,来启动蓝牙栈

static void event_start_up_stack(UNUSED_ATTR void* context) {
  if (stack_is_running) {
    LOG_INFO(LOG_TAG, "%s stack already brought up", __func__);
    return;
  }
  ensure_stack_is_initialized();
  LOG_INFO(LOG_TAG, "%s is bringing up the stack", __func__);
  future_t* local_hack_future = future_new();
  hack_future = local_hack_future;
  // Include this for now to put btif config into a shutdown-able state
  module_start_up(get_module(BTIF_CONFIG_MODULE));
  bte_main_enable();
  if (future_await(local_hack_future) != FUTURE_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s failed to start up the stack", __func__);
    stack_is_running = true;  // So stack shutdown actually happens
    event_shut_down_stack(NULL);
    return;
  }
  stack_is_running = true;
  LOG_INFO(LOG_TAG, "%s finished", __func__);
  btif_thread_post(event_signal_stack_up, NULL);
}

bte_main_enable()方法中进行btsnoop_module和hci_module的启动以及启动BTU操作。


作者:二十岁了还没有去过星巴克


--结束END--

本文标题: Android9.0 蓝牙开启流程

本文链接: https://www.lsjlt.com/news/29624.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android BLE蓝牙开发流程
    Android BLE蓝牙开发流程包括以下步骤:1. 检查设备是否支持BLE:使用`BluetoothAdapter`类的`getD...
    99+
    2023-09-20
    Android
  • windows10如何打开蓝牙作用windows10打开蓝牙操作流程
    蓝牙是一种无线通信技术,客户在电脑上打开蓝牙功能以后,就能完成材料的无线传输,那麼windows10如何打开蓝牙作用呢?操作步骤比较简单,你需要先打开设置控制面板,点击设备进到,在左边挑选蓝牙和其它机器设备,以后就能在右边页面中见到蓝牙,将...
    99+
    2023-07-13
  • win8蓝牙怎么开启
    这篇文章主要讲解了“win8蓝牙怎么开启”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“win8蓝牙怎么开启”吧!win8蓝牙开启:点击左下角开始,进入设置。 在出现的界面中选择更改电脑设置。...
    99+
    2023-07-01
  • Android蓝牙服务启动流程分析探索
    目录1、SystemServer2、BluetoothService3、BluetoothManagerService 首先我们要知道,主要系统服务都是在 SystemServer ...
    99+
    2023-01-18
    Android蓝牙服务启动 Android蓝牙服务 Android服务启动
  • android蓝牙开发的基本流程是什么
    Android蓝牙开发的基本流程如下:1. 检查设备是否支持蓝牙功能:使用BluetoothAdapter类的getDefaultA...
    99+
    2023-09-25
    android
  • 台式电脑蓝牙如何开启
    这篇文章主要介绍“台式电脑蓝牙如何开启”,在日常操作中,相信很多人在台式电脑蓝牙如何开启问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”台式电脑蓝牙如何开启”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!台式...
    99+
    2023-07-02
  • Win10怎么开启蓝牙支持服务
    要在Windows 10上开启蓝牙支持服务,请按照以下步骤操作:1. 打开“设置”。2. 点击“设备”。3. 在左侧面板中选择“蓝牙...
    99+
    2023-08-25
    Win10
  • Android Bluetooth(一)——蓝牙的开启和搜索
    Android Bluetooth(一)——蓝牙的开启和搜索 Android Bluetooth(一)——蓝牙的开启和搜索概览设置蓝牙蓝牙权限设置蓝牙 查找设备查询已配对设备发现设备启用...
    99+
    2023-09-04
    android 蓝牙 Bluetooth BLE
  • Win10如何开启蓝牙支持服务
    要在Windows 10上开启蓝牙支持服务,请按照以下步骤操作:1. 点击开始菜单并打开“设置”。2. 在设置窗口中,选择“设备”选...
    99+
    2023-08-25
    win10
  • Flutter:BLE蓝牙开发
    说明: 使用flutter_blue_plus插件实现低功耗蓝牙开发。 一、添加蓝牙权限: Android网络权限(工程/android/app/src/main/AndroidManifest.xml): iOS蓝牙权限(工程/ios/...
    99+
    2023-09-09
    flutter
  • Android蓝牙开发
    题引: 最近项目上涉及与硬件相关的功能,需要通过蓝牙进行消息收发。项目已完成,这里做下记录。 通信步骤: 初始化BluetoothAdapter.getDefaultAdapter()获取BluetoothAdapter对象 2.判断蓝牙是...
    99+
    2023-09-01
    java 开发语言
  • Win8.1系统蓝牙怎么开? win8.1怎么打开蓝牙
    今天有朋友问小编说不知道新装的Win8.1蓝牙怎么开,使用蓝牙的时候,就弹出这个窗口,但是蓝牙相关的服务已经开启。   以上是他的问题情况,小编 桌面上右键点击“计算机”,选&l...
    99+
    2023-06-02
    Win8.1系统 Win8.1蓝牙 win8.1 打开蓝牙 蓝牙 Win8.1 系统
  • Android蓝牙BLE开发
    最近正在研究Android的蓝牙BLE开发学习,以下是自己做的个人总结 1.1何为BLE? 首先得说明什么是低功耗蓝牙BLE,BLE的全称为Bluetooth low energy(或称Blooth ...
    99+
    2023-09-01
    android java
  • win7系统怎么连蓝牙鼠标win7联接蓝牙鼠标操作流程
    蓝牙鼠标相比有线电视鼠标而言实际操作会更方便,大伙儿无需受电极连接线的限定,所以很多消费者都需要应用它,那样win7系统怎么连蓝牙鼠标呢?实际操作比较简单,你先点击任务栏图标右下方的蓝牙标志,随后挑选添加设备,以后在开启控制面板中选定蓝牙鼠...
    99+
    2023-07-10
  • win10蓝牙开启选项没了怎么找回
    如果在Windows 10中无法找到蓝牙开启选项,请尝试以下解决方案:1. 检查是否已安装蓝牙驱动程序:右键单击“开始”按钮,选择“...
    99+
    2023-09-11
    win10
  • 基于蓝牙(HC-05)的安卓蓝牙 APP开发
    前言         ​​​​由于想做一个蓝牙小车,就随便找了点开发蓝牙app的资料教程。这边呢也是一个能快速弄一个app出来,比较简单。一小时之内可以弄好了。 一、开发网站                 这儿——>传送门 二、...
    99+
    2023-10-07
    iphone ios
  • 教你电脑系统win7蓝牙怎么开启
    想要在win7电脑系统上连接蓝牙耳机或者鼠标等设备使用的话,不仅需要安装相应的驱动,还要开启win7蓝牙功能服务。下面小编将为大家介绍如何在win7中开启蓝牙服务,以便帮助那些不清楚的网友。方法一:1、利用快捷键“Windows +R”打开...
    99+
    2023-07-17
  • win7蓝牙如何打开
    今天小编给大家分享一下win7蓝牙如何打开的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。win7蓝牙打开的方法:按下“win...
    99+
    2023-07-02
  • win7 蓝牙怎么打开
    我们都知道蓝牙是一个不需要连接wifi,也不需要消耗流量的传输工具,但是win7自带有这一功能的,又有多少人知道,说到这里,不禁有用户会问了,win7 蓝牙怎么打开呢我们都知道,要想使用蓝牙,就要先打开。下面,小编就给大家演示打开win7 ...
    99+
    2023-07-14
  • win11蓝牙如何打开
    这篇文章主要介绍“win11蓝牙如何打开”,在日常操作中,相信很多人在win11蓝牙如何打开问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”win11蓝牙如何打开”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作