Android实现蓝牙串口通讯
作者:Roy?Mustang· 发布时间:2023-03-19 09:22:21
标签:Android,蓝牙,串口通讯
本文实例为大家分享了Android实现蓝牙串口通讯的具体代码,供大家参考,具体内容如下
最近在弄蓝牙串口,参考了不少网上的大佬,加上自己早期对C#的学习,写一个给自己的备忘录,如果有大佬看到还请多多指教。
1.简介
Android设备中提供了一整套蓝牙的API,我这边只取了其中需要的部分。
初期权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
1.BluetoothAdapter
BluetoothAdapter是本地蓝牙适配器的对象,是所有蓝牙交互操作的入口。
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
?
?
private BluetoothAdapter mBluetoothAdapter = null;
public ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
?
?
// 初始化蓝牙
private void BlueInit()
{
?? ?// 获取蓝牙适配器
?? ?mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
?? ?// 请求开启蓝牙
?? ?if (!mBluetoothAdapter.isEnabled())?
?? ?{
?? ??? ?Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
?? ??? ?((Activity)_context).startActivityForResult(enableBtIntent, 1);
?? ?}
}
这里我只获取了已经匹配好的蓝牙模块,Android本身自带搜索匹配蓝牙设备功能。太麻烦了,还有匹配,还要输PIN码。
直接搜索已经匹配的蓝牙模块。
2.BluetoothDevice
表示远程的蓝牙设备可进行远程蓝牙设备的连接请求,以及查询该蓝牙设备的信息,例如名称,地址等。
protected void onResume()?
{
?? ?// 将已配对的设备添加到列表中
?? ?Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
?? ?deviceList.clear();
?? ?if (pairedDevices.size() > 0)?
?? ?{
?? ??? ?String[] nameList = new String[pairedDevices.size()];
?? ??? ?int i=0;
?? ??? ?for (BluetoothDevice device : pairedDevices)
?? ??? ?{
? ? ? ? ? ? ? ?deviceList.add(device);
?? ??? ??? ?nameList[i] = device.getName() + "\n" + device.getAddress();
?? ??? ??? ?i++;
??? ?}
?? ??? ?//创建一个ArrayAdapter
?? ??? ?ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList);
?? ??? ?DeviceView.setAdapter(adapter);
?? ??? ?//注册一个元素单击事件监听方法
?? ??? ?DeviceView.setOnItemClickListener(new DeviceClick());
?? ?}
}
然后直接返回给主窗体
//事件按钮触发
public class DeviceClick implements AdapterView.OnItemClickListener?
{
?? ?@Override
?? ?public void onItemClick(AdapterView<?> arg0, View view, int position, long id)?
?? ?{
?? ??? ?onConfirmListener.confirm(deviceList.get(position));
?? ?}
??? ??? ?
}
public interface OnConfirmListener?
{
? ? public void confirm(BluetoothDevice device);
}
这里其实用了一个Activity的作为一个Dialog。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
? ? xmlns:tools="http://schemas.android.com/tools"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? android:paddingBottom="@dimen/activity_vertical_margin"
? ? android:paddingLeft="@dimen/activity_horizontal_margin"
? ? android:paddingRight="@dimen/activity_horizontal_margin"
? ? android:paddingTop="@dimen/activity_vertical_margin"
? ? tools:context="bluetoothtoserial.DeviceActivity" >
?
? ? <ListView
? ? ? ? android:id="@+id/DeviceView"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="match_parent"
? ? ? ? android:layout_alignParentLeft="true"
? ? ? ? android:layout_alignParentTop="true" >
? ? </ListView>
</RelativeLayout>
也是方便后面调用
package bluetoothtoserial;
?
import java.util.ArrayList;
import java.util.Set;
import android.app.Activity;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
?
public class DeviceActivity extends Dialog?
{
?? ?Context _context;
? ? public OnConfirmListener onConfirmListener;
?? ?private ListView DeviceView;
?? ?private BluetoothAdapter mBluetoothAdapter = null;
?? ?public ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
?
?? ?public DeviceActivity(Context context)?
?? ?{
?? ??? ?super(context);
?? ??? ?this._context = context;
?? ??? ?// TODO Auto-generated constructor stub
?? ?}
?? ?@Override
?? ?protected void onCreate(Bundle savedInstanceState)?
?? ?{
?? ??? ?super.onCreate(savedInstanceState);
?? ??? ?setContentView(R.layout.activity_device);
?? ??? ?DeviceView = (ListView)findViewById(R.id.DeviceView);
?? ??? ?BlueInit();
?? ??? ?onResume();
?? ?}
?? ?// 初始化蓝牙
?? ?private void BlueInit()
?? ?{
?? ??? ?// 获取蓝牙适配器
?? ??? ?mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
?? ??? ?// 请求开启蓝牙
?? ??? ?if (!mBluetoothAdapter.isEnabled())?
?? ??? ?{
?? ??? ??? ?Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
?? ??? ??? ?((Activity)_context).startActivityForResult(enableBtIntent, 1);
?? ??? ?}
?? ?}
?? ?protected void onResume()?
?? ?{
?? ??? ?// 将已配对的设备添加到列表中
?? ??? ?Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
?? ??? ?deviceList.clear();
?? ??? ?if (pairedDevices.size() > 0)?
?? ??? ?{
?? ??? ??? ?String[] nameList = new String[pairedDevices.size()];
?? ??? ??? ?int i=0;
?? ??? ??? ?for (BluetoothDevice device : pairedDevices)
?? ??? ??? ?{
? ? ? ? ? ? ? ? deviceList.add(device);
?? ??? ??? ??? ?nameList[i] = device.getName() + "\n" + device.getAddress();
?? ??? ??? ??? ?i++;
?? ??? ??? ?}
?? ??? ??? ?//创建一个ArrayAdapter
?? ??? ??? ?ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList);
?? ??? ??? ?DeviceView.setAdapter(adapter);
?? ??? ??? ?//注册一个元素单击事件监听方法
?? ??? ??? ?DeviceView.setOnItemClickListener(new DeviceClick());
?? ??? ?}
?? ?}
?? ?//事件按钮触发
? ?? ?public class DeviceClick implements AdapterView.OnItemClickListener?
? ?? ?{
?? ??? ?@Override
?? ??? ?public void onItemClick(AdapterView<?> arg0, View view, int position, long id)?
?? ??? ?{
?? ??? ??? ?onConfirmListener.confirm(deviceList.get(position));
?? ??? ?}
? ?? ??? ?
? ?? ?}
? ?? ?public interface OnConfirmListener?
? ? {
? ? ? ? public void confirm(BluetoothDevice device);
? ? }
}
3.BluetoothSocket
BluetoothSocket 蓝牙的socket接口,与TCP Socket类似,设备添加完成可以开始连接设备。
这里我直接写了一个Session通讯类
package Channel;
?
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
?
public class Session extends Thread?
{
?? ?private BluetoothDevice _device = null;
?? ?private BluetoothSocket _socket = null;
?? ?private OutputStream _outStream;
?? ?private InputStream _inStream = null;?
?? ?public boolean IsConnect = false;
?? ?public String Name="";
?? ?public String Address="";
?? ?Handler _handler;
?? ?public Session(BluetoothDevice _device,Handler _handler)
?? ?{
?? ??? ?this._handler = _handler;
?? ??? ?this._device = _device;
?? ??? ?this.Name = this._device.getName();
?? ??? ?this.Address = this._device.getAddress();
?? ??? ?IsConnect = false;
?? ??? ?try?
? ?? ??? ?{
? ?? ??? ? ? ?// 蓝牙串口服务对应的UUID。如使用的是其它蓝牙服务,需更改下面的字符串
? ? ? ? ? ? // UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
? ?? ??? ? ? ?_socket = _device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
? ?? ??? ?} catch (Exception e)?
? ?? ??? ?{
? ?? ??? ? ? ?return;
? ?? ??? ?}
?? ?}
?? ?public void connect()
?? ?{
?? ??? ?try?
?? ??? ?{
?? ??? ??? ?_socket.connect();
?? ??? ??? ?_outStream = _socket.getOutputStream();
?? ??? ??? ?_inStream = _socket.getInputStream();
?? ??? ??? ?IsConnect = true;
?? ??? ?}
?? ??? ?catch (IOException e)?
?? ??? ?{
?? ??? ??? ?IsConnect = false;
?? ??? ??? ?try {
?? ??? ??? ??? ?_socket.close();
?? ??? ??? ?} catch (IOException e1)?
?? ??? ??? ?{
?? ??? ??? ?}
? ?? ??? ? ? ?return;
?? ??? ?}
?? ?}
?? ?@Override
?? ?public void run()?
?? ?{ ?
?? ??? ?byte [] buffer = new byte [1024];
?? ??? ?int len = 0;
?? ??? ?while(true)?
?? ??? ?{
?? ??? ??? ? //从InputStream读取
?? ??? ??? ?try?
?? ??? ??? ?{
?? ??? ??? ??? ?len = _inStream.read(buffer);
?? ??? ??? ?} catch (IOException e)?
?? ??? ??? ?{
?? ??? ??? ??? ?continue;
?? ??? ??? ?}
? ? ? ? ? ? if(len> 0)
? ? ? ? ? ? {?
? ? ? ? ? ? ?? ?Message msg = _handler.obtainMessage();
? ? ? ? ? ? ?? ?msg.what = 0;?
? ? ? ? ? ? ?? ?try?
? ? ? ? ? ? ?? ?{
?? ??? ??? ??? ??? ?msg.obj=new String(buffer,"UTF-8");
?? ??? ??? ??? ?} catch (UnsupportedEncodingException e)?
? ? ? ? ? ? ?? ?{
?? ??? ??? ??? ?}
? ? ? ? ? ? ?? ?_handler.sendMessage(msg);
? ? ? ? ? ? }
?? ??? ?}
?? ?}
?? ?public void Send(String _value) throws IOException
?? ?{
?? ??? ?_outStream.write(_value.getBytes());
?? ?}
?? ?public void Close() throws IOException
?? ?{
?? ??? ?IsConnect = false;
?? ??? ?_socket.close();
?? ?}
}
接下来就是使用,弹窗选择设备。
public void btnDevice_Click(View v)//选择设备
{
?? ?final DeviceActivity _deviceDialog = new DeviceActivity(this);
?? ?_deviceDialog.onConfirmListener = new ?OnConfirmListener()?
?? ?{
? ? ? ? @Override
? ? ?? ?public void confirm(BluetoothDevice device)
?? ??? ?{
?? ??? ??? ?_device = device;
?? ??? ??? ?txtDevice.setText(device.getName()+"\n"+device.getAddress());
?? ??? ??? ?_deviceDialog.dismiss();
?? ??? ??? ?btnConnect.setText("连接设备");
?? ??? ??? ?btnConnect.setVisibility(View.VISIBLE);
?? ??? ??? ?btnSend.setVisibility(View.INVISIBLE);
?? ??? ?}
?? ?};
?? ?_deviceDialog.show();
}
选择完设备,建立Session连接设备。
public void btnConnect_Click(View v)//连接设备
{
? ?? ?_session = new Session(_device,_handler);
? ?? ?setTitle(_session.Name);
? ?? ?_session.connect();
? ?? ?if (_session.IsConnect)
? ?? ?{
? ?? ??? ?_session.start();
? ?? ??? ?btnConnect.setVisibility(View.INVISIBLE);
? ?? ??? ?btnSend.setVisibility(View.VISIBLE);
? ?? ??? ?btnSend.setText("发送消息");
?? ?}
? ?? ?else
? ?? ?{
? ?? ??? ?Toast.makeText(MainActivity.this,
? ?? ??? ??? ??? ?"连接失败",
? ?? ??? ??? ??? ?Toast.LENGTH_LONG).show();
? ?? ??? ?btnSend.setVisibility(View.INVISIBLE);
?? ?}
}
建立回调函数。
Handler _handler=new Handler(Looper.getMainLooper())
{
? ? @Override
?? ?public void handleMessage(Message msg)
?? ?{
?? ??? ?super.handleMessage(msg);
?? ??? ?edxMessage.setText(edxMessage.getText()+"\n"+msg.obj);
?? ?}
};
发送消息。
public void btnSend_Click(View v)//发送消息
{
? ?? ?try
? ?? ?{
?? ??? ?_session.Send(edxContent.getText().toString());
?? ?} catch (IOException e)?
? ?? ?{
?? ? ? ?Toast.makeText(MainActivity.this,
? ?? ??? ??? ??? ?"发送失败",
? ?? ??? ??? ??? ?Toast.LENGTH_LONG).show();
?? ?}
}
基本上操作就这些。
来源:https://blog.csdn.net/fjyexu/article/details/120831832


