公司项目,需要开发一个,手机蓝牙通过蓝牙模块和传感器通信的软件
手机app:
我是先看了android官网关于蓝牙这方面的知识(https://developer.android.com/guide/topics/connectivity/bluetooth),
然后参考的(https://blog.csdn.net/huangliniqng/article/details/82185983),
最后写完后,又找个一篇巩固了一下知识(https://blog.csdn.net/qq_25827845/article/details/52997523)
其中,权限1在得到默认蓝牙适配器时需要,即BluetoothAdapter mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter( )
权限2在mBluetoothAdapter.enable( )或者mBluetoothAdapter.disable( ) 时需要使用到。
1.判断蓝牙是否打开,得到的默认适配器不为空的时候支持蓝牙:
bluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
if(bluetoothAdapter!=null){
//支持蓝牙
}else {
ToastUtil.show(context,"不支持蓝牙");
}
2.判断蓝牙是否打开:
//蓝牙是否打开
if(!bluetoothAdapter.isEnabled()){
bluetoothAdapter.enable();//启动蓝牙
}
3.开始搜索,搜索的结果以广播的形式进行发送出来:
bluetoothAdapter.startDiscovery();//开始搜索,搜索出的结果将以广播的形式发送出来
4.注册广播,接收搜索结果并将其适配到ListView中:
mainActivity中注册,开始搜说后,每搜索到一个设备就会发送一个广播,广播接收着就能接收到并作相关处理,我这里的处理是——每接收到一个找到设备广播后,得到这个设备,并将其发送到mainctivity中,mainActivity中进行解析。
registerReceiver(blueToothReceiver,blueToothReceiver.markFilter());//动态注册广播
public class BlueToothReceiver extends BroadcastReceiver {
private int pairingSuccess=5;
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()){
case BluetoothAdapter.ACTION_STATE_CHANGED:
int blueStat= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,0);
switch (blueStat){
case BluetoothAdapter.STATE_TURNING_ON://蓝牙打开中
break;
case BluetoothAdapter.STATE_ON://蓝牙打开完成
break;
case BluetoothAdapter.STATE_TURNING_OFF://蓝牙关闭中
break;
case BluetoothAdapter.STATE_OFF://蓝牙关闭完成
break;
}
break;
//开始扫描
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
EventBus.getDefault().post(new BluRxBean(STARTSCAN));
break;
//找到设备
case BluetoothDevice.ACTION_FOUND:
//将得到的设备发送给前端处理
EventBus.getDefault().post(new BluRxBean(BlueToothId.RECEIVER_MESSAGE_Byte,(BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)));
break;
//搜索完成
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
EventBus.getDefault().post(new BluRxBean(ENDSCAN));
break;
//状态改变
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
BluetoothDevice de =intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (de.getBondState()) {
case BluetoothDevice.BOND_NONE:
break;
case BluetoothDevice.BOND_BONDING:
ToastUtil.shortShow(context,"配对中");
break;
case BluetoothDevice.BOND_BONDED:
ToastUtil.shortShow(context,"配对成功");
EventBus.getDefault().post(new BluRxBean(pairingSuccess));
break;
}
break;
}
}
public IntentFilter markFilter(){
IntentFilter filter=new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变
return filter;
}
}
5.mainActivity中解析得到的设备,并将其适配到ListView中
这里需要两个List集合,一个方存放设备(用于listview点击事件中用到,知道点击的那个设备,才能进行连接)
另一个,将设备的名字、状态、图表放进map中,然后放在list中(用于适配到listView中)
listBlueToothReceiver.add(bluRxBean.getBluetoothDevice());
Map map = new HashMap<>();
map.put("deviceName", bluRxBean.getBluetoothDevice().getName() + "\n" + bluRxBean.getBluetoothDevice().getAddress());
if(bluRxBean.getBluetoothDevice().getBondState()!=BluetoothDevice.BOND_BONDED){
map.put("statue", "未配对");
map.put("image",R.drawable.unline);
} else {
map.put("statue", "已配对");
map.put("image",R.drawable.line);
}
btDetails.add(map);
adapter=new BlueToothDataAsapter(context,btDetails);
list.setAdapter(adapter);
6.ListView点击事件,配对并连接设备
//ListView点击事件
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, final int position, long id) {
Map map;
map = btDetails.get(position);
if (map.get("statue").equals("已配对")) {
//如果已经配对成功就进行连接
alertDialog = DialogUtils.dialogloading(context, "正在连接", false, false);
poolExecutor.execute(new Runnable() {
@Override
public void run() {
connect(listBlueToothReceiver.get(position));
}
});
}
else {
//开始配对
try {
listOnClickItem=position;
//如果想要取消已经配对的设备,只需要将creatBond改为removeBond
Method method = BluetoothDevice.class.getMethod("createBond");
Log.e(getPackageName(), "开始配对");
method.invoke(listBlueToothReceiver.get(position));
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
//-----蓝牙连接代码,项目中连接会使用封装的工具类,在这里提取重写--------
private void connect(final BluetoothDevice bluetoothDevice) {
new Thread(new Runnable() {
@Override
public void run() {
try {
//得到客户端Socket
mBluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(BlueToothId.SPP_UUID);
if (mBluetoothSocket != null) {
App.bluetoothSocket = mBluetoothSocket;//保证Socket的生命周期最长
if (bluetoothAdapter.isDiscovering()) {//如果正在发现
bluetoothAdapter.cancelDiscovery();//停止发现
}
if (!mBluetoothSocket.isConnected()) {//如果没有链接
mBluetoothSocket.connect();//进行连接
}
EventBus.getDefault().post(new BluRxBean(connectsuccess, bluetoothDevice));
}
} catch (Exception e) {
e.printStackTrace();
try {
mBluetoothSocket.close();
DialogUtils.dimissloading(alertDialog);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}).start();
}
1.发送消息
private void sendMessageByte(byte[] message){
if(bluetoothSocket!=null&&message.length>0){
try {
outputStream= bluetoothSocket.getOutputStream();//得到输入流
outputStream.write(message);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.接收消息
public void receiveMessageByte(){
Log.e("3 ","接收到数据");
if(App.bluetoothSocket==null)return;
try {
in=App.bluetoothSocket.getInputStream();//得到输入流
out = new ByteArrayOutputStream();//得到字节数组输出流
while (true){
readByte();
}
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void readByte() throws IOException {
int ch=0;
while ((ch=in.read())!=-1){
if(lastHitCount!=hitCount){
out.close();
out = new ByteArrayOutputStream();//得到字节数组输出流
}
out.write(ch);
content = out.toByteArray();
EventBus.getDefault().post(new BluRxBean(RECEIVER_MESSAGE_Byte,content));
lengthOutput=content.length;
Log.d("接收数据长度:" , content.length+"");
lastHitCount=hitCount;
}
}
到此重点差不多就完了,具体代码可下载看:
链接:https://pan.baidu.com/s/1o7VcQmHj78BcpDld776Bmg
提取码:ntax