Android 蓝牙操作详解

1.启用蓝牙并使设备处于可发现状态    

   1.1 在使用BluetoothAdapter类的实例进操作之前,应启用isEnable()方法检查设备是否启用了蓝牙适配器。

    // 使用意图提示用户启用蓝牙,并使设备处于可发现状态

 private void startBluetooth() {
          BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
  // 检测蓝牙是否开启
  if (!bt.isEnabled()) {
              Intent enableIntent = new Intent(
                        BluetoothAdapter. ACTION_REQUEST_ENABLE);
              startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
          }
     }

 1.2返回意图活动时,调用onActivityResult(),可以提取主设备名称和mac地址

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == REQUEST_ENABLE_BT
                   && resultCode == Activity. RESULT_OK) {
              BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
              String address = bt.getAddress();
              String name = bt.getName();
              String toastText = name + " :" + address;
              Toast. makeText(this, toastText, Toast.LENGTH_LONG).show();
              discoverable();
          }
     }

1.3 请求用户授权,让设备可被其它临近设备发现:

 // 请求用户授权,让设备在120秒内处于可发现状态
 private void discoverable() {
          Intent discoverableIntent = new Intent(
 BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
          startActivity(discoverableIntent);
     }

2.连接启用蓝牙设备

 2.1对于任何蓝牙应用,都必须在AndroidManifst.xml中添加如下权限:

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

2.2 创建到其他蓝牙设备的套接字连接

     我们应该在一个线程内持续监听套接字流中的数据。可以在该线程外写入连接的流。这种连接是一个阻塞调用,由于蓝牙设备发现是一个缓慢的过程,可能降低连接速率。所以,在连接其它设备之前要取消设备发现。

     蓝牙套接字连接时阻塞调用,只在连接成功或者连接设备发生异常时才会返回。BluetoothConnection一经实例化,就会创建到其他设备的连接,并开始监听来自连接设备的数据。

package com.example.blueoothdemo;

 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.UUID;

 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothSocket;

 /**
 * 读写蓝牙设备
 *
 * @author hbbliyong
 *
 */
 public class BluetoothConnecion extends Thread {
      private final BluetoothSocket mSocket;
      private final InputStream mInStream;
      private final OutputStream mOutStream;
      byte[] buffer;
      private final BluetoothAdapter mAdapter;
      // 用于本应用程序唯一的UUID,
      private static final UUID MY_UUID = UUID
                .fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

      public BluetoothConnecion(BluetoothDevice device) {
           BluetoothSocket tmp = null;
           mAdapter = BluetoothAdapter.getDefaultAdapter();
           // 获得用于指定蓝牙连接的BluetoothSocket
           try {
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
           } catch (Exception e) {
                e.printStackTrace();
           }
           mSocket = tmp;

           // 在新线程中建立套接字连接,避免FC
           Thread connectionThread = new Thread(new Runnable() {
                @Override
                public void run() {
                     // TODO Auto-generated method stub
                     // 始终取消发现,因为它会降低连接的速度
                     mAdapter.cancelDiscovery();

                     // 建立到BluetoothSocket的连接
                     try {
                          // 这是一个阻塞调用,只在成功连接或者异常时返回
                          mSocket.connect();
                     } catch (Exception e) {
                          e.printStackTrace();
                          // 设备连接失败,关闭套接字
                          try {
                               mSocket.close();
                          } catch (Exception e2) {
                               // TODO: handle exception
                               e2.printStackTrace();
                          }
                     }
                }
           });

           connectionThread.start();

           InputStream tmpIn = null;
           OutputStream tmpOut = null;

           // 获得BluetoothSoket输入输出流
           try {
                tmpIn = mSocket.getInputStream();
                tmpOut = mSocket.getOutputStream();
                buffer = new byte[1024];
           } catch (Exception e) {
                e.printStackTrace();
           }
           mInStream = tmpIn;
           mOutStream = tmpOut;
      }

      public void run() {
           // 连接时保持监听InputStream
           while (true) {
                try {
                     // 从套接字流读取数据
                     mInStream.read(buffer);
                     // 向UI Activity发送获取的数据
                } catch (Exception e) {
                     // TODO: handle exception
                     // 这里的异常标志着连接的丢失
                     // 向UI Activity发送获取的数据
                     break;
                }
           }
      }
 
      public void write(byte[] buffer)
      {
           try {
                mOutStream.write(buffer);
           } catch (Exception e) {
                e.printStackTrace();
           }
      }
 
      public void cancel()
      {
           try {
                mSocket.close();
           } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
           }
      }
 }

