Android蓝牙操作-主动发起连接
上次Android开发中用到了蓝牙设备,用于主动连接stm32控制的蓝牙模块,这里把它的使用方式总结出来:
目录:
- 前言
- 操作步骤
- Android蓝牙控制代码
- 总结
一、前言
开发环境相关参数如下:
//AndroidSdudio2.2.2
compileSdkVersion 26
buildToolsVersion "26.0.0"
minSdkVersion 19
targetSdkVersion 19
当然,高于这个版本的理论上都是没问题的,因为没有用到一些高版本安卓的新特性,所以老版本的也可以试试。
二、操作步骤
其实蓝牙相关的基础知识网上一搜一大把,我就不在这里copy了,主要讲讲主动发起连接的相关用途与操作步骤。
用途:两个蓝牙连接后进行透明传输(可以理解为相当于一根数据线直接连接两个设备从而进行数据传输,忽略了蓝牙设备存在的事实以及相关实现细节)。
步骤1: 检测当前手机蓝牙是否开启,若没有则打开。
步骤2:对周围环境的蓝牙进行搜索,发现设备则记录起来。
步骤3:用户选择一个蓝牙设备进行连接。
步骤4:开始配对并发起连接。
步骤5:传输数据。
三、Android蓝牙控制代码
1、检测蓝牙是否开启:
private BluetoothAdapter mBTAdapter = null;
mBTAdapter = BluetoothAdapter.getDefaultAdapter(); //得到一个系统默认可用的蓝牙设备对象,可以用来进行大部分蓝牙操作了
if (!mBTAdapter.isEnabled()) { //如果蓝牙设备没有开启
mBTAdapter.enable();//申请打开蓝牙
}
2、发起搜索
//开始搜索设备
private void doDiscovery(){
if(BTAdapter.isDiscovering()){
BTAdapter.cancelDiscovery();//取消搜索
}
BTAdapter.startDiscovery();//开始搜索
}
3、记录设备
//定义两个string类型的数组适配器
ArrayAdapter<String> pairedListAdapter = new ArrayAdapter<String>(this.R.layout.device_name);//定义一个已连接过的设备列表适配器
newDeviceAdapter = new ArrayAdapter<String>(this, R.layout.device_name);//定义一个新设备列表的适配器
//下面三行是已连接设备的更新与点击
ListView pairedList = (ListView)findViewById(R.id.lv_paired);
pairedList.setAdapter(pairedListAdapter);//setAdapter,执行后都会到getView方法中,用来刷新新数据
pairedList.setOnItemClickListener(connectDeviceListener);//给已经配对了的设备列表的每一项注册监听事件
//下面三行是新设备的更新与点击
ListView newDeviceList = (ListView)findViewById(R.id.lv_newdevices);
newDeviceList.setAdapter(newDeviceAdapter);
newDeviceList.setOnItemClickListener(connectDeviceListener);
//接收系统发出的的发现新设备广播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(BTReceiver,filter);//注册广播器监听
//接收系统的搜索结束了的广播
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(BTReceiver,filter);
BTAdapter = BluetoothAdapter.getDefaultAdapter();//获取一个BluetoothAdapter对象昂
//以下这句话加下面的if判断句联合实现了一个功能:获取已配对的蓝牙list并展示在pairedList里
Set<BluetoothDevice> pairedDeviceSet = BTAdapter.getBondedDevices() ;//取得已经绑定了的蓝牙设备集合,蓝牙关闭时返回值为null
if(pairedDeviceSet.size()>0){//若已经绑定过的蓝牙设备不为空
for(BluetoothDevice device:pairedDeviceSet){
String s = device.getName().toString();
pairedListAdapter.add(device.getName() + "\n" + device.getAddress());//添加入列表
}
}else{
String noDevice = "没发现任何设备".toString();
pairedListAdapter.add(noDevice);
}
4、选择一个蓝牙并连接
if (mBTAdapter.getState() == BluetoothAdapter.STATE_ON) {//若不加这个判断语句,用户拒绝开启蓝牙时会闪退
String address = destinationBluetoothAddress;
BluetoothDevice decive = mBTAdapter.getRemoteDevice(address);
mChatServer.connect(decive);
}
//注意:这里是从另一个类截取的上面的mChatServer.connect(decive)的具体实现:
public synchronized void connect(BluetoothDevice device) {
//取消正在连接的线程
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {
mConnectThread.cancel();//关闭套接字
mConnectThread = null;
}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
**注意:**destinationBluetoothAddress必须是一个蓝牙的MAC地址字符串,可以从蓝牙列表获得。
5、传送数据
//获得message的内容转化为字符数组,使用输出流传递出去
private void sendMessage(String message){
if(mChatServer.getState()!= ChatServer.STATE_CONNECTED){//getstate():获取当前蓝牙的状态:已经打开,打开中,已经关闭,关闭中
//sendMsgtoUI("未连接");
reConnect.setImageResource(R.drawable.top_bulutooth_unconnect2);
title.setText("蓝牙灯:未连接");
return;
}
byte[] send = message.getBytes();
mChatServer.write(send);
//注意:这里贴上mChatServer.write(send)的具体实现:
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
//注意:这里将贴上 r.write(out)的具体实现:
public void write(byte[] buffer) {//将数据写入输出流的buffer
try {
mmOutStream.write(buffer);//mmOutStream是一个private final OutputStream mmOutStream;
} catch (IOException e) {
e.printStackTrace();
}
}
四、总结
其实代码只是一个简单的思路提供,由于几部分代码都封装成了类,不同功能代码是放在不同的类里面的,所以仅仅是直接复制那五步的,肯定是不能用的。但是我相信如果理解了,一定会收获很多。
而且因为项目的目标设备是STM32控制的蓝牙模块,所以这里直接解析为byte进行传输是有必要的(当然也是因为outputstream的特性)。
贴个图:
禁止转载。