猜你喜欢
- 走马灯是一种常见的效果,本文讲一下如何用 PageView 在 Flutter 里实现一个走马灯, 效果如下,当前页面的高度比其它页面高,切
- 废话不多说,直接上代码: 很简单:将类复制到项目中,最后在配置文件上配置一下:logUrl即可。 默认保存在:项目/temp/lo
- Java 表格数据导入word文档中个人觉得这个功能实在搞笑,没什么意义,没办法提了需求就要实现,(太好说话了把我)我的实现是再word中生
- 建造者模式针对的是复杂对象的构建,比如一个产品有多个部分构成,每个部分都可以单独进行生产,这时候就可以用建造者模式,由Builder构造产品
- jar包就指第三方提供的开源的API,这些API不属于JDK的,需要通过导入才能使用。添加和导入的区别注意:本文里的 导入 和 添加 jar
- 简介本文用示例介绍使用MyBatis-Plus进行多表查询的方法,包括静态查询和动态查询。代码controllerpackage com.e
- 猜数字游戏你在和朋友一起玩 猜数字(Bulls and Cows)游戏,该游戏规则如下:写出一个秘密数字,并请朋友猜这个数字是多少。朋友每猜
- 一、简介   Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布
- 当我们右键点击listview控件时,可以得到选择的项的各个文本内容。现在我们要求只获取右键点击时的单元格的文本内容。方法如下:1、定义全局
- 目录1、一个抽象类并不需要其中所有的方法都是抽象的。( )2、下列程序的运行结果3、在Java中,关于HashMap类的描述,以下错误的是(
- 1、先使用tiledmap编辑地图,图层用来刷图块,对象用来定义单个格子的数据2、为每个图块调属性 3、图块需要单独配置属性的就必
- 1、导包,四大核心包,一个切面包(AOP),logging,web,springmvc2、配置文件,核心代码如下:web.xml<se
- Android开发过程中,特别是新开的项目,底部状态栏的切换使用的频率非常的高,主要的实现方式有:(1)、TabLayout + Fragm
- 本文是针对AndBase框架学习整理的第二篇笔记,想要了解AndBase框架的朋友可以阅读本文,大家共同学习。使用AbActivity内部封
- 最近项目里面用到了一个日期选择器,实现现在主流的WheelView滑动选择,整理了下,做了个Demo.废话不多说,直接上代码.主布局:act
- SpringBoot找不到映射文件org.apache.ibatis.binding.BindingException: Invalid b
- 本文实例为大家分享了视频播放器的两种方式,供大家参考,具体内容如下1)、SurfaceView在布局文件中<?xml version=
- 创建个SpringBoot项目勾选生所需的依赖:我把application的后缀改为.yml了,方便些。 pom.xml:<?xml
- 背景我们都知道http协议只能在浏览器单方面向服务器发起请求时获得响应,然而服务器不能主动向浏览器推送消息,想要实现浏览器的主动推送目前有两
- 一、概述运行时变更就是设备在运行时发生变化(例如屏幕旋转、键盘可用性及语言)。发生这些变化,Android会重启Activity,这时就需要