Android 普通蓝牙学习

需要的权限
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />


蓝牙有关的所有的类如下:

普通蓝牙用到的几个关键的类:

BluetoothAdapter 蓝牙适配器

Represents the local device Bluetooth adapter. The BluetoothAdapter lets you perform fundamental Bluetooth tasks, such as initiate device discovery,

query a list of bonded (paired) devices, instantiate a BluetoothDevice using a known MAC address, and create a BluetoothServerSocket to listen for

connection requests from other devices, and start a scan for Bluetooth LE devices.

根据官方文档的说明,BluetoothAdapter可以执行基本的蓝牙任务,比如启动设备发现,查询已配对的蓝牙列表,使用已知的地址实例化一个BluetoothDevice,创建一个BluetoothServerSocket

监听链接请求等。

BluetoothDevice 蓝牙设备

Represents a remote Bluetooth device. A BluetoothDevice lets you create a connection with the respective device or query information about it,

such as the name, address, class, and bonding state.

代表一个远程蓝牙设备。BluetoothDevice允许创建一个连接的设备或查询相关信息,如名称、地址、阶级和配对的状态。

BluetoothSocket

The interface for Bluetooth Sockets is similar to that of TCP sockets: Socket and ServerSocket.

顾名思义蓝牙连接

BluetoothServerSocket

The interface for Bluetooth Sockets is similar to that of TCP sockets: Socket and ServerSocket.

蓝牙服务链接,后两者都是和TCP端口类似的一个socket。

BluetoothAdapter
首先打开蓝牙开始搜索等;

主要用到的几个方法:

getDefaultAdapter() 获取一个适配器对象

getName() 获取本地蓝牙名称

getAddress() 获取本地蓝牙的地址

enable() 打开本地蓝牙(低版本中不会提示用户)

isEnabled() 判断蓝牙是否已经打开

disable() 关闭本地蓝牙

startDiscovery() 开始搜索(发现)

cancelDiscovery() 取消设备搜索(发现)

isDiscovering() 返回当前是否是在搜索设备

listenUsingRfcommWithServiceRecord(String name, UUID uuid) 创建一个安全的BluetoothServerSocket

打开蓝牙

bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //打开蓝牙 方法一
        if (!bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.enable();
        }

//方法二 推荐
        Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enabler, REQUEST_ENABLE);

开始搜索设备

调用startDiscovery()开始搜索设备,但是仅仅调用此方法是没有任何作用的,startDiscovery()是异步调用,立即返回,需要注册一个广播接收者

来接受搜索的结果。整个搜索过程持续12秒。

//注册
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, intentFilter);

//广播接收者
BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //找到设备
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent
                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                Log.d("MainActivity", "搜索到设备");
                //在列表中显示搜索出的设备
                adapter.add("name : " + device.getName() + "\n address : " + device.getAddress());
                bluetoothDevices.add(device);
            }
            //搜索完成
            else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
                    .equals(action)) {
                Log.d("MainActivity", "搜索结束");
            } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                Log.d("MainActivity", "开始搜索");
            }
        }
    };

连接设备

建立连接,Android sdk支持的蓝牙连接是通过BluetoothSocket建立连接,服务器端(BluetoothServerSocket)和客户端(BluetoothSocket)需指定同样的UUID,才能建立连接,因为建立连接的方法会阻塞线程,所以服务器端和客户端都应启动新线程连接。

UUID的格式如下:

String uuid = "a60f35f0-b93a-11de-8a39-08002009c666";

建立服务器端代码如下:

首先建立服务器,获取BluetoothServerSocket对象,通过BluetoothAdapter的listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid)方法和listenUsingRfcommWithServiceRecord(String name, UUID uuid)方法,其中前者是不安全的链接,后者是安全的链接。

然后使用BluetoothServerSocket.accept()方法接受客户端连接,当连接成功返回一个BluetoothSocket对象。

private class ServiceThread extends Thread {
        @Override
        public void run() {

BluetoothServerSocket serverSocket = null;
            try {
                serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord("my_test_lianjie", UUID.fromString(uuid));
                Log.d("ServiceThread", "建立服务器成功");
            } catch (IOException e) {
                e.printStackTrace();
                Log.d("ServiceThread", "建立服务器失败");
            }

try {
                socket = serverSocket.accept();
                Log.d("ServiceThread", "客户端连接成功");
                new ReadThread().start();
            } catch (IOException e) {
                e.printStackTrace();
                Log.d("ServiceThread", "客户端连接失败");
            }
        }
    }

建立客户端链接代码如下:

这里需要注意的是要对首先检测设备是否进行了配对,只有首先进行配对才能进行连接。蓝牙配对是通过反射的方法调用BluetoothDevice.creMethod()方法。

建立连接首先获取BluetoothSocket对象,调用BluetoothDevice的createInsecureRfcommSocketToServiceRecord(UUID uuid)或者createRfcommSocketToServiceRecord(UUID uuid)方法,其中前者是不安全的链接,后者是安全的链接。

然后调用BluetoothSocket.connect()方法进行连接。

