上一篇《Android 6.0 Settings源码简单分析之蓝牙(1)》我们只是简单的介绍了蓝牙的界面和流程的启动,讲得比较粗糙,这次我们继续深入讨论蓝牙,设计Framework的代码

源码:Android 6.0

应用:Settings 和 Framework(权且看做一个应用吧^_^)

目录:

Settings\src\com\android\settings\bluetooth

base\packages\settingslib\src\com\android\settingslib\bluetooth

base\services\core\java\com\android\server

 

好了,原归正传,下面由我细细道来。

由上一篇(如上)知道,虽然Settings中蓝牙入口类是BluetoothSettings.java,但其没有重写onCreate()方法,因此先执行了其父类DeviceListPreferenceFragment.java,因此开始从其父类开始从头讲起。

1、DeviceListPreferenceFragment.onCreate()

   //DeviceListPreferenceFragment.java 【Settings】
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        2、蓝牙管理类的初始化
        mLocalManager = Utils.getLocalBtManager(getActivity());
        if (mLocalManager == null) {
            Log.e(TAG, "Bluetooth is not supported on this device");
            return;
        }
        获取LocalAdapter,这个在蓝牙管理类初始化时就初始化了
        mLocalAdapter = mLocalManager.getBluetoothAdapter();
        ......
    }

2、蓝牙管理类的初始化

mLocalManager = Utils.getLocalBtManager(getActivity());

蓝牙管理类的初始化,这里封装起来了,因为后续很多地方都在调用这个方法。

    //Utils.java  【Settings】
    public static LocalBluetoothManager getLocalBtManager(Context context) {
               LocalBluetoothManager初始化
        return LocalBluetoothManager.getInstance(context, mOnInitCallback);
    }

LocalBluetoothManager使用了懒汉单例模式,加了synchronized表示线程安全,一次只能一个访问。

    //LocalBluetoothManager.java 【Framework】
     public static synchronized LocalBluetoothManager getInstance(Context context,
            BluetoothManagerCallback onInitCallback) {
         非null判断,第一次调用时走这里
        if (sInstance == null) {
            2.1 LocalBluetoothAdapter的初始化
            LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
            if (adapter == null) {
                return null;
            }
            // This will be around as long as this process is
            Context appContext = context.getApplicationContext();
            sInstance = new LocalBluetoothManager(adapter, appContext);
            if (onInitCallback != null) {
                onInitCallback.onBluetoothManagerInitialized(appContext, sInstance);
            }
        }

        return sInstance;
    }

    private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
        mContext = context;
        mLocalAdapter = adapter;

        mCachedDeviceManager = new CachedBluetoothDeviceManager(context, this);
        mEventManager = new BluetoothEventManager(mLocalAdapter,
                mCachedDeviceManager, context);
        mProfileManager = new LocalBluetoothProfileManager(context,
                mLocalAdapter, mCachedDeviceManager, mEventManager);
    }
2.1 、LocalBluetoothAdapter的初始化

也是用了懒汉单例模式

    //LocalBluetoothAdapter.java 【Framework】
     static synchronized LocalBluetoothAdapter getInstance() {
        懒汉模式
        if (sInstance == null) {
            2.2、BluetoothAdapter通过getDefaultAdapter初始化
            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
            if (adapter != null) {
                sInstance = new LocalBluetoothAdapter(adapter);
            }
        }
        return sInstance;
    }

    private LocalBluetoothAdapter(BluetoothAdapter adapter) {
        mAdapter = adapter;
    }
2.2、BluetoothAdapter通过getDefaultAdapter初始化

Android代码中有注释,默认提供一种蓝牙适配器,但是API可以支持多种。(直接看英文吧)

 Get a handle to the default local Bluetooth adapter.Currently Android only supports one Bluetooth adapter, but the API could be extended to support more. This will always return the default adapter.

如果getDefaultAdapter()返回是null,表示当前设备不支持蓝牙。

    public static synchronized BluetoothAdapter getDefaultAdapter() {
        if (sAdapter == null) {
            【返回蓝牙服务的引用】
            IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
            if (b != null) {
                【获取BluetoothManagerService】
                IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
                sAdapter = new BluetoothAdapter(managerService);
            } else {
                Log.e(TAG, "Bluetooth binder is null");
            }
        }
        return sAdapter;
    }

BluetoothAdapter初始化

    BluetoothAdapter(IBluetoothManager managerService) {
        【判读蓝牙服务是否启动,如果没有就抛异常】
        if (managerService == null) {
            throw new IllegalArgumentException("bluetooth manager service is null");
        }
        try {
           【注册adapter,mManagerCallback】
            mService = managerService.registerAdapter(mManagerCallback);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        mManagerService = managerService;
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
        mToken = new Binder();
    }

3、

 

【没有完成。。。 [尴尬]。。。还是先放出来了 】

 历史上的今天

  1. 2024: android13添加SELinux权限时踩的坑(0条评论)
  2. 2024: Android 13framework中添加AIDL(1条评论)
  3. 2021: MediaPlayer异常(0条评论)
  4. 2020: 顾城:树枝的疏忽(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

《MySQL基础教程》笔记1

前言学习一下MySQL,之前一直没有系统的学习一下。最近有空,看了《MySQL基础教程-西泽梦路》,简单的做一下笔记。记录于此,方便自己回忆。正文我这以Window版的phpstudy软件验证。需要进入这个目录,才可以使用mysql命令D:\phpstudy_pro\Extension...

[摘]Android音频焦点处理

概要Android系统允许多个应用同时播放音频,这种特性有利有弊。例如当我们正在听音乐的时候突然点开了一个视频,如果我们发现音乐的声音和视频的的声音混合了在一起,这显然让我们非常不爽。而如果我们在播放音乐的时候,突然来了一条信息,这个时候,我们既希望能听到短信的提示音,又不希望音乐此刻停止,而是...

常用的简单monkey测试命令集合

前言Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行测试。Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法。正文下面整理了一下黑名单和白名单...

张爱玲:花落的声音

家中养了玫瑰,没过多少天,就在夜深人静的时候,听到了花落的声音。起先是试探性的一声“啪”,像一滴雨打在桌面。紧接着,纷至沓来的“啪啪”声中,无数中弹的蝴蝶纷纷从高空跌落下来。那一刻的夜真静啊,静得听自己的呼吸犹如倾听涨落的潮汐。整个人都被花落的声音吊在半空,尖着耳朵,听得心里一惊一惊的,像听一个正...

byte数组以十六进制字符串打印简介

前言在协议开发中,需要把byte数组格式化到日志中,方便查看收发的报文,比较常用的就是把byte数组格式化成十六制作的字符串。下面记录一下格式数据的方法,方便自己查阅。正文下面有常用的两种,效果都一样,个人比较喜欢第二种。隐藏内容!付费阅读后才能查看!¥1 ¥3多个隐藏块只需支付一次付费...

Fragment的简单使用

多用几次就熟悉了。以防止忘记,因此附上代码于此。(图片来自Android官网)零、Fragment的生命周期一、布局<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" x...