Android之开发BLE 详细步骤(有源码提供)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

Android之开发BLE (有源码提供)#

开发之前我们必须知道蓝牙广播常量所代表的含义:

参考文档

  • String ACTION_ACL_CONNECTED=“android.bluetooth.device.action.ACL_CONNECTED” 与远程设备建立连接(低级别)

  • String ACTION_ACL_DISCONNECTED= "android.bluetooth.device.action.ACL_DISCONNECTED"与远程设备断开连接(低级别)

  • String ACTION_ACL_DISCONNECT_REQUESTED="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"设备提出断开连接请求,即将断开连接

  • String ACTION_BOND_STATE_CHANGED= "android.bluetooth.device.action.BOND_STATE_CHANGED"远程设备连接状态发生改变

  • String ACTION_CLASS_CHANGED=“android.bluetooth.device.action.CLASS_CHANGED” 远程设备被改变

  • String ACTION_FOUND=“android.bluetooth.device.action.FOUND” 发现一个远程设备

  • String ACTION_NAME_CHANGED=“android.bluetooth.device.action.NAME_CHANGED” 远程设备名字发送改变或者第一次发现远程蓝牙设备的名称

  • String ACTION_PAIRING_REQUEST=“android.bluetooth.device.action.PAIRING_REQUEST” 广播配对请求

  • String ACTION_UUID=“android.bluetooth.device.action.UUID” 远程设备取回UUID广播

  • String ACTION_BOND_STATE_CHANGED = “android.bluetooth.device.action.BOND_STATE_CHANGED”; 获取配对状态
    int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); //当前的配对的状态
    int state = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.BOND_NONE); //前一次的配对状态
    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //配对的设备信息

    • 已配对:int BOND_BONDED =12;
    • 配对中:int BOND_BONDING=11;
    • 配对未成功:int BOND_NONE =10;
  • String ACTION_CONNECTION_STATE_CHANGED = “android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED”; 配对后的连接状态
    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.ERROR); //当前的连接状态
    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, BluetoothAdapter.ERROR); //前一次的连接状态
    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //连接的设备信息

    • 未连接 int STATE_DISCONNECTED = 0;
    • 连接中 int STATE_CONNECTING = 1;
    • 连接成功 int STATE_CONNECTED = 2;
  • 蓝牙类型常量:

    • 传统蓝牙:int DEVICE_TYPE_CLASSIC = 1;
    • 低功耗蓝牙(BLE):int DEVICE_TYPE_LE= 2;
    • 双模蓝牙:int DEVICE_TYPE_DUAL = 3;
    • 未知蓝牙:int DEVICE_TYPE_UNKNOWN =0;
  • 本地蓝牙开关状态广播: String ACTION_STATE_CHANGED = “android.bluetooth.adapter.action.STATE_CHANGED”
    得到状态值: int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.STATE_OFF);

    • 蓝牙关闭 int STATE_OFF = 10;
    • 蓝牙打开 int STATE_ON = 12;
    • 蓝牙正在关闭 STATE_TURNING_OFF = 13;
    • 蓝牙正在打开 int STATE_TURNING_ON = 11;
  • String DISCOVERY_START = BluetoothAdapter.ACTION_DISCOVERY_STARTED; //开始搜索

  • String END_FIND_DEVICE = BluetoothAdapter.ACTION_DISCOVERY_FINISHED; //搜索结束

  • String FIND_DEVICE = BluetoothDevice.ACTION_FOUND; //搜索到设备

  • String PAIRING_REQUEST = BluetoothDevice.ACTION_PAIRING_REQUEST; //请求配对

开发流程

