使用Android Bluetooth APIs将设备通过蓝牙连接并通信,设置蓝牙,查找蓝牙设备,配对蓝牙设备
连接并传输数据,以下是Android系统提供的蓝牙相关的类和接口

  • BluetoothAdapter
  • BluetoothDevice
  • BluetoothSocket
  • BluetoothServerSocket
  • BluetoothClass
  • BluetoothProfile
  • BluetoothHeadset
  • BluetoothA2dp
  • BluetoothHealth
  • BluetoothHealthCallback
  • BluetoothHealthAppConfiguration
  • BluetoothProfile.ServiceListener

蓝牙权限

使用蓝牙功能,需要在AndroidManifest.xml中声明蓝牙相关的权限

  <uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

建立蓝牙

  • 初始化连接

    在通过蓝牙通信之前,需要先确定设备是否支持蓝牙功能,先初始化一个BluetoothAdapter的实例,
    BluetoothAdapter提供了一个静态方法getDefaultAdapter()来获得BluetoothAdapter的实例

    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (mBluetoothAdapter == null) {
    // 设备不支持蓝牙功能
    }
  • 打开蓝牙
    下一步就是打开蓝牙,调用isEnabled()方法检查蓝牙功能是否已经打开,返回true说明蓝牙已开启,
    返回false说明蓝牙功能未开启,开启蓝牙可以通过发送广播ACTION_REQUEST_ENABLE,也可以通过方法
    enable()直接打开,这两种方法都会有蓝牙权限的提示,选择允许,否则无法打开蓝牙

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

    在应用中可以设置蓝牙的状态的监听ACTION_STATE_CHANGED广播,当蓝牙的状态的变化时,就会触发这个
    广播,接收到这个广播之后,在intent中可以获得当前蓝牙的状态和前一次的蓝牙的状态

    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

    蓝牙的状态值有:

    int STATE_OFF = 10;//蓝牙关闭状态
    int STATE_TURNING_ON = 11;//蓝牙正在打开
    int STATE_ON = 12;//蓝牙打开状态
    int STATE_TURNING_OFF = 13;//蓝牙正在关闭

查找蓝牙设备

打开蓝牙之后,下一步就是查找可以使用的蓝牙设备,蓝牙的api中也提供了相关的接口,由于蓝牙的扫描
是一个耗电的操作,不用时计时取消扫描蓝牙

  mBluetoothAdapter.isDiscovering(); //监测蓝牙是否正在扫描
mBluetoothAdapter.startDiscovery();//开始扫描
mBluetoothAdapter.cancelDiscovery();//取消扫描

为了发现可用的蓝牙的设备,必须在应用中注册ACTION_FOUND的广播,调用方法startDiscovery()如果查找到可用的
设备会触发这个广播,这个广播中带有EXTRA_DEVICE的设备信息可以通过下面的方法获得设备的信息

  private final 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.e("tag","device name: "+device.getName()+" address: "+device.getAddress());
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
  • 查询已经配对的设备列表
    在进行查找之前,可以先获得之前已经配对成功的蓝牙设备的列表,可以调用方法getBondedDevices()获得
    已经配对的蓝牙设备列表

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    if (pairedDevices.size() > 0) {
    for (BluetoothDevice device : pairedDevices) {
    //可以获得已经配对的蓝牙的名称和地址
    Log.e("tag","device name: "+device.getName()+" address: "+device.getAddress());
    }
    }
  • 是其他设备可见
    上面讲的都是发现其他的蓝牙设备,也可以设置设备本身是否对其他设备可见,通过发送ACTION_REQUEST_DISCOVERABLE
    的广播,会调用系统的方法,还可以设置多长时间内是可见的,在intent中设置EXTRA_DISCOVERABLE_DURATION,最大值是
    3600s,超过3600s会设置为120s,点击允许会回调onActivityResult()方法

    //设置设备在300s内是可见的
    Intent discoverableIntent = new
    Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
    startActivity(discoverableIntent);

    如果没有打开蓝牙,执行上面的操作会自动打开蓝牙

    可以通过监听ACTION_SCAN_MODE_CHANGED广播,可以在intent中根据EXTRA_SCAN_MODE的参数获得当前设备的SCAN MODE
    有一些几种模式

    int SCAN_MODE_NONE = 20;//这个模式不能被发现也不能连接
    int SCAN_MODE_CONNECTABLE = 21;//这个模式不能被扫描到,但是可以连接
    int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;//这个模式可以被发现,也能被连接

