前段时间由于项目需要,针对部分热敏蓝牙打印机做了开发,本来刚开始是要用佳博的,结果开发完了说要换成汉印的打印机(此时内心一万只草泥马奔腾而过)。好了,言归正传。既然是蓝牙打印机,那么首先要做的就是进行蓝牙开发。先贴一个别人推荐的一个开源库:https://github.com/Jasonchenlijian/FastBle  话说在15年的时候有接触过原生的蓝牙开发,但是那时候并没有运用到项目中,当时给我的一个感觉就是再也不要做这个玩意儿了。没想到从今年(2019年)开始,一直在做这方面的项目,为了养家糊口只能硬着头皮上了。各种Google各种百度,最后还是没搞明白,那就放弃吧(怎么阔能,我是那么容易放弃的人吗(●'◡'●))。最后还是得感谢老天眷顾,我朋友他们也都在做这个,那就一起约个饭出来聊波技术咯~

其实对于蓝牙开发,最难的不是网上能找到的那些东西,它的一个关键点就是它需要的那几个UUID怎么获取?从何而来?同样这也是困惑我良久的一个问题。(serviceUuid、 writeCharactUuid 、 notifyCharactUuid 这三个)。我问了好多人他们都说不知道,实际上这个应该是厂家那边应该提供过来的,但是厂家不是技术,他们根本都不知道这是什么玩意儿,好吧 ,我跪了。那是不是真的没有办法了?并不是,虽然我的办法有点不太靠谱,但是对于菜的要死又无知的自己来说,当然要抱着试一试的态度咯。

连接成功后拿到UUID集合然后进行遍历,将遍历得到的这些UUID一个一个赋值去试,终于皇天不负有心人,守得云开见月明,成功啦。o(* ̄▽ ̄*)ブ(PS:这么长时间的头发总算没有白掉)。

下面介绍一下完整步骤。

首先,清单文件中给权限(6.0以上一定要加定位权限):


<!-- 使用蓝牙的权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 扫描蓝牙设备或者操作蓝牙设置 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!--模糊定位权限,仅作用于6.0+-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--精准定位权限,仅作用于6.0+-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

还有要添加

 <uses-featureandroid:name="android.hardware.bluetooth_le"android:required="true" /><service android:name="com.inuker.bluetooth.library.BluetoothService" />

然后就根据之前贴出的开源库进行开发就好了,我在这里贴一个工具类:

public class BleUtil {private static final String TAG = "BleUtil-->";private static BleUtil bleUtil;public List<BleDevice> bleDevices;private OnBleListener listener;private String uuid_service = "自己获取的";//接受数据特征UUIDprivate String uuid_characteristic_receive = "自己获取的";//发送数据特征UUID(视情况而定,本人不需要发送数据功能)
//    private String uuid_characteristic_send = "自己获取的";private boolean isStandByBle;private boolean isEnableBle;private Context context;private Handler handler = new Handler(Looper.getMainLooper());private final int START_SCAN = 100;private final int RESET_CONNECT = 101;
//    private final UUID[] serviceUuids;private BleDevice connectedBleDevice;private BleScanRunnable bleScanRunnable;private BleResetConnectRunnable bleConnectRunnable;private BleManager bleManager;private BleConnectedRunnable bleConnectedRunnable;private boolean isResetConnect = false;private boolean isScaning;private final ReturnTimeOutRunnable returnTimeOutRunnable;private String currentData = "";private final ReceiveDataRunnable receiveDataRunnable;private BleUtil(Context context) {this.context = context.getApplicationContext();bleManager = BleManager.getInstance();isStandByBle = bleManager.isSupportBle();isEnableBle = bleManager.isBlueEnable();
//        //根据指定的UUID扫描特定的设备
//        UUID serviceUuid = UUID.fromString(uuid_service);
//        serviceUuids = new UUID[]{serviceUuid};bleScanRunnable = new BleScanRunnable();bleConnectRunnable = new BleResetConnectRunnable();bleConnectedRunnable = new BleConnectedRunnable();returnTimeOutRunnable = new ReturnTimeOutRunnable();receiveDataRunnable = new ReceiveDataRunnable();}public static BleUtil getInstance(Context context) {if (bleUtil == null) {synchronized (BleUtil.class) {if (bleUtil == null) {bleUtil = new BleUtil(context);}}}return bleUtil;}public void startBle() {if (!isStandByBle) {Toast.makeText(context, "该设备不支持蓝牙功能", Toast.LENGTH_SHORT).show();return;}bleDevices = new ArrayList<>();BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
//                .setServiceUuids(serviceUuids)
//                .setAutoConnect(true)
//                .setDeviceMac("连接到的蓝牙MAC地址").setScanTimeOut(15000).build();bleManager.initScanRule(scanRuleConfig);if (!bleManager.isBlueEnable()) {bleManager.enableBluetooth();}handler.postDelayed(bleScanRunnable, 2 * 100);}private void startScan() {if (isResetConnect && listener != null) {listener.onResetConnect();isResetConnect = false;}bleManager.scan(new BleScanCallback() {@Overridepublic void onScanFinished(List<BleDevice> list) {isScaning = false;}@Overridepublic void onScanStarted(boolean b) {isScaning = true;}@Overridepublic void onScanning(BleDevice bleDevice) {Log.e(TAG, bleDevice.getName() + "        " + bleDevice.getMac());bleDevices.add(bleDevice);if (listener != null) {listener.onScaningBle(bleDevice);}}});}
//停止扫描public void stopScan() {if (isScaning)bleManager.cancelScan();}
//断开连接public void disConnect() {handler.removeCallbacks(bleScanRunnable);handler.removeCallbacks(bleConnectedRunnable);handler.removeCallbacks(bleConnectRunnable);handler.removeCallbacks(returnTimeOutRunnable);handler.removeCallbacks(receiveDataRunnable);if (connectedBleDevice != null && bleManager.isConnected(connectedBleDevice)) {stopIndicate();bleManager.clearCharacterCallback(connectedBleDevice);bleManager.disconnect(connectedBleDevice);}}
//判断是否连接public boolean isConnected() {if (connectedBleDevice == null) {return false;} else {return bleManager.isConnected(connectedBleDevice);}}@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)public void connectBle(BleDevice bleDevice) {stopScan();bleManager.connect(bleDevice, new BleGattCallback() {@Overridepublic void onStartConnect() {}@Overridepublic void onConnectFail(BleDevice bleDevice, BleException e) {//连接失败,需做好重连措施connectedBleDevice = bleDevice;handler.postDelayed(bleConnectRunnable, 200);Log.e("连接失败:", e.toString());}@Overridepublic void onConnectSuccess(BleDevice bleDevice, BluetoothGatt bluetoothGatt, int i) {Log.e(TAG, "连接成功");receiveData(bleDevice);connectedBleDevice = bleDevice;handler.postDelayed(bleConnectedRunnable, 200);//设备的服务信息及特征信息
//                List<BluetoothGattService> serviceList = bluetoothGatt.getServices();
//                for (BluetoothGattService service : serviceList) {
//                    UUID uuid_service = service.getUuid();
//                    Log.e(TAG, "onConnectSuccess:service---- " + uuid_service);
//                    List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
//                    for (BluetoothGattCharacteristic characteristic : characteristicList) {
//                        UUID uuid_chara = characteristic.getUuid();
//                        Log.e(TAG, "onConnectSuccess: chara" + uuid_chara);
//                    }
//                }}@Overridepublic void onDisConnected(boolean b, BleDevice bleDevice, BluetoothGatt bluetoothGatt, int i) {//连接断开,需区分异常断开与主动断开(b=true),异常断开的重连操作,需做好时间间隔操作,否者可能导致长时间连接不上的情况if (b) {Log.e(TAG, "正常断开");bleManager.clearCharacterCallback(bleDevice);bluetoothGatt.connect();bleManager.clearCharacterCallback(connectedBleDevice);if (listener != null) {listener.onDisConnected();}} else {isResetConnect = true;Log.e(TAG, "异常断开");if (!bleManager.isBlueEnable()) {bleManager.enableBluetooth();handler.postDelayed(bleScanRunnable, 200);} else {//重连handler.postDelayed(bleConnectRunnable, 200);}}}});}
//连接蓝牙public void connectBle(String MAC) {bleManager.connect(MAC, new BleGattCallback() {@Overridepublic void onStartConnect() {}@Overridepublic void onConnectFail(BleDevice bleDevice, BleException e) {//连接失败,需做好重连措施connectedBleDevice = bleDevice;handler.postDelayed(bleConnectRunnable, 200);Log.e("连接失败:", e.toString());}@Overridepublic void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {Log.e(TAG, "连接成功");receiveData(bleDevice);connectedBleDevice = bleDevice;handler.postDelayed(bleConnectedRunnable, 200);}@Overridepublic void onDisConnected(boolean b, BleDevice device, BluetoothGatt gatt, int status) {//连接断开,需区分异常断开与主动断开(b=true),异常断开的重连操作,需做好时间间隔操作,否者可能导致长时间连接不上的情况if (b) {Log.e(TAG, "正常断开");bleManager.clearCharacterCallback(device);gatt.connect();bleManager.clearCharacterCallback(connectedBleDevice);if (listener != null) {listener.onDisConnected();}} else {isResetConnect = true;Log.e(TAG, "异常断开");if (!bleManager.isBlueEnable()) {bleManager.enableBluetooth();handler.postDelayed(bleScanRunnable, 200);} else {//重连handler.postDelayed(bleConnectRunnable, 200);}}}});}
//接受数据private void receiveData(final BleDevice bleDevice) {final StringBuilder stringBuilder = new StringBuilder();bleManager.indicate(bleDevice,uuid_service,uuid_characteristic_receive,new BleIndicateCallback() {@Overridepublic void onIndicateSuccess() {//订阅通知成功handler.postDelayed(returnTimeOutRunnable, 5 * 1000);Log.e(TAG, "onIndicateSuccess: 订阅成功");}@Overridepublic void onIndicateFailure(BleException e) {Log.e("接收数据异常------------>", e.toString());}@Overridepublic void onCharacteristicChanged(byte[] bytes) {handler.removeCallbacks(returnTimeOutRunnable);//接收到的数据String s = BinaryConversionUtils.byte2hex(bytes);String resultData = BinaryConversionUtils.hexString2String(s);Pattern pattern = Pattern.compile("\n|\r");Matcher matcher = pattern.matcher(resultData);resultData = matcher.replaceAll("");stringBuilder.append(resultData);Log.e("接收数据成功------------>", stringBuilder.toString());
//                        Toast.makeText(context, resultData+"--", Toast.LENGTH_SHORT).show();if (listener != null) {if (TextUtils.isEmpty(stringBuilder.toString()) || stringBuilder.toString().contains("ERROR")) {//空返回handler.postDelayed(returnTimeOutRunnable, 200);} else if (resultData.contains("")) {//成功返回currentData = resultData;handler.postDelayed(receiveDataRunnable, 200);
//                                stopIndicate();}}}});}
//发送数据
//    public void sendData(final BleDevice bleDevice, final String str) {
//        byte[] data = BinaryConversionUtils.hex2byte(str);
//        bleManager.write(bleDevice,
//                uuid_service,
//                uuid_characteristic_send,
//                data,
//                true,
//                new BleWriteCallback() {
//                    @Override
//                    public void onWriteSuccess(int current, int total, byte[] justWrite) {
//                        // 发送数据到设备成功(分包发送的情况下,可以通过方法中返回的参数可以查看发送进度)
//                        Log.e("发送数据成功------------>", str);
//                        receiveData(bleDevice);
//                        bleManager.removeWriteCallback(bleDevice, uuid_characteristic_send);
//                    }
//
//                    @Override
//                    public void onWriteFailure(BleException exception) {
//                        // 发送数据到设备失败
//                        Log.e("发送数据异常------------>", exception.toString());
//                    }
//                });
//    }public void stopIndicate() {if (connectedBleDevice != null) {bleManager.stopIndicate(connectedBleDevice, uuid_service, uuid_characteristic_receive);bleManager.removeIndicateCallback(connectedBleDevice, uuid_characteristic_receive);}}//扫描设备的实时回调public interface OnBleListener {//扫描结果void onScaningBle(BleDevice bleDevice);//连接成功void onConnected(BleDevice bleDevice);//异常重连void onResetConnect();//返回数据void onReceiveData(String data);//返回数据超时void onTimeOutReturn();//蓝牙正常断开void onDisConnected();}public void setOnBleListener(OnBleListener listener) {this.listener = listener;}public class BleScanRunnable implements Runnable {@Overridepublic void run() {startScan();}}public class BleResetConnectRunnable implements Runnable {@Overridepublic void run() {if (connectedBleDevice != null) {if (listener != null)listener.onResetConnect();connectBle(connectedBleDevice);} else {Toast.makeText(context, "未扫描到蓝牙,请退出重连", Toast.LENGTH_SHORT).show();}}}public class BleConnectedRunnable implements Runnable {@Overridepublic void run() {if (listener != null)listener.onConnected(connectedBleDevice);}}public class ReturnTimeOutRunnable implements Runnable {@Overridepublic void run() {if (listener != null) {listener.onTimeOutReturn();}}}public class ReceiveDataRunnable implements Runnable {@Overridepublic void run() {if (listener != null) {listener.onReceiveData(currentData);}}}}

记得添加依赖哦

到这里蓝牙连接功能结束了。效果如下(gif图传不上去,委屈大家看看图片咯~):

确实是有点丑的要死哈~

