Android蓝牙开发学习(传输数据到蓝牙模块)

来源:互联网 发布:上帝掷骰子吗 知乎 编辑:程序博客网 时间:2024/05/22 02:26

转载请注明出处:http://blog.csdn.net/ldslwh/article/details/73312704

蓝牙是一种支持设备短距离传输数据的无线技术,Android在2.0以后提供了这方面的支持。如今蓝牙的使用越来越普遍, 近期在项目中使用到了相关的蓝牙知识,因为ble的相关API需要Android4.3以上才支持,所以在项目中使用的还是传统蓝牙,在此归纳总结一下。

蓝牙常用的API

BluetoothAdapter

通过此类的方法你可以检测设备是否支持蓝牙,以及设备蓝牙的开启状态和蓝牙的开关,还可以搜索周边的蓝牙设备,以及查询已配对设备的列表等。

BluetoothDevice

代表一个远程蓝牙设备,通过这个类可以与远程设备连接,通过远程设备的BluetoothSocket获取输入和输出流。也可以通过此类查询关于设备名称、地址、类和连接状态等设备信息。

BluetoothSocket

代表蓝牙socket的接口(类似TCP的Socket)。这是允许一个应用程序跟另一个蓝牙设备通过输入流和输出流进行数据交换的连接点,可以通过这个socket接口发送数据到蓝牙模块,以及接受蓝牙返回来的信息。

BluetoothServerSocket

代表一个打开的监听传入请求的服务接口(类似于TCP的ServerSocket)。为了连接两个Android设备,一个设备必须用这个类打开一个服务接口。当远程蓝牙设备请求跟本设备建立连接请求时,BluetoothServerSocket会在连接被接收时返回一个被连接的BluetoothSocket对象。

蓝牙权限

BLUETOOTH权限
一般用于执行蓝牙通信(如请求连接、接收连接和传输数据)
BLUETOOTH_ADMIN权限
一般用于启动设备发现

开发流程

以上介绍了一些基本的蓝牙开发的API以及所需要的权限,接下来主要说一下蓝牙开发步骤。
1.首先,先通过getDefaultAdapter()获得系统默认的蓝牙适配器。

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

根据返回的mBluetoothAdapter是否为空来判断设备是否支持蓝牙,如果为null代表该设备不支持蓝牙。
2.通过获取到的蓝牙适配器蓝判断蓝牙是否开启,如果没有开启则先开启蓝牙,这里有两种开启方式,一种是直接开启(不弹出对话框),另一种是弹出对话框开启。

if (!mBluetoothAdapter.isEnabled()) { //通过用于弹出选择对话框开启  Intent enabler = new    Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);        startActivityForResult(enabler, 100);        //直接开启        // mBluetoothAdapter.enable();    } else {        startScan();    }

3.开启蓝牙后,可以先通过蓝牙设配器获取已配对的列表,如果已配对的蓝牙列表不存在你要连接的蓝牙设备,那么就进行周边的蓝牙搜索,在这里定义一个广播进行接受搜索蓝牙的消息。

public void getBondedDevices() {    Set<BluetoothDevice> pairedDevices =  mBluetoothAdapter.getBondedDevices();    //已配对列表不为空    if (pairedDevices.size() > 0) {        //判断已配对的列表里是否存在你要连接的蓝牙设备,如果存在        可以进行连接等操作。    } else {        //进行蓝牙设备的搜索        startScan();    }} //蓝牙搜索广播private final 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);    if (device != null && device.getName() != null && device.getName().equals("XXXX")) {  //搜索到你要的蓝牙设备后,马上停掉搜索,因为搜索这个操作很耗费资源      mBluetoothAdapter.cancelDiscovery();}}      } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {   if (index != 1) {       Toaster.show(getApplicationContext(), "未发现设备蓝牙设备!");                hideLoading();                //已搜素完成            }        }    }};

4.进行手机与蓝牙模块的连接。在这里我是通过反射的方法获取到蓝牙模块的BluetoothSocket,然后再进行连接,然后根据连接的状态进行回调,通知更新蓝牙连接状态,第一次连接新的蓝牙设备时,会弹出一个配对框,需要输入pin码(一般为0000或者1234),据闻可以通过反射进行主动帮用户输入并隐藏配对框,在这里我没做处理,因为对项目影响不大。

Method method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});BluetoothSocket socket= (BluetoothSocket) method.invoke(device, 1);try {  socket.connect();  } catch (Exception e) {    setState(CONNECT_FAILED);    state=DISCONNECTED; }setState(CONNECT_OK);state=CONNECT_OK;

5.进行手机与蓝牙模块通信。通过上面获取的socket,获取到输入和输出流,进行数据的发送和接收。最开始的时候,发现发送数据到蓝牙模块后响应返回的数据不完整,后来通过搜索相关资料后发现,因为蓝牙数据接收是有间隔的,如果连续往蓝牙模块不断发送数据,蓝牙模块可能并未来得及接收响应,所以返回的数据不完整,在这里我设置为连续发送的间隔为100毫秒。

 //往蓝牙模块发送byte数组数据。 OutputStream out = socket.getOutputStream();                out.write(bytes);                out.flush();                Thread.sleep(100); private void read() throws IOException {      InputStream in=socket.getInputStream();       int count = in.available();      byte[] bytes = new byte[count];      in.read(bytes);      String data= bytesToHexString(bytes);}

6.蓝牙传输结束后记得关闭资源。

 public void close() {    try {        if (socket != null) {            socket.close();        }    } catch (Exception e) {      }}

总结

以上就是我个人对蓝牙的一点初浅的经验,如果有不对的地方希望各位指出。