3.监听和接收蓝牙连接请求

在两个蓝牙设备交互之前,其中一个通信设备必须起服务器的作用。它获取一个BluetoothServerSocket实例并监听入站请求。这个实例通过调用蓝牙适配器上的listenUsingRfcommWithServiceRecord()方法获得。有了这个实例我们可以通过start()方法开始监听来自远程设备的入站请求。

  //使主设备处于可发现状态
  Intent disCoverableIntent = new Intent(
                      BluetoothAdapter. ACTION_REQUEST_DISCOVERABLE);
  startActivityForResult(disCoverableIntent,DISCOVERY_REQUEST_BLUETOOTH );

 //创建一个蓝牙服务器并接受连接
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == DISCOVERY_REQUEST_BLUETOOTH ) {
  boolean isDiscoverable = resultCode > 0;
  if (isDiscoverable) {
  // UUID
  // uuid=UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666");
  final UUID uuid = UUID.randomUUID();
  final String serverName = "BTServer" ;
  final BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
  final BluetoothServerSocket bluetoothServer;
                   Thread listenThread = new Thread(new Runnable() {
  @Override
  public void run() {
  // TODO Auto-generated method stub
  try {
                                  bluetoothServer = bt.listenUsingRfcommWithServiceRecord(serverName, uuid);
                    BluetoothSocket serverSocket = bluetoothServer.accept();
                    myHandleConnectionWiht(serverSocket);
                             } catch (Exception e) {
                                  e.printStackTrace();
                             }
                        }
  private void myHandleConnectionWiht(
                                  BluetoothSocket serverSocket) {
  // TODO Auto-generated method stub
                        }
                   });
                   listenThread.start();
              }
          }
     }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术碎碎念

jdbc基础 (五) 连接池与数据源 DBCP以及C3P0的使用

一、连接池的概念和使用 在实际应用开发中,特别是在WEB应用系统中,如果JSP、Servlet或EJB使用JDBC直接访问数据库中的数据,每一次数据访问请求都必...

2556
来自专栏冷冷

【Spring Cloud】Redis缓存接入监控、运维平台CacheCloud

CacheCloud CacheCloud提供一个Redis云管理平台:实现多种类型(Redis Standalone、Redis Sentinel、Redis...

2787
来自专栏技术记录

如何减轻ajax定时触发对服务器造成的压力和带宽的压力?ajax-长轮训

AJAX长轮询的方法来解决频繁对后台的请求,进一步减小压力 在实现过程发现AJAX的多次请求会出现多线程并发的问题又使用线程同步来解决该问题 个人对ajax长轮...

1785
来自专栏电光石火

基于Tcp协议的简单Socket通信实例(JAVA)

基于TCP协议Socket服务端和客户端的通信模型: Socket通信步骤:(简单分为4步) 1.建立服务端ServerSocket和客户端Sock...

2236
来自专栏行者悟空

利用zookeeper实现服务上线(离线)自动感知

1582
来自专栏码匠的流水账

聊聊spring cloud gateway的ForwardedHeadersFilter

本文主要研究一下spring cloud gateway的ForwardedHeadersFilter

412
来自专栏java学习

数据库连接池C3P0,DBCP教程详解示例

连接池 实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection。...

4066
来自专栏积累沉淀

干货--JMS(java消息服务)整合Spring项目案例

Sprng-jms消息服务小项目 所需的包: spring的基础包 spring-jms-xx包 spring-messag...

30110
来自专栏JMCui

Java 原生网络编程.

    Java 语言从其诞生开始,就和网络紧密联系在一起。在 1995 年的 Sun World 大会上,当时占浏览器市场份额绝对领先的网景公司宣布在浏览器中...

832
来自专栏用户2442861的专栏

java数据库操作 (附带数据库连接池的代码)

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188

392

扫描关注云+社区