 注意:一定要区分是BLE(低功耗)蓝牙还是经典蓝牙

到这里对于蓝牙开发就结束了,下篇文章将给出上文中提到的佳博和汉印两款打印机的开发历程。敲重点啦哈~如果对于获取UUID有好的方法的,可以留言讨论一下哈,互相学习嘛(*  ̄3)(ε ̄ *),本文的Demo有需要可以留下你的邮箱哟~

Android之BLE(低功耗)蓝牙开发相关推荐

  1. Android BLE低功耗蓝牙开发

    啦啦啦在上一个项目中有用到BLE低功耗蓝牙开发,当时baidu google了很多资料,但大多数都是千篇一律,英文文档我这种渣渣又看不懂...总之刚开始查的很痛苦.所以要把自己的踩坑之路写下来记录下, ...

  2. Android 8.0 BLE 低功耗蓝牙开发记录

    Android 8.0 BLE 低功耗蓝牙开发记录(1-3)--------------(权限申请篇未完待续) 目的:开源博客,希望大家一起修改博客错误地方,共同完善并会鸣谢提供意见的朋友.为大家提供 ...

  3. ble 低功耗蓝牙开发学习 嵌入式交流学习

    ble 低功耗蓝牙开发学习 嵌入式交流学习 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 这篇文章教你学会低功耗蓝牙开发,从0到深入,适合自学的学生.初级工程师 前言 随着疫情爆发 ...