蓝牙的连接

  • Server 端
    通过BluetoothAdapterlistenUsingRfcommWithServiceRecord(String, UUID)方法获得BluetoothServerSocket对象
    的实例,然后socket就会通过accept()监听客户端的连接的状态

    private class AcceptThread extends Thread {
    private final BluetoothServerSocket mmServerSocket;
    public AcceptThread() {
    BluetoothServerSocket tmp = null;
    try {
    tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
    } catch (IOException e) { }
    mmServerSocket = tmp;
    } public void run() {
    BluetoothSocket socket = null;
    // 在后台一直监听客户端的请求
    while (true) {
    try {
    socket = mmServerSocket.accept();
    } catch (IOException e) {
    break;
    }
    if (socket != null) {
    mmServerSocket.close();
    break;
    }
    }
    }
    public void cancel() {
    try {
    mmServerSocket.close();
    } catch (IOException e) { }
    }
    }
  • Client 端
    使用BluetoothDevicecreateRfcommSocketToServiceRecord(UUID)方法获得BluetoothSocket对象的实例
    然后调用connect()方法,这时server端会监听到这个请求,之后就建立连接,然后就可以进行通信了

    private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;
    public ConnectThread(BluetoothDevice device) {
    BluetoothSocket tmp = null;
    mmDevice = device;
    try {
    tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
    } catch (IOException e) { }
    mmSocket = tmp;
    } public void run() {
    mBluetoothAdapter.cancelDiscovery(); try {
    mmSocket.connect();
    } catch (IOException connectException) {
    try {
    mmSocket.close();
    } catch (IOException closeException) { }
    return;
    }
    }
    public void cancel() {
    try {
    mmSocket.close();
    } catch (IOException e) { }
    }
    }

连接的监听

可以通过注册广播监听蓝牙设备连接的状态变化,广播BluetoothDevice.ACTION_BOND_STATE_CHANGED,监听到这个广播之后,可以
在intent中获得连接的状态

  int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);

设备连接的状态值

  int BOND_NONE = 10;//没有连接
int BOND_BONDING = 11;//正在连接
int BOND_BONDED = 12;//已经建立连接

