Android蓝牙开发

来源:互联网 发布:米思米2015选型软件 编辑:程序博客网 时间:2024/06/06 02:48

Android对于蓝牙开发从2.0版本的sdk才开始支持,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发。
1. 首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限

// 管理蓝牙设备的权限

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

// 使用蓝牙设备的权限

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

2.打开蓝牙
获得蓝牙适配器(android.bluetooth.BluetoothAdapter),检查该设备是否支持蓝牙,如果支持,就打开蓝牙。

[java]
// 检查设备是否支持蓝牙

adapter = BluetoothAdapter.getDefaultAdapter();    if (adapter == null)    {    // 设备不支持蓝牙      }    // 打开蓝牙      if (!adapter.isEnabled())    {    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);    // 设置蓝牙可见性,最多300秒      intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);    context.startActivity(intent);    }   

3.获取已配对的蓝牙设备(android.bluetooth.BluetoothDevice)
首次连接某蓝牙设备需要先配对,一旦配对成功,该设备的信息会被保存,以后连接时无需再配对,所以已配对的设备不一定是能连接的。

[java]

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();    Set<BluetoothDevice> devices = adapter.getBondedDevices();    for(int i=0; i < devices.size(); i++)    {            BluetoothDevice device = (BluetoothDevice) devices.iterator().next();       System.out.println(device.getName());    }   

4.搜索周围的蓝牙设备
适配器搜索蓝牙设备后将结果以广播形式传出去,所以需要自定义一个继承广播的类,在onReceive方法中获得并处理蓝牙设备的搜索结果。

[java]

// 设置广播信息过滤   IntentFilter intentFilter = new IntentFilter();    intentFilter.addAction(BluetoothDevice.ACTION_FOUND);    intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);    intentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);    intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);    // 注册广播接收器,接收并处理搜索结果      context.registerReceiver(receiver, intentFilter);    // 寻找蓝牙设备,android会将查找到的设备以广播形式发出去      adapter.startDiscovery();   

自定义广播类
[java]

private BroadcastReceiver receiver = new BroadcastReceiver() {       @Override      public void onReceive(Context context, Intent intent) {       String action = intent.getAction();        if (BluetoothDevice.ACTION_FOUND.equals(action)) {            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);            System.out.println(device.getName());       }       }    } 

5.蓝牙设备的配对和状态监视

[java]