  4. c# 低功耗蓝牙_Android ble低功耗蓝牙开发-客户端

    什么是BLE(低功耗蓝牙) BLE(Bluetooth Low Energy,低功耗蓝牙)是对传统蓝牙BR/EDR技术的补充. 尽管BLE和传统蓝牙都称之为蓝牙标准,且共享射频,但是,BLE是一个完全 ...

  5. Android ble covana,Android BLE低功耗蓝牙开发

    最近做了一个智能硬件开发(针灸仪)的项目,有一部分涉及到低功耗蓝牙的开发,就是通过蓝牙和设备进行数据的交互,比如控制改设备的LED的开关,设备的开关机,设置设备的时间和温度等,下面就项目中遇到的坑一一 ...

  6. android低耗能蓝牙开发,Android BLE低功耗蓝牙开发

    最近做了一个智能硬件开发(针灸仪)的项目,有一部分涉及到低功耗蓝牙的开发,就是通过蓝牙和设备进行数据的交互,比如控制改设备的LED的开关,设备的开关机,设置设备的时间和温度等,下面就项目中遇到的坑一一 ...

  7. Android BLE低功耗蓝牙开发(下) BLE客户端(中央设备)与GATT服务的通讯

    之前的文章简单实现了使用传统蓝牙进行通讯的DEMO,说是最简单其实只是夸张的写法~毕竟标题党横行,我们也得学学点~至少没有UC震惊部那么夸张. 然后,本来是要写Android开发之BlueTooth- ...

