本文意在介绍蓝牙开发的主要流程,学习使用蓝牙开发一个星期了,写写一个星期以来遇到的一些小问题,还有介绍下流程。开发具有基本的通信功能,本项目主要是用于与蓝牙模块的串口读写功能。
下一篇文章还有Android开发之蓝牙(二)——基于BLE协议蓝牙模块通信:
http://blog.csdn.net/wzhworld/article/details/76324738
1、魅族手机
2、蓝牙FSC-BT826
3、最终目的是做出能与串口调试助手通信的功能
1、适配器:
BuletoothAdapter:本地蓝牙的适配器,也就是说当前应用程序所运行的Android设备上的蓝牙。
BuletoothDevice : 远程的蓝牙适配器,也就是说你要连接的Android设备的适配器。。
2、权限:
android.permission.BLUETOOTH : 一些配置连接蓝牙的权限
android.permission.BLUETOOTH_ADMIN : 进行操作的权限
3、相关广播:
BluetoothDevice.ACTION_FOUND:表示可搜索到附近的蓝牙设备
BluetoothDevice.ACTION_PAIRING_REQUEST:配对请求
BluetoothAdapter.ACTION_STATE_CHANGE:配对状态改变
后面两个因为刚刚开始用的时候很迷糊,所以就直接是自动匹配,所以这两个都没怎么用到,不过感觉如果是要做这一方面的话得去了解这些广播代表什么。
程序写得有点乱,所以还是说下大概程序写法,
(1)我是在主活动初始化布局、蓝牙适配、获取选定蓝牙设备,PS:得先匹配后才能连接
(2)然后开启一个服务,通过广播从主活动把选定蓝牙对象发送到服务中。
(3)服务收到之后主要所做的任务就是开启两个线程,一个是负责对蓝牙的socket进行连接,另一个是通过socket进行读写,第二个线程主要进行的是read,而写只需要在需要的时候才使用,所以不需要在run中。
(4)异步线程采用消息机制handler进行成功失败消息的传输。
1、检测蓝牙以及权限是否开启
//获取蓝牙适配器,当没有开启时开启,会回调一个成功与否的结果
private void initBluetooth() {
if(!mBluetoothAdapter.isEnabled()){
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE);
}
}
2、此时注册一个广播接收器进行接收
//注册广播
IntentFilter discoveryFilter = new IntentFilter();
discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
discoveryFilter.addAction(BluetoothTools.ACTION_CONNECT_ERROR);
discoveryFilter.addAction(BluetoothTools.ACTION_CONNECT_SUC);
discoveryFilter.addAction(BluetoothTools.ACTION_RECEIVE_DATA);
registerReceiver(mBluetoothReceiver, discoveryFilter);
3、获取本地适配器,进行连接
public BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
******
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();//异步的,不会等待结果,直接返回。
} else if(!mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.startDiscovery();
} //如果设备正在寻找
4、进行匹配,连接
ClsUtils.createBond(mLastBluetoothDevice.getClass(), mLastBluetoothDevice);
ClsUtils.setPin(mLastBluetoothDevice.getClass(), mLastBluetoothDevice,pin);
使用了一个ClsUtils的工具类,其实就是将一些创建配对什么的提供一个方法,简单化。
不过遇到的奇怪的问题就是我createBond创建配对之后,使用Pin配对会自动配对,并没有说弹出窗口,查了下网上说需要取消窗口什么的,我试了也是不行,所以就最后没管了,直接一个自动配对,不过pin是死的,我设了0000,对BT826模块等蓝牙模块才有用。
5、在主活动获取对象之后,传到服务之中去开启线程。首先是开启连接的线程
//如果匹配成功
if (BluetoothTools.ACTION_PAIRING_SUCC.equals(actionCon)){
Bundle mBundle = intent.getExtras();
BluetoothDevice mBluetoothDevice = mBundle.getParcelable("Pairing_Succ");
BluetoothClientConnThread mThread = new BluetoothClientConnThread(handler,mBluetoothDevice);
mThread.start();//开钱连接线程
}
6、进行连接的具体过程
注意连接之前要取消扫描,因为扫描是一个很费时的动作,连接通信的过程其实与网络的SOCKET相似。
//UUID匹配
socket = serverDevice.createRfcommSocketToServiceRecord(BluetoothTools.PRIVATE_UUID);//蓝牙模块的UUID是固定(只对于spp),是00001101-0000-1000-8000-00805F9B34FB
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
socket.connect();
Log.e("Socket connect",String.valueOf(socket.isConnected()));
7、开启聊天的线程
通过广播读取editView写的数据,然后用的是gbk,当时有用过UTF8但是传输我记得发生乱码
//如果键盘点击send发送数据
if(BluetoothTools.ACTION_DATA_TO_GAME.equals(actionCon)){
try {
String editData = (String)intent.getExtras().get("editViewData");
byte[] bytes = editData.getBytes("gbk");
communThread.write(bytes);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
8、通信线程的read、write
bytes = mmInStream.read(buffer);
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_READ_OBJECT, bytes, -1, buffer).sendToTarget();
就是将读到的buffer通过消息机制传回服务,
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
当时也参考了很多的文章,有得是用object传输的,但传的的时候有点问题,传不了,所以最后都改为使用字节流传输。
基本大概的spp通信就是这样一个过程,整体上不算很难,但因为属于初学阶段用起来还不是很熟练,所以学得久一点。下一篇的BLE其实大概过程相差不会很大,但有一些会改变。
Android开发之蓝牙(二)——基于BLE协议蓝牙模块通信
git下载
csdn下载