Android:能接收HC05数据的APP
Posted Z|Star
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android:能接收HC05数据的APP相关的知识,希望对你有一定的参考价值。
android的更新速度太快,以至于目前搜到的很多蓝牙APP的源码都无法使用。花了三天时间,终于实现了蓝牙app的基本功能。
1.项目需求
本项目需要制作一款APP,实现手机蓝牙和HC-05蓝牙模块连接,接收来自单片机的数据,并在APP页面上进行实时显示。
2.效果展示
这里只为测试APP的性能,因此将HC-05接TTL转USB模块,连接电脑,通过串口工具XCOM发送信息。
测试手机系统:Android 10
(由于gif太大传不上来,因此仅展示图片)
3.工程结构
4.核心代码
4.1蓝牙打开、关闭、搜索
/**
* 检测和开启蓝牙
*/
private void openBluetooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
//判断蓝牙是否打开并可见
if (!mBluetoothAdapter.isEnabled()) {
//请求打开并可见
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,1);
mToast.showToast("蓝牙已打开");
}
else{
mToast.showToast("蓝牙已经打开");
}
}else{
mToast.showToast("设备不支持蓝牙功能");
}
}
/**
* 关闭蓝牙
*/
private void closeBluetooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
//判断蓝牙是否打开并可见
if (mBluetoothAdapter.isEnabled()) {
//请求关闭
mBluetoothAdapter.disable();
mToast.showToast("蓝牙已关闭");
}
else{
mToast.showToast("蓝牙已经关闭");
}
}else{
mToast.showToast("设备不支持蓝牙功能");
}
}
/**
* 搜索蓝牙设备
*/
private void discoverBluetooth(){
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
//搜索设备
mBluetoothAdapter.startDiscovery();
mToast.showToast("正在搜索设备");
}
4.2蓝牙搜索,适配器显示
MyArrayAdapter
public class MyArrayAdapter extends BaseAdapter {
private final List<DeviceInformation> mDatas;
private final Context mContext;
public MyArrayAdapter(List<DeviceInformation> mDatas, Context mContext) {
this.mDatas = mDatas;
this.mContext = mContext;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Object getItem(int i) {
return mDatas.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.device_item_layout,null);
}
TextView nameTv = view.findViewById(R.id.device_name);
TextView addressTv = view.findViewById(R.id.device_address);
DeviceInformation deviceInformation = mDatas.get(i);
nameTv.setText(deviceInformation.getDeviceName());
addressTv.setText(deviceInformation.getDeviceAddress());
return view;
}
}
扫描显示
private void initReceiver() {
//创建用于接收蓝牙状态改变广播的广播接收者
mBLuetoothStateReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
switch (state){
case BluetoothAdapter.STATE_ON:
mToast.showToast("蓝牙已打开");
break;
case BluetoothAdapter.STATE_OFF:
mToast.showToast("蓝牙已关闭");
break;
case BluetoothAdapter.STATE_TURNING_ON:
mToast.showToast("蓝牙正在打开");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
mToast.showToast("蓝牙正在关闭");
break;
}
}
};
//创建设备扫描广播接收者
mBluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"onReceive");
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
boolean isAdded = false;//标记扫描到的设备是否已经在数据列表里了
//获取扫描到的设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//保存设备的信息
DeviceInformation deviceInformation = new DeviceInformation(device.getName(),device.getAddress());
for (DeviceInformation data : mDatas) {
//判断已保存的设备信息里是否有一样的
if (data.getDeviceAddress().equals(deviceInformation.getDeviceAddress())) {
isAdded = true;
break;
}
}
if (!isAdded) {
//通知UI更新
mDatas.add(deviceInformation);
mAdapter.notifyDataSetChanged();
}
}
}
};
//注册广播接收者
IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBLuetoothStateReceiver,filter1);
registerReceiver(mBluetoothReceiver,filter2);
}
//权限是否授予,给出提示
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_CONSTANT: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mToast.showToast("权限授权成功");
}else{
mToast.showToast("权限授权失败");
}
return;
}
}
}
4.3建立连接
/**
* 与目标设备建立连接
*/
private void connectDevice() {
//获取默认蓝牙设配器
mBlueToothAdapter = BluetoothAdapter.getDefaultAdapter();
//通过地址拿到该蓝牙设备device
mDevice = mBlueToothAdapter.getRemoteDevice(mAddress);
try {
//建立socket通信
mBluetoothSocket = mDevice.createRfcommSocketToServiceRecord(mUUID);
mBluetoothSocket.connect();
if (mBluetoothSocket.isConnected()) {
mToast.showToast("连接成功");
//开启接收数据的线程
ReceiveDataThread thread = new ReceiveDataThread();
thread.start();
}else{
mToast.showToast("连接失败,结束重进");
}
} catch (IOException e) {
e.printStackTrace();
mToast.showToast("连接出错! ");
finish();
try {
mBluetoothSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
if (mBluetoothSocket.isConnected()) {
//关闭socket
mBluetoothSocket.close();
mBlueToothAdapter = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
4.4创建线程,传输数据
/**
* 负责接收数据的线程
*/
public class ReceiveDataThread extends Thread{
private InputStream inputStream;
public ReceiveDataThread() {
super();
try {
//获取连接socket的输入流
inputStream = mBluetoothSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
super.run();
while (true){
try {
//每次运行需新生成一个
byte[] buffer = new byte[16];
inputStream.read(buffer);
String a = new String(buffer,0,buffer.length);
runOnUiThread(new Runnable() {
@Override
public void run() {
//将收到的数据显示在TextView上
mReceiveContent.append(a);
//System.out.println(a);
/**
* 注:inputStream控制固定字节读入时并不稳定,读入数据容易出现漏读情况,因此采用其它方法来更新数据
* 在每次UI线程中,获取收到数据的最后一行,即最新数据,截取出来进行显示
* 由于append会自动换行,因此line_num-2
*/
Layout layout = mReceiveContent.getLayout();
String text = mReceiveContent.getText().toString();
int line_num = layout.getLineCount();
int start = layout.getLineStart(line_num - 2);
int end = layout.getLineEnd(line_num - 2);
String line = text.substring(start, end);
//实时将数据显示更新,这里后期根据单片机数据进行修改
mid.setText(line);
mtemp.setText(line);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.完整源码
6.参考资料
以上是关于Android:能接收HC05数据的APP的主要内容,如果未能解决你的问题,请参考以下文章
QT应用编程: 编写HC05串口蓝牙调试助手(Android系统APP)