  8. 08_微信小程序-BLE低功耗蓝牙开发-设备搜索

    遇到的一些问题 BLE相关的好多函数都是异步的,但是BLE的操作又必须按照顺序流程来,否则就会出现问题,所以这里得嵌套大量的回调函数. 普通回调函数中this拿不到data数据的问题 原因:小程序在回 ...

  9. BLE低功耗蓝牙开发学习,从零到深教程文档总结(持续更新2022/6/14更新)

    写在前面: 写教程原因: 说说自己写这次的ble教程的由来吧.以往公司总有很多是做单片机的或者应届生毕业,他们对ble不是很连接,公司一般都会安排别人来做一点培训啊,或者老员工带.巧了,之前帮别的培训 ...

  10. 20_微信小程序-BLE低功耗蓝牙开发-发布小程序

    所有功能测试OK了,就剩下最后一步了,那就是把开发好的微信小程序发布出去. 1. 填写小程序信息,登录小程序管理平台,在设置->填写信息,里面填写小程序相关信息(后面我直接把小程序名称改为&qu ...

最新文章

  1. JAVA工程师定向招聘_Java工程师面试题整理[社招篇]
  2. python如何读取数据保存为新格式_Python Numpy中数据的常用保存与读取方法
  3. Java EE 8怎么了? (第2部分)
  4. Android启动后icon应用图标不能显示的可能问题
  5. oracle 数据库 字符串函数
  6. 简述ospf的工作原理_现代数字存储示波器的工作原理简述
  7. MacPort 的使用
  8. WindowsMobile应该如何发展?(未完待续)
  9. 织梦响应式鲜花绿植花艺类网站模板(自适应手机端)
  10. 145_Power BI Report Server自定义Form登录
  11. 实践:在运维大数据这事上,Apache Kylin比ELK更擅长?
  12. BlackBerry Key2 键盘扩展
  13. 两台笔记本的操作系统都为xp的共享上网教程
  14. 关于批判性思维(Critical Thinking)
  15. c语言万年历查询程序代码,C语言实现万年历程序
  16. 微信小程序——计算从今天到某天间隔多少天
  17. c语言程序中u8是什么意思,c – __u8和uint8_t之间的区别
  18. 备战下半年秋招,分享蚂蚁Java岗面试题80+
  19. 一道小学数学问题的编程解法
  20. rtsp和sdp协议简介

热门文章

  1. APP开发的七大阶段,你了解多少?
  2. cad卸载_CAD卸载后为什么安装不了?解决方法原来是这样!
  3. 问卷调查报告html,问卷调查报告格式优秀范文
  4. 字节跳动小程序平台审核常见被拒情形
  5. 广外专版-msn聊天记录查看器
  6. 7 基于matplotlib的python数据可视化——导入Excel数据制作饼图
  7. C# 图片识别技术(支持21种语言,提取图片中的文字)
  8. 关于使用itextpdf生成pdf的页面横向和竖向
  9. 程序员为什么要转行项目经理
  10. 微信小程序 内容评论-回复评论-回复回复的实现