private BroadcastReceiver receiver = new BroadcastReceiver() {    @Override    public void onReceive(Context context, Intent intent) {        String action = intent.getAction();        if (BluetoothDevice.ACTION_FOUND.equals(action)) {            // 获取查找到的蓝牙设备              BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);            System.out.println(device.getName());            // 如果查找到的设备符合要连接的设备,处理              if (device.getName().equalsIgnoreCase(name)) {                // 搜索蓝牙设备的过程占用资源比较多,一旦找到需要连接的设备后需要及时关闭搜索                  adapter.cancelDiscovery();                // 获取蓝牙设备的连接状态                  connectState = device.getBondState();                switch (connectState) {                    // 未配对                      case BluetoothDevice.BOND_NONE:                        // 配对                          try {                            Method createBondMethod = BluetoothDevice.class.getMethod("createBond");                            createBondMethod.invoke(device);                        } catch (Exception e) {                             e.printStackTrace();                        }                        break;                    // 已配对                      case BluetoothDevice.BOND_BONDED:                        try {                            // 连接                             connect(device);                        } catch (IOException e) {                            e.printStackTrace();                        }                        break;                }            }       } else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {            // 状态改变的广播              BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);            if (device.getName().equalsIgnoreCase(name)) {                 connectState = device.getBondState();                switch (connectState) {                    case BluetoothDevice.BOND_NONE:                        break;                    case BluetoothDevice.BOND_BONDING:                        break;                    case BluetoothDevice.BOND_BONDED:                        try {                            // 连接                              connect(device);                        } catch (IOException e) {                            e.printStackTrace();                        }                        break;                }            }        }    }    }   

6.蓝牙设备的连接

[java]

private void connect(BluetoothDevice device) throws IOException {  // 固定的UUID   final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";  UUID uuid = UUID.fromString(SPP_UUID);  BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuid);  socket.connect();  } 

服务端接受外来的连接


private class AcceptThread extends Thread {private final BluetoothServerSocket mmServerSocket; public AcceptThread() {    // Use a temporary object that is later assigned to mmServerSocket,    // because mmServerSocket is final    BluetoothServerSocket tmp = null;    try {        // MY_UUID is the app's UUID string, also used by the client code        tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);    } catch (IOException e) { }    mmServerSocket = tmp;}public void run() {    BluetoothSocket socket = null;    // Keep listening until exception occurs or a socket is returned    while (true) {        try {            socket = mmServerSocket.accept();        } catch (IOException e) {            break;        }        // If a connection was accepted        if (socket != null) {            // Do work to manage the connection (in a separate thread)           // manageConnectedSocket(socket);            mmServerSocket.close();            break;        }    }}/** Will cancel the listening socket, and cause the thread to finish */public void cancel() {    try {        mmServerSocket.close();    } catch (IOException e) { }}}

客户端初始化蓝牙连接

private class ConnectThread extends Thread {private final BluetoothSocket mmSocket;private final BluetoothDevice mmDevice;public ConnectThread(BluetoothDevice device) {    // Use a temporary object that is later assigned to mmSocket,    // because mmSocket is final    BluetoothSocket tmp = null;    mmDevice = device;    // Get a BluetoothSocket to connect with the given BluetoothDevice    try {        // MY_UUID is the app's UUID string, also used by the server code        tmp = device.createRfcommSocketToServiceRecord(MY_UUID);    } catch (IOException e) { }    mmSocket = tmp;}public void run() {    // Cancel discovery because it will slow down the connection    mBluetoothAdapter.cancelDiscovery();    try {        // Connect the device through the socket. This will block        // until it succeeds or throws an exception        mmSocket.connect();    } catch (IOException connectException) {        // Unable to connect; close the socket and get out        try {            mmSocket.close();        } catch (IOException closeException) { }        return;    }    // Do work to manage the connection (in a separate thread)   // manageConnectedSocket(mmSocket);}/** Will cancel an in-progress connection, and close the socket */public void cancel() {    try {        mmSocket.close();    } catch (IOException e) { }}}

本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2011-12/48374.htm

1.BluetoothAdapter 顾名思义,蓝牙适配器,直到我们建立bluetoothSocket连接之前,都要不断操作它

  BluetoothAdapter里的方法很多,常用的有以下几个:  cancelDiscovery() 根据字面意思,是取消发现,也就是说当我们正在搜索设备的时候调用这个方法将不再继续搜索  disable()关闭蓝牙  enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,更多的时候我们需要问下用户是否打开,一下这两行代码同样是打开蓝牙,不过会提示用户:Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enabler,reCode);//同startActivity(enabler);  getAddress()获取本地蓝牙地址  getDefaultAdapter()获取默认BluetoothAdapter,实际上,也只有这一种方法获取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   这个方法也是我们获取BluetoothDevice的目的——创建BluetoothSocket   这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter3.BluetoothServerSocket如果去除了Bluetooth相信大家一定再熟悉不过了,既然是Socket,方法就应该都差不多,

这个类一种只有三个方法

两个重载的accept(),accept(inttimeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!

还有一点需要注意的是,这两个方法都返回一个BluetoothSocket,最后的连接也是服务器端与客户端的两个BluetoothSocket的连接

  close()这个就不用说了吧,翻译一下——关闭!4.BluetoothSocket,跟BluetoothServerSocket相对,是客户端

一共5个方法,不出意外,都会用到

  close(),关闭  connect()连接  getInptuStream()获取输入流  getOutputStream()获取输出流  getRemoteDevice()获取远程设备,这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备

蓝牙通讯源码下载:http://download.csdn.net/detail/he_666/9511565

0 0