Android蓝牙开发总结

一.蓝牙的使用环境:

版本的sdk才支持,模拟机上不能进行测试,需要在真机上进行测试。

2.  Android的蓝牙一般常用有2.0和4.0两个版本:

版本:使用BlueZ协议栈

版本:使用全新的协议栈,可快速建立简单的链接。作为蓝牙1.0 – 3.0版本中蓝牙标准协议的替代方案。

因此4.0版本的蓝牙连接协议和连接方式和2.0的版本是不一样的!

二.蓝牙的开发过程:

1.   要操作蓝牙,先要在AndroidManifest.xml里加入权限: 

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

2.  获取本地蓝牙适配器:

BluetoothAdapter  mAdapter  =  BluetoothAdapter.getDefaultAdapter();

3.   打开蓝牙:

If (!mAdapter.isEnabled()) {
Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabler, REQUEST_ENABLE)};

搜索蓝牙设备:

1)mAdapter.startDiscovery();

2)定义BroadcastReceiver,用来取得搜索的远程蓝牙设备的信息:

BroadcastReceiver broadcastReceiver = new BlueBroadcastReceiver();
)创建过滤器,注册广播接收器,BluetoothReceiver接收广播。
  //创建一个IntentFilter对象,将其action指定为BluetoothDevice.ACTION_FOUND
  //IntentFilter它是一个过滤器,只有符合过滤器的Intent才会被我BluetoothReceive所接收
        IntentFilter intent = new IntentFilter();
        intent.addAction(BluetoothDevice.ACTION_FOUND);
// 用BroadcastReceiver来取得搜索结果
        intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//注册广播接收器 注册完后每次发送广播后,BluetoothReceiver就可以接收到这个广播
        registerReceiver(broadcastReceiver, intent);

 

BroadcastReceiver接收到广播后,发现蓝牙设备,获取蓝牙设备的地址信息;

Class BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action=intent.getAction();
            // 当发现蓝牙设备时
            if(action.equals(BluetoothDevice.ACTION_FOUND)){
                // 从Intent中获取蓝牙设备对象
                //只要BluetoothReceiver接收到来自于系统的广播,这个广播是找到了  一个远程蓝牙设备
                //Intent代表刚刚发现远程蓝牙设备适配器的对象,可以从收到的Intent对象取出一些信息
                BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // 添加蓝牙的名称和地址到listView中并显示列表
                String str=(device.getName() + "|" + device.getAddress());
}

 

 4)建立蓝牙连接:

        A)通过远程蓝牙设备的地址来连接:

BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
  mBluetoothAdapter.cancelDiscovery();

        B)服务器端(BluetoothServerSocket)和客户端(BluetoothSocket)指定同样UUID来连接:

 1)服务器端:

BluetoothServerSocket serverSocket = mAdapter. listenUsingRfcommWithServiceRecord(serverSocketName,UUID);
serverSocket.accept();
      2)客户端:
BluetoothSocket clienSocket=dcvice. createRfcommSocketToServiceRecord(UUID);
clienSocket.connect();

 

5)数据传递:

inputStream = socket.getInputStream();
    outputStream = socket.getOutputStream();

接收到的数据是字节流,又由于一般来说厂家给的协议都是十六进制数据,所以很多情况需要一个byte转十六进制String的函数:

public static String bytesToHex(byte[] bytes) {char[] hexChars = new char[bytes.length * 2];for ( int j = 0; j < bytes.length; j++ ) {    int v = bytes[j] & 0xFF;    hexChars[j * 2] = hexArray[v >>> 4];    hexChars[j * 2 + 1] = hexArray[v & 0x0F];}return new String(hexChars);}

交换数据的方式:

发送一条协议的十六进制的数据给远程蓝牙设备,远程设备返回对应的数据,然后对接收到的字节流处理读取,提取我们需要的数据;

 

三.常用的蓝牙的类:

  1.BluetoothAdapter 蓝牙适配器

      BluetoothAdapter的常用方法:

      cancelDiscovery() 取消发现,停止搜索设备  

       disable()关闭蓝牙

      enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,

Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);打开蓝牙,这个方法会弹出提示;

startActivityForResult(enabler,reCode);//同startActivity(enabler);

      getAddress()获取本地蓝牙地址

      getDefaultAdapter()获取默认BluetoothAdapter,

      getName()获取本地蓝牙名称

      getRemoteDevice(String address)根据蓝牙地址获取远程蓝牙设备

      getState()获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要)

      isDiscovering()判断当前是否正在查找设备,是返回true

      isEnabled()判断蓝牙是否打开,已打开返回true,否则,返回false

     listenUsingRfcommWithServiceRecord(String name,UUID uuid)根据名称,UUID创建并返回BluetoothServerSocket,创建BluetoothSocket服务器端。

      startDiscovery()开始搜索;

 

2.BluetoothDevice蓝牙设备: 

      createRfcommSocketToServiceRecord(UUIDuuid)根据UUID创建并返回一个BluetoothSocket,创建BluetoothSocket;BluetoothSocket这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter一样;

          getState() 蓝牙状态,只有在 BluetoothAdapter.STATE_ON 状态下才可以监听;

 3.BluetoothServerSocket远程蓝牙设备,方法和Socket都差不多。
两个重载的accept(),accept(inttimeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!这两个方法都返回一个BluetoothSocket,最后的连接也是服务器端与客户端的两个BluetoothSocket的连接

      close()关闭!

4.BluetoothSocket和BluetoothServerSocket客户端和服务端:

      close(),关闭

      connect()连接

      getInptuStream()获取输入流

      getOutputStream()获取输出流

      getRemoteDevice()获取远程设备,获取bluetoothSocket指定连接的那个远程蓝牙设备