(额,CSDN太low了,图居然没有了。。。。不对不住大家!)
[外链图片转存失败(img-s7hYQ8J3-1568960081939)(http://i.imgur.com/SJoOMpm.png)]

开发步骤详解

第一步:在Manifests文件中注册权限

<!--需要硬件支持低功耗蓝牙-->
<uses-feature android:name"android.permission.BLUETOOTH_ADMIN"/>
<!--蓝牙权限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!--Android 5.0以上蓝牙好需要位置权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="andriod.permission.ACCESS_FINE_LOCATION"/>
<!--android 10权限 并动态申请-->
 <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

第二步打开蓝牙

  /**
   * 检查BLE是否起作用
   */
   private void checkBLEFeature() {
	//判断是否支持蓝牙4.0
	if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
		Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
			finish();
	}
	//获取蓝牙适配器
	final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
	mBluetoothAdapter = bluetoothManager.getAdapter();
	//判断是否支持蓝牙
	if (mBluetoothAdapter == null) {
              //不支持
		Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
		finish();
		return;
	}else
	      //打开蓝牙
	if (!mBluetoothAdapter.isEnabled()) {//判断是否已经打开
		Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
		startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
          }
      
   }

第三步:扫描BEL设备

    //扫描BLE设备
    private void scanLeDevice(final boolean enable) {
        if (enable) {
            if (mBluetoothAdapter.isEnabled()) {
                if (mScanning)
                    return;
                mScanning = true;
                mLeDeviceListAdapter.clear();
                mHandler.postDelayed(mScanRunnable, 5000);//五秒后关闭扫描
                mBluetoothAdapter.startLeScan(mLeScanCallback);
            } else {
                ToastUtil.showMsg(getActivity(), R.string.scan_bt_disabled);
            }
        } else {
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
            mRefreshLayout.setRefreshing(false);
            mHandler.removeCallbacks(mScanRunnable);
            mScanning = false;
        }
    }
   //关闭扫描
    private final Runnable mScanRunnable = new Runnable() {

        @Override
        public void run() {
            scanLeDevice(false);
        }
    };

第四步:查看扫描后的回调

private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        /**
         * 简单说一下这三个参数的含义:
         * @param device:识别的远程设备
         * @param rssi:  RSSI的值作为对远程蓝牙设备的报告; 0代表没有蓝牙设备;
         * @param scanRecord:远程设备提供的配对号(公告)
         */
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //保存到本地:用来展示扫描得到的内容
                    mLeDeviceListAdapter
                            .addDevice(new LeDevice(device.getName(), device.getAddress(), rssi, scanRecord));
                    mLeDeviceListAdapter.notifyDataSetChanged();
                }
            });
        }
    };

第五步:连接设备
BluetoothGatt常规用到的几个操作示例:
* connect() :连接远程设备。
* discoverServices() : 搜索连接设备所支持的service。
* disconnect():断开与远程设备的GATT连接。
* close():关闭GATTClient端。
* readCharacteristic(characteristic) :读取指定的characteristic。
* setCharacteristicNotification(characteristic, enabled):设置当指定characteristic值变化时,发出通知。
* getServices() :获取远程设备所支持的services。

//获取BluetoothDevice对象后调用coonnectGatt()进行连接
   mBluetoothDevice.connectGatt(context,false,mGattCallbask);//第一个参数:上下文,第二个参数:断开连接是否重连,第三个
  //mBluetoothGatt.discoverServices();//此步骤根据业务需求添加
参数连接状态回调。
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
      //连接状态改变的回调
      @Override
      public void onConnectionStateChange(BluetoothGatt gatt, int status,
              int newState) {
          if (newState == BluetoothProfile.STATE_CONNECTED) {
              // 连接成功后启动服务发现
              Log.e("AAAAAAAA", "启动服务发现:" + mBluetoothGatt.discoverServices());
          }
      };

      //发现服务的回调
      public void onServicesDiscovered(BluetoothGatt gatt, int status) {
          if (status == BluetoothGatt.GATT_SUCCESS) {                                   
               Log.e(TAG, "成功发现服务");
                         }else{
                 Log.e(TAG, "服务发现失败,错误码为:" + status);
                      }
      };
               
      //写操作的回调
      public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
          if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.e(TAG, "写入成功" +characteristic.getValue());
                     }
             };
        
     //读操作的回调
     public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
          if (status == BluetoothGatt.GATT_SUCCESS) {
                  Log.e(TAG, "读取成功" +characteristic.getValue());
                  }
              }
              
    //数据返回的回调(此处接收BLE设备返回数据)
    public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
              };
          };
    }