private class ConnectThread extends Thread {

BluetoothDevice device;

public ConnectThread(BluetoothDevice device) {
            this.device = device;
        }

@Override
        public void run() {

try {
                socket = device.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
            } catch (IOException e) {
                e.printStackTrace();
            }

if (device.getBondState() == BluetoothDevice.BOND_BONDED) { //已配对设备 直接进行链接
                connectSocket();
            } else if (device.getBondState() == BluetoothDevice.BOND_NONE) { //未配对设备 先配对再链接
                Method creMethod = null;
                try {
                    creMethod = BluetoothDevice.class.getMethod("createBond");
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
                Log.e("TAG", "开始配对");
                try {
                    creMethod.invoke(device);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    Log.e("TAG", "配对失败");
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }

private void connectSocket() {
            try {
                socket.connect();
                Log.e("TAG", "连接成功");
                new ReadThread().start();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("TAG", "连接失败");
            }
        }

public void cancel() {
            try {
                socket.close();
                socket = null;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
        }
    }

客户端建立连接的方式有很多种,这里使用的是先获得一个socket然后再检查是否需要进行配对,再建立连接。

还可以通过反射的方法,通过端口进行连接。

进行通讯

蓝牙通讯是通过流的方式进行的:

OutputStream outS = socket.getOutputStream();

InputStream inS = socket.getInputStream();

发送的方法如:

OutputStream os = null;
                try {
                    os = socket.getOutputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    os.write("你好".getBytes());
                    Log.d("MainActivity", "发送成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d("MainActivity", "发送失败");
                }

接受的方法如:

private class ReadThread extends Thread {
        @Override
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
            InputStream mmInStream = null;

try {
                mmInStream = socket.getInputStream();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            while (true) {
                try {
                    // Read from the InputStream
                    if ((bytes = mmInStream.read(buffer)) > 0) {
                        byte[] buf_data = new byte[bytes];
                        for (int i = 0; i < bytes; i++) {
                            buf_data[i] = buffer[i];
                        }
                        String s = new String(buf_data);
                        Log.d("ReadThread", s);
                    }
                } catch (IOException e) {
                    try {
                        mmInStream.close();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    break;
                }
            }
        }
    }

至此,普通蓝牙的基本发现、连接、通讯功能就完成了,当然还有许多需要完善的地方。

Android BLE(2)---蓝牙学习相关推荐

  1. Android BLE低功耗蓝牙学习总结

    1.服务器端相关原理:https://blog.csdn.net/weixin_38032755/article/details/78357035 2.客户端相关原理:https://www.jian ...

  2. Android BLE(1)---蓝牙通讯学习

    Android BLE蓝牙通讯学习 在app应用的开发过程中,一般和蓝牙接触的不多,但是随着智能穿戴设备的发展,穿戴设备和手机关联的app越来越多,之前也是没怎么接触过这一块的东西,正好最近需要做一个 ...

  3. Android BLE(低功耗蓝牙)技术总结

    文章目录 前言 一.蓝牙介绍 1.什么是蓝牙? 2.蓝牙版本介绍 二.低功耗蓝牙(BLE) 1.BLE介绍 2.经典蓝牙(Classic Bluetooth)与低功耗蓝牙(BLE)的区别 3.低功耗蓝 ...

  4. Android BLE低功耗蓝牙开发

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

  5. Android BLE设备蓝牙通信框架BluetoothKit

    BluetoothKit是一款功能强大的Android蓝牙通信框架,支持低功耗蓝牙设备的连接通信.蓝牙广播扫描及Beacon解析. 关于该项目的详细文档请关注:https://github.com/d ...

  6. android ble 经典蓝牙,Android 经典蓝牙(Classic Bluetooth)和低功耗蓝牙(BLE)

    [实例简介] 从蓝牙4.0开始包含两个蓝牙芯片模块:传统/经典蓝牙模块(Classic Bluetooth,简称BT)和低功耗蓝牙(Bluetooth Low Energy,简称BLE) 经典蓝牙是在 ...

  7. Android BLE 低功耗蓝牙技术使用解析

    什么是BLE BLE 全称为 Bluetooth low energy,意思是低功耗蓝牙. Android 4.3 (API 18)之后引入Ble. 最常用的Ble蓝牙技术是设备之间传输数据. And ...

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

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

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

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

最新文章

  1. poj1988(判断一个结点下面有多少个结点,推荐)
  2. eclipse常用以及实用的快捷键
  3. 新年立个小目标!代码写得更规范!
  4. 飞鸽传书的设计应当具有“完整性”
  5. JAVA学习 02Day
  6. java 和_java中的和=是什么意思
  7. 动态规划算法实验报告_搞懂这几点,动态规划算法就是那么简单
  8. SqlServer存储过程调用接口
  9. Java Web开发Session超时设置
  10. Python培训包食宿
  11. 专访微软梁念坚:任职两年给自己打70分
  12. php base64 转 amr,base64转amr文件
  13. android 实现果冻动画效果,Android实现果冻滑动效果的控件
  14. 中国居民身份证号码检验程序
  15. python 根据空格切割英文单词
  16. 小南迎宾机器人使用说明
  17. ESP32S蓝牙05
  18. 半乳糖-人血清白蛋白 Gal-HSA,Gal-PEG-HSA 半乳糖修饰人血清白蛋白
  19. 盘点:2022年国内31省市数字经济发展相关政策、目标
  20. 数学分析-证明:单调有界数列必有极限

热门文章

  1. 【实验1】——脉冲测距
  2. ARM汇编指令:LDR伪指令和LDR装载指令的区别
  3. 微软物联网服务器,靠近物联网 微软发布定制 Linux内核
  4. java生成unix.z压缩_JAVA压缩 解压缩zip 并解决linux下中文乱码
  5. 菜鸟学习笔记:Java提升篇6(IO流2——数据类型处理流、打印流、随机流)
  6. github仓库建立及配置教程新手教程
  7. yii2解决资源插件路径不对应问题
  8. 每天一点点之vue框架开发 - vue坑-input 的checked渲染问题
  9. Makefile知识点
  10. gmail导入foxmail