Android实践 -- Android蓝牙设置连接的更多相关文章

  1. android开发之蓝牙配对连接的方法

    最近在做蓝牙开锁的小项目,手机去连接单片机总是出现问题,和手机的连接也不稳定,看了不少蓝牙方面的文档,做了个关于蓝牙连接的小结. 在做android蓝牙串口连接的时候一般会使用 ? 1 2 3 4 5 ...

  2. Android蓝牙A2DP连接实现

    代码地址如下:http://www.demodashi.com/demo/14624.html 开发环境: 开发工具:Androidstudio 适配机型:honor8(Android6.0), 坚果 ...

  3. vue app混合开发蓝牙串口连接(报错java.io.IOException: read failed, socket might closed or timeout, read ret: -1;at android.bluetooth.BluetoothSocket.connect at js/BluetoothTool.js:329)

    我使用的uni-app <template> <view class="bluetooth"> <!-- 发送数据 --> <view c ...

  4. Android实践 -- 设置系统日期时间和时区

    设置系统日期时间和时区 设置系统的日期时间和时区,需要 系统权限和系统签名,android:sharedUserId="android.uid.system" 需要在manifes ...

  5. Android开发之蓝牙--扫描已经配对的蓝牙设备

    一. 什么是蓝牙(Bluetooth)? 1.1  BuleTooth是目前使用最广泛的无线通信协议 1.2  主要针对短距离设备通讯(10m) 1.3  常用于连接耳机,鼠标和移动通讯设备等. 二. ...

  6. Android真机测试,连接到本地服务器的方法

    1. 前言 作为一名Android开发者,不管怎么说,都会经历使用Android真机来测试连接本地服务器这样的事情.这里所说的“本地服务器”大多数时候指的是:搭载有某种服务器软件的PC,例如搭载有To ...

  7. Android开发常用权限设置

    加在AndroidManifest.xml 文件中manifest标签以内,application以外 例如:<!--网络权限 --> <uses-permission androi ...

  8. Android单片机与蓝牙模块通信实例代码

    Android单片机与蓝牙模块通信实例代码 参考路径:http://www.jb51.net/article/83349.htm 啦啦毕业了,毕业前要写毕业设计,需要写一个简单的蓝牙APP进行交互,通 ...

  9. Android学习之蓝牙操作

    BluetoothAdapter 用法 蓝牙运行原理:通过BluetoothAdapter 蓝牙适配器处理任务,如果蓝牙被启动之后,系统会自动去搜索其它设备,如果匹配到附近的设备就发送一个广播,Bro ...

随机推荐

  1. Swift学习笔记(8)--函数

    1.定义及调用 func sayHelloAgain(personName: String) -> String { return "Hello again, " + per ...

  2. Linux学习总结(5)——CentOS常用的目录文件操作命令

    CentOS常用的目录文件操作命令 一.路径操作的CentOS常用命令  cd pwd  NO1. 显示当前路径  [root@rehat root]# pwd  NO2. 返回用户主目录  [roo ...

  3. amlogic M8操作gpio bank

    參照规格书: r代表:读 a代表GPIOAO bank 0x28代表read bit echo r a 0x28 > /sys/class/amlogic/debug 操作GPIO口读取 w代表 ...

  4. 比MD5 和HMAC还要安全的加密 - MD5 加时间戳

    //1.给一个字符串进行MD5加密 NSString *passKey = @"myapp"; passKey = [passKey md5String]; //2.对第一步中得到 ...

  5. 下载eclipse详细步骤

    先登陆eclipse的官网 然后点击红色箭头进行选择你电脑是32还是64位的 根据自己的需求下载 然后点击下载 这里下载的是安装包,你要进行压缩.安装时一定要好相应的jdk要不然就会报错 这上面的错误 ...

  6. window cmd 命令大全 (order)

    Windows CMD命令大全 命令简介 cmd是command的缩写.即命令行 . 运行操作 CMD命令:开始->运行->键入cmd或command(在命令行里可以看到系统版本.文件系统 ...

  7. vue UI 框架

    (1)Element 饿了么 vue 2.0后台UI框架 (Star:18382) https://github.com/ElemeFE/element (1-1)Vuetify   最新的ui 框架 ...

  8. 通过PXE安装Linux实况

    通过PXE安装Linux实况 网卡引导操作系统的过程我们可以把它称为PXE(Pre-bootExecutionEnvironment),十几年前,在搞无盘NT时候,我们为了使网卡支持PXE引导要特意购 ...

  9. Android ijkplayer在windows下编译并导入Android Studio

     我是看着里面的步骤来做的,由于我自己对Linux环境和命令不熟悉,导致我对Cygwin的知识为零,在编译ijkplayer的时候走了一点弯路,需要的同学先去看一下上面的这篇文章,我这边是对上面文章做 ...

  10. spring bean中的properties元素内的ref和value的区别;* 和 ** 的区别

    spring bean中的properties元素内的ref和value的区别 至于使用哪个是依据你所用的属性类型决定的. <bean id="sqlSessionFactory&qu ...