Android 蓝牙BLE开发从官方源码demo开始(一)

1.前言

蓝牙在我们生活中扮演者许多重要的角色,蓝牙耳机、蓝牙音箱、蓝牙灯泡、蓝牙智能硬件等等!可见,蓝牙无处不在,而且也是物联网的基础纽带,它改变了我们的许多生活方式,给我们带来了许多益处。

前段时间我也简单地使用了小程序的蓝牙api操作,接下来我也要开始重新认识下Android蓝牙开发,蓝牙又分为经典蓝牙和BLE(低功耗蓝牙),这次我主要学习蓝牙BLE,所以我第一时间找了谷歌给我们提供了官方源码demo:

https://github.com/googlesamples/android-BluetoothLeGatt

2.权限

配置文件需要先声明蓝牙权限:

<!--蓝牙必须的权限-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

除了蓝牙权限外,还有如下权限是声明程序是否可用于支持BLE或者支持出BLE外的设备;如果required=true,则应用只能在支持BLE的Android设备上安装运行,不支持BLE的设备将finish。

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

此外还有一个很关键的问题,不知道你们在开发中有没有遇到过呢?官方demo没有适配到这里。Android6.0以上的手机仅仅是添加如上蓝牙权限是不行的,这将会造成无法扫描到其他设备,针对这问题,果断查了资料,需要添加位置权限;

<!--android6.0以上使用蓝牙需要的权限,否则在Android6.0以上的手机扫描不到蓝牙设备-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

在Android6.0以上 位置相关的权限属于运行时权限,所以代码同时也要请求一下 让用户确认,这个就不多说了。

3.是否支持蓝牙BLE

在前面的权限也说了如果required=true,则应用只能在支持BLE的Android设备上安装运行,不支持BLE的设备将finish;

如果想在java代码上实现上面的逻辑也是可以的,官方demo如下:

/**使用此检查确定设备是否支持BLE。 然后你可以有选择地禁用与BLE相关的功能。*/
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
   Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
   finish();
}

4.初始化蓝牙适配器

初始化蓝牙适配器。 对于API级别18及更高级别,请通过BluetoothManager获取对BluetoothAdapter的引用。最后这里记得要判空!

        // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
        // BluetoothAdapter through BluetoothManager.
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
 
        // Checks if Bluetooth is supported on the device.
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

5.当前设备是否已开启蓝牙

要想操作蓝牙,必须确保在设备上启用蓝牙。如果当前未启用蓝牙,因此我们可以触发Intent调用系统显示一个对话框,要求用户授予启用蓝牙的权限。

       if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }

6.初始化listview列表适配器

这里目的就是将扫描到的蓝牙设备显示到listview列表上,然后用户就可以点击对应的item,程序就可以进行下一步操作。这一步骤可根据需要定制。

7.扫描

官方demo的扫描方法如下,如果要扫描的话就要传入true执行scanLeDvice(true)方法,然后蓝牙适配器就调用startLeScan()方法进行扫描,mLeScanCallback是扫描回调,下面会说到;执行扫描的同时开启了一个延时操作,时间到了就调用stopLeScan()方法停止扫描。

我觉得这里设置了一个延时停止扫描操作是非常友好的,因为扫描非常耗资源。

       private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    invalidateOptionsMenu();
                }
            }, SCAN_PERIOD);
 
            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
        invalidateOptionsMenu();
    }
 

接下来就看看扫描的Callback回调吧,这个回调里面有个onLeScan方法,蓝牙扫描成功后的结果会返回此方法中,然后就可以处理BluetoothDevice拿到设备信息 最后展示到前面初始化的listview列表中,大概流程就是这样。

      // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
 
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mLeDeviceListAdapter.addDevice(device);
                    mLeDeviceListAdapter.notifyDataSetChanged();
                }
            });
        }
    };

接着再看看这个onLeScan方法中的值吧!

第一个参数device,表示一个远程蓝牙设备,里面有它独有的蓝牙地址Address和Name等,所以后续需要进行连接蓝牙操作也需要用到这里获取的蓝牙Address;

第二个参数rssi表示扫描到的设备信号强度,这里应该可以用来判断距离的远近。

第三个参数scanRecord表示远程设备提供的广告记录的内容。

至此已经完成初始化配置、一些设备的判断逻辑和扫描操作了,如果能成功地扫描到设备并展示到界面上的话,下一步如果用户点击了列表,将进行蓝牙连接和相关的读写操作!

所以下一篇文章不出意外的话,就是继续学习Android蓝牙的连接和读写操作。
Android 蓝牙BLE开发从官方源码demo开始(二)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容