第六步:发送数据()回调也是BluetoothGattCallback

  • 读操作,读操作比较简单,只需将相应的特征值传入即可得到该特征值下的数据,如下代码:
     mBluetoothGatt.readCharacteristic(characteristic);
     读取的结果通过onCharacteristicRead回调返回:(通过characteristic.getValue()就可以得到读取到的值了)
     // 读操作的回调
         public void onCharacteristicRead(BluetoothGatt gatt,
                 BluetoothGattCharacteristic characteristic, int status) {
             if (status == BluetoothGatt.GATT_SUCCESS) {
                 Log.e(TAG, "读取成功" +characteristic.getValue());
             }
         }
    
    • 写操作,写操作是我们的重点,我们可以通过向characteristic写入指令(发送指令)以此来达到控制BLE终端设备的目的:
      mBluetoothGatt.setCharacteristicNotification(characteristic,true)//设置该特征具有Notification功能
     //将指令放置进特征中
     characteristic.setValue(new byte[] {数据});
     //设置回复形式
     characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
     //开始写数据
     mBluetoothGatt.writeCharacteristic(chharacteristic);
    
  • 注:
    BLE传输过程每次最大只能传输20个字节,所以如果发送的指令大于20字节的话要分包发送,例如现在要发送28个字节的,可以先write(前20个字节),开启线程sleep(几十毫秒)后在write(后面8个字节)。
    第七步:关闭蓝牙
BluetoothAdapter. disable();//关闭蓝牙

题外话:谢谢大家观看,有不足之处欢迎大家一起讨论;码字不易,大家喜欢,麻烦点赞哦。


灵魂三问:

  • 有没有觉得技术得不到系统的提升,技术成长慢?
  • 有没面试懵逼,升职加薪难?
  • 有没有想过去大一点的世界看看?

有期望JAVA技术巩固的、Android知识进阶的、期望升职加薪的、Android面试技巧的大厂面试真题的;大家可以加我QQ哦:1070800492。我们一起学习,一起进步!

重要的事情说三遍:

  • 学习、挣钱、自由
  • 学习、挣钱、自由
  • 学习、挣钱、自由

疫情当下,唯有自强

Android蓝牙设备的状态值管理 Android6.0(API 23)开始,Google引入了新的权限模型,要求应用程序在使用蓝牙功能时请求相应的权限,并且用户必须在运行时明确授权。在Android中,蓝牙状态可以通过多种方式来描述,主要包括蓝牙适配器状态、蓝牙设备连接状态以及蓝牙广播状态 阅读详情

相关推荐

Android蓝牙2.0开发

因项目需要,做一个与2.0蓝牙模块连接的Demo,在此记录一下 1.先注册个广播,来接收一下蓝牙的状态 MyBroadCastRevciver broadcastReceiver = null; public void registerBroadcast(){ broadcastReceiver = new MyBroadCastRevciver(); IntentFilte...

zhao_Android的博客 902

Android BLE蓝牙例子(包括android版Lightblue)实例源码.zip

Android BLE蓝牙例子(包括android版Lightblue)实例源码: 源码里面有Bluetooth4_3/BLEDemo/Android_Lightblue.apk三个.前两个是BLE的demo。BLEDemo这个功能较Bluetooth4_3多一些,有兴趣的可以都看下。Android_Lightblue.apk是Android版的lightblue,在进行ble开发的时候用该app作为辅助工具还是非常不错的,功能较Bluetooth4_3 BLEDemo 这两个demo都强大。不过Android_Lightblue.apk在android5.0以上的版本手机上运行不起来,我也没有该app的源码

Android BLE开发详解和FastBle源码解析

蓝牙是一种近距离无线通信技术。它的特性就是近距离通信,典型距离是 10 米以内,传输速度最高可达 24 Mbps,支持多连接,安全性高,非常适合用智能设备上。

2401_84414763的博客 851

监听蓝牙连接的状态

之前写的是监听蓝牙是否打开。这篇文章简单的介绍蓝牙的连接状态监听。忘记是哪位博主写的了。本人简单的整理下。代码其实就一个工具类而已: package com.tools; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Cont...

湖言的博客 4065

android蓝牙ACL连接,Android BLE ACTION_ACL_CONNECTED未调用配对设备

我使用的是Android 4.4 . 我有2个蓝牙设备,一个老式蓝牙和一个BLE . 就它们传输的数据而言,它们在功能上是相同的 . 它们都有一个按钮,可以在按下时连接和传输数据 .我有蓝牙权限并在我的清单中注册了BroadcastReceiver,就像这样......android:name=".BluetoothBroadcastReceiver">为了测试,我只是在BroadcastR...

weixin_26985923的博客 2466

Android BLE 源码简介

Android BLE 源码简介 去发现同类优质开源项目:https://gitcode.com/ 此仓库提供了一份Android BLE蓝牙低功耗)APP源码,该源码在网上收集,经过实际应用测试,有效解决了安卓手机在连接BLE设备时遇到的连接困难或无法连接的问题。相较于安卓BLE调试助手,此源码在连接稳定性和易用性上均有优势。 该源码适用于开发者快速搭建BLE应用框架,或者进行相关功能的学习与...

gitblog_06749的博客 434

蓝牙4.0开发揭秘:IoT-Firstep安卓BLE通信协议实现与源码分析

IoT-Firstep是一个物联网开发的入门教程项目,涵盖了单片机、上位机、移动应用和服务器后台开发等知识,其中蓝牙4.0技术的应用实例是重要组成部分。本文将深入剖析该项目中安卓BLE通信协议的实现原理与源码结构,为新手开发提供清晰的学习路径。 ## 一、蓝牙4.0技术基础与项目架构 蓝牙4.0(BLE)以低功耗、低成本和快速连接的特性,成为物联网设备通信的理想选择。在IoT-Firstep

gitblog_00212的博客 691

BLE_SPP 安卓手机蓝牙串口助手源码

BLE_SPP 安卓手机蓝牙串口助手源码 去发现同类优质开源项目:https://gitcode.com/ 此仓库提供BLE_SPP安卓手机蓝牙串口助手的完整源码,经过实际测试,功能完整且可用。本源码适用于Android Studio开发环境,方便开发者进行二次开发与学习。 简介 BLE_SPP是一款基于Android系统的手机蓝牙串口助手应用,支持低功耗蓝牙BLE)通信。该源码包含了完整的A...

gitblog_06728的博客 460

BLE_SPP安卓手机蓝牙串口助手源码:连接世界的桥梁

BLE_SPP安卓手机蓝牙串口助手源码:连接世界的桥梁 去发现同类优质开源项目:https://gitcode.com/ 在物联网和智能家居迅速发展的今天,蓝牙技术已成为连接各类设备的重要手段。本文将为您介绍一款功能强大的开源项目——BLE_SPP安卓手机蓝牙串口助手源码,助您轻松实现设备间的无线通信。 项目介绍 BLE_SPP安卓手机蓝牙串口助手源码是一款基于Android系统的应用,专为低功耗...

gitblog_06789的博客 1111

Android蓝牙开发BLE通讯Demo

[源码地址](https://github.com/ansen360/CodeRepository/tree/master/app/src/main/java/com/code/bluetooth)

你只是看起很努力 7267

AndroidBLE蓝牙例子实例源码Android平台BLE开发利器

AndroidBLE蓝牙例子实例源码Android平台BLE开发利器 【下载地址】AndroidBLE蓝牙例子实例源码 探索Android BLE蓝牙开发的绝佳起点!本开源项目提供了两个详尽的BLE示例源码,`Bluetooth4_3`为基础入门,而`BLEDemo`则功能更为丰富,助力开发者深入理解BLE技术。此外,...

gitblog_06734的博客 677

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

1.前言 蓝牙在我们生活中扮演者许多重要的角色,蓝牙耳机、蓝牙音箱、蓝牙灯泡、蓝牙智能硬件等等!可见,蓝牙无处不在,而且也是物联网的基础纽带,它改变了我们的许多生活方式,给我们带来了许多益处。 前段时间我也简单地使用了小程序的蓝牙api操作,接下来我也要开始重新认识下Android蓝牙开发蓝牙又分为经典蓝牙BLE(低功耗蓝牙),这次我主要学习蓝牙BLE,所以我第一时间找了谷歌给我们提供了官...

ChessLuo 8790

android 5.0 ble demo,Android BLE蓝牙例子(包括android版Lightblue)实例源码

【实例简介】源码里面有Bluetooth4_3/BLEDemo/Android_Lightblue.apk三个.前两个是BLE的demo。BLEDemo这个功能较Bluetooth4_3多一些,有兴趣的可以都看下。Android_Lightblue.apk是Android版的lightblue,在进行ble开发的时候用该app作为辅助工具还是非常不错的,功能较Bluetooth4_3 BLEDem...

weixin_30472793的博客 1558

Android BLE4.+ 蓝牙开发国产手机兼容性解决方案

算是做了n年的智能穿戴BLE开发了, 首先对国内的安卓开发者提醒下 , BLE开发是真的很坑, 特别是安卓, ios端也坑, 但没安卓坑 因为国产有很多手机 各种奇葩兼容都有, 其实这些方案我很早就写到云笔记里了,一直没公开, 这里的解决方案大部分都是网上搜不到 或者网上搜到类似的问题, 但回复基本上是回答[无法解决] 或 [重启手机解决]等 没意义的解决办法,让我很无语… 以下内...

没错, 我是东芝 1万+

android(安卓)蓝牙框架 bluetooth ble蓝牙低功耗

FastBle-github: star 3.9k Android BLE开发详解和FastBle源码解析

baidu_40537062的博客 448

深入解析Android-nRF-Toolbox源码:构建BLE设备

蓝牙低功耗(Bluetooth Low Energy, BLE)技术是一种为了实现低功耗通信而特别设计的蓝牙技术版本。相较于传统蓝牙技术,它在保证了数据传输可靠性的同时,大幅降低了设备的能耗。nRF Toolbox是由Nordic Semiconductor开发的一款多功能工具箱应用,适用于基于其nRF5x芯片系列的BLE产品。该工具箱的主要功能包括但不限于:蓝牙设备的扫描、连接和数据交换。用于测量、记录和显示环境数据的传感器工具。用于测试和调试BLE应用和服务的工具。

weixin_30205153的博客 797

Android-BLE源码架构深度剖析:设计模式在蓝牙框架中的应用

Android-BLE是一个功能强大的蓝牙低功耗(BLE)框架,提供了完整的蓝牙操作接口和优化的连接管理机制。本文将深入解析其源码架构,揭示设计模式在蓝牙框架中的精妙应用。 ## 🚀 框架核心架构概览 Android-BLE框架采用分层设计,核心代码位于[core/src/main/java/cn/com/heaton/blelibrary/ble/](https://link.gitcod

gitblog_00255的博客 1091

Android BLE(3) ---FastBle解析

Android BLE开发详解和FastBle源码解析    项目中有用到了蓝牙相关的功能,所以之前也断断续续地针对蓝牙通信尤其是BLE通信进行了一番探索,整理出了一个开源框架FastBle与各位分享经验。 源码地址: https://github.com/Jasonchenlijian/FastBle 随着对FastBle框架关注的人越来越多,与我讨论问题的小伙伴也多起来,所以整理了一...

zhangbijun1230的专栏 3176
下一篇: FragmentTabHost+FrameLayout
我是昆虫
博客等级 码龄10年 14粉丝 23原创
评论 16
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值