基于经典蓝牙的安卓蓝牙开发-串口

一、展现广播的三种方式
1、通知; 2、对话框; 3、消息提示框
2、在使用Android蓝牙适配器中的startDiscovery需要先打开定位服务
3、在连接蓝牙之前,还要先取消蓝牙设备的扫描,否则容易连接失败

前段时间自己学做了一个基于安卓经典蓝牙的app,也遇到不少坑,在网上相对与BLE低功耗蓝牙来说,它的资料方面都是比较缺少的,而且网上经典蓝牙源码大部分都很长,对于入门的同学来说,看没两分钟就产生放弃的念头了。

第一步:在AndroidManifest中添加:

<!--管理蓝牙需要-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!--搜索蓝牙需要,因为蓝牙可以被用来定位,所以需要定位权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

上面都是我们使用到设备功能的权限申请。

第二步:设置两个按钮分别是打开和关闭蓝牙
对蓝牙设备干事情,那么我们就得拿到它的接口来控制它

//获取蓝牙适配器
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

打开蓝牙:
1、

public void OpenBlueTooth(View view) {if(isSupportBlueTooth() == true) {if(!BlueToothState()) {Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(intent,0);showToast("亲,打开了噢!需要什么帮助吗?");}else {showToast("亲,已经打开了噢,无需重复打开。");}}else {showToast("亲,您不支持此蓝牙设备!");}
}

2、打开蓝牙应该先确定使用的手机是否支持蓝牙设备(手机没有就没必要进行下一步了)

//判断是否支持蓝牙
public boolean isSupportBlueTooth() {if(mBluetoothAdapter != null) {return true;}else {return false;}
}

3、然后打开前还需要知道手机是否打开蓝牙了吧!那就获取手机现在蓝牙设备的状态

//获取蓝牙状态
public  boolean BlueToothState() {assert (mBluetoothAdapter != null);   //若不支持该蓝牙设备会有个断言return mBluetoothAdapter.isEnabled();
}

2、3小步骤都只是个函数功能体,都是为1、步骤使用的,初学者会疑惑什么是断言,就是做判断,真的那么下面就不执行咯!还有下面是是一个消息对象,
获取用户对蓝牙适配器申请打开的请求消息,使用startActivityForResult对消息做出应答,会有对话框的提示效果

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,0);

关闭蓝牙:

public void CloseBlueTooth(View view) {mBluetoothAdapter.disable();showToast("亲,我们会再见面的!");
}

先说明一点我这里的还是都在有View view形参接口,这是一个动作的监听接口,下图有设置的图片,这里设置就可以了。

感觉打开蓝牙和关闭蓝牙挺简单的吧!
难度开始来了噢!

第三步:
打开了蓝牙我们就得弄一个来搜索周围的设备吧!
下面是一个定义好的搜索蓝牙函数

public void startDiscovery() {if (mBluetoothAdapter.isDiscovering()) {mBluetoothAdapter.cancelDiscovery();  Toast.makeText(this,"搜索器打开",Toast.LENGTH_SHORT).show();}mBluetoothAdapter.startDiscovery();if (!mBluetoothAdapter.isDiscovering()) {Toast.makeText(this,"搜索器没打开",Toast.LENGTH_SHORT).show();}
}

有点看不懂吗,其实还好吧,就是第一次判断是否开启搜索周围蓝牙设备,开启了就把它关了,重新打开在搜索,在判断我是否开启了搜索没。(isDiscovery是开启搜索,cancelDiscovery是关闭搜索的意思)
有搜索蓝牙设备函数了,我们就搞一个按键让其有触发效果吧!

//按钮搜寻蓝牙
Button button_discovery = (Button) findViewById(R.id.DiscoveryBT);
button_discovery.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startDiscovery();}
});

开启了搜索蓝牙设备我们得有东西接收这些设备吧,不然它偷偷摸摸搜索鬼知道它搜了什么东西。那我们就得用广播把这些偷偷摸摸搜索到了设备把它弄出来,放进“箱子”里。
这就是我们定义的广播接收器

public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if(intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {Toast.makeText(context, "开始", Toast.LENGTH_SHORT).show();} else if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//创建搜索蓝牙列表的///for (int i = 0; i < deviceAdress.size(); i++) {if (deviceAdress.get(i).getAddress().equals(device.getAddress())) return;//上面if语句就是去除已经获取的蓝牙设备}// 不是重复的就添加到列表中(获取未配对的蓝牙设备)deviceAdress.add(device);  //添加地址到列表中   用于鉴别是否已经添加列表和点击事件用的deviceName.add("地址:"+device.getAddress()+"\n"+"名称:"+device.getName());  //存放蓝牙名称和地址用于显示到列表上的} else if(intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {}}
}

代码都有注释我就不一一说明了,说一下箱子要在外面定义

public ArrayList<BluetoothDevice> deviceAdress = new ArrayList<>();  //存放蓝牙设备(这里Adress我忘了改过来了,这是存放设备不是设备地址)
public ArrayList<String> deviceName = new ArrayList<>();  //存放蓝牙名称和地址

然后就是用广播类里面用if那些进行信息筛选(用蓝牙设备这个方法获取设备的信息BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
然后就是把搜索到的device
你可以用Toast.make()打印一下信息看看效果
记得广播接收器的使用一定要注册广播接收器,不然就废掉了

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);//发现蓝牙
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索停止
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED );//搜索启动
//上面是添加动作事件
//注册广播接收者的对象
registerReceiver(myReceiver,intentFilter);

都放在箱子里了,我们应该把它拿出来一个一个展示一下吧!

这展示的方法就是用列表把它展示出来:

public ListView listView;   //定义展示列表//创建搜索蓝牙列表的///并把
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1,deviceName);  //实例化ArrayAdapter对象deviceName集合数据放入arrayAdapter适配器集合内
listView = (ListView) findViewById(R.id.list);  //获取列表框的
listView.setAdapter(arrayAdapter);  //将arrayAdapter集合内的数据加载到列表框 就是适配器对象与ListView关联
这样放进列表你以为就可以了吗,你怎么知道它加载了多少个已发现的设备呢?这需要我们到广播接收器这个线程中间断刷新载入新设备
arrayAdapter.notifyDataSetChanged();  //更新列表
下面是我定义的一个刷新列表搜索Button button= (Button) findViewById(R.id.Broadcast);  //获取布局文件中的广播按钮button.setOnClickListener(new View.OnClickListener() { //为按钮设置单击事件@Overridepublic void onClick(View v) {//蓝牙刷新///deviceAdress.clear();         //deviceName.clear();           //startDiscovery();             //}});

到现在你就可以试试你做的可不可以将搜索到的蓝牙加载到列表中显示了,可以的化,看看可不可以刷新列表。

第四步:
把我们列表中的设备能进行点击触发

    //连接蓝牙public void Connect_BT(ArrayList<BluetoothDevice> deviceAdress) {//MainActivity 实现OnItemClickListener 然后重写方法listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {BluetoothDevice clickDevice = (BluetoothDevice)deviceAdress.get(position);String s1 = String.valueOf(position);  //编号Toast.makeText(MainActivity.this, s1 + "--" + clickDevice.getName() + "--" + clickDevice.getAddress(), Toast.LENGTH_SHORT).show();//在连接前需要先关闭搜索}});}

把我们列表按键触发这个类放到广播接收器这个线程中

Connect_BT(deviceAdress);
```c
按下列表就有这个提示框咯!开心吧第五步:
连接我们选中的蓝牙
连接这些蓝牙都需要协议的,都是厂家底层工作人员定好的
<font color=#999AAA >
```c
//手机连接的UUID
//设备连接的UUID由厂商决定。
private final String BLUETOOTH_UUID = "00001101-0000-1000-8000-00805F9B34FB";   //蓝牙通信的UUID,必须为这个,如果换成其他的UUID会无法通信
private BluetoothSocket bluetoothSocket = null;
UUID我就步详细说了,你们自行百度。BluetoothSocket套接字就是连接蓝牙服务器用的。
在Connect_BT添加下面代码即可()//在连接前需要先关闭搜索//点击列表,去请求服务器if (clickDevice != null) {new Thread(new Runnable() {@Overridepublic void run() {try {bluetoothSocket = clickDevice.createRfcommSocketToServiceRecord(UUID.fromString(BLUETOOTH_UUID));bluetoothSocket.connect();} catch (IOException e) {e.printStackTrace();}}}).start();}

这我要说明一下connect方法会阻塞线程,我们需要在下面创建一个子线程来运行,不然程序奔溃别找我就可以了。
到这我们就所有基本弄好了

第五步:
接收和发送数据
这里我略微讲一下

// 用来收数据
InputStream inputStream = bluetoothSocket.getInputStream();
// 用来发数据
OutputStream outputStream;
下面是我用按键发送数据的代码(参考)
Button button_oc3 = (Button) findViewById(R.id.button_open_close3);
button_oc3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String text = "d12";try {outputStream = bluetoothSocket.getOutputStream();outputStream.write(text.getBytes());outputStream.flush();} catch (IOException e) {e.printStackTrace();}}
});

读取数据这部分代码是我后面做项目把这个小实验拿过来用的时候添加的

    /*** 读取数据*/private class readThread extends Thread {public void run() {byte[] buffer = new byte[1024];int bytes;InputStream is = null;try {is = bluetoothSocket.getInputStream();textView_receive.setText("客户端:获得输入流");} catch (IOException e1) {e1.printStackTrace();}while (true) {try {if ((bytes = is.read(buffer)) > 0) {byte[] buf_data = new byte[bytes];for (int i = 0; i < bytes; i++) {buf_data[i] = buffer[i];}s = new String(buf_data);//textView_receive.setText("客户端:读取数据了");if(state==1) {readThread.sleep(3000);textView_receive.setText("读取的数据:\n" + s);}}} catch (IOException e) {try {is.close();} catch (IOException e1) {e1.printStackTrace();}break;} catch (InterruptedException e) {e.printStackTrace();}}}

上面读数据代码我们要将它放在连接蓝牙后开启读线程

我这里没有加判断是否连接成功,严谨一点的话要加个判断语句。这里我修复了一下发送、开关闪退的原因,原因是因为没有在连接蓝牙后才能使能这些操作,之前没连接直接用是会闪退的。
记住完成BluetoothSocket的一系列操作后,记住用close()方法关闭套接字噢,不然手机很耗电,烧坏别找我麻烦。
接收数据的话会比较麻烦一点点,需要用一个线程和while死循环继续时刻接收(因为InputStream 也会阻塞线程的)
到这就告一段落了。
我有一个老师是这样说过的游戏打累了就休息一下,休息的方法就是敲代码。

在社会学到的要学会分享回报社会

QQ:1411471554(有什么好的想法和建议可以分享一下给我)
广州大学华软软件学院djw

第一次玩这东西不太懂,有待学习哈~
这下面是源码和开发过程文档
链接:https://pan.baidu.com/s/19K2QCr1HIbAg2OBaJDCbNQ
提取码:1234
复制这段内容后打开百度网盘手机App,操作更方便哦

基于经典蓝牙的安卓蓝牙APP开发(基于蓝牙2.0开发,例:HC-05)相关推荐

  1. 安卓毕业设计app项目基于Uniapp+SSM实现的安卓的掌上校园系统食堂缴费图书馆预约

    目录 一.项目介绍 二.开题报告 三.截图 四.源码获取 一.项目介绍 计算机毕业设计安卓App毕设项目之ssm基于安卓的掌上校园系统-IT实战课堂_哔哩哔哩_bilibili计算机毕业设计安卓App ...

  2. 安卓毕业设计app项目基于Uniapp+SSM实现的家庭账单财务APP

  3. 安卓毕业设计app项目-基于Uniapp+SSM实现的日常饮食美食菜谱管理

  4. 安卓毕业设计app项目基于Uniapp+SSM实现的移动端的酒店餐饮住宿订餐点餐管理系统

     

  5. crashlands中文安卓下载_崩溃大陆中文版下载_崩溃大陆中文版安卓版APP下载手机版v100.0.62 - 42824手游下载站...

    崩溃大陆中文版是一款有着各种元素的冒险手游,游戏中充满了大量的怪物,玩家需要生存,那么就必须战斗下去,不要退缩,疯狂的对决就在这里进行,胜利终将属于你. 崩溃大陆中文版介绍 全新冒险开始了,数不清的怪 ...

  6. PyQt5 “PyTuning“调试软件从0开发总结

    PyQt5 "PyTuning"调试软件从0开发总结 北航3系大四要调小车在赛道上跑,小车单片机用的K60,老师提供的代码里还有串口收发的库,就想着用蓝牙模块再开发上位机调试软件进 ...

  7. Qt安卓app开发,蓝牙通信调试助手,经典蓝牙通信调试工具

    目录 软件说明 app界面 源码下载地址 软件说明 1.基于Qt开发,QBluetoothSocket通信: 2.开/关蓝牙.搜索/停止搜索设备.Ascii/Hex收发.收发延迟设置.收发计数等功能: ...

  8. ESP32与APP通信--基于MicroPythone的BLE蓝牙篇

    基于ESP32的低功耗蓝牙程序 1,编译环境搭建:基于MicroPython的ESP32环境搭建 2,代码直接复制 """ The MIT License (MIT) C ...

  9. 基于intel芯片的安卓蓝牙4.0 BLE通信总结

    基于intel芯片的安卓蓝牙4.0 BLE通信问题总结 使用设备: 台电 x98 air 3G 系统:安卓4.4.4 系统搭建: 1.安装ADT驱动,可以搜索intel_mobile_usb_driv ...

最新文章

  1. tp数组转为json_数据存储—JSON
  2. 中科院张士峰:基于深度学习的通用物体检测算法对比探索
  3. 文轩在线:如何让IT部门成为企业的价值中心
  4. 使用元数据设计测试用例
  5. 在html中怎么制作友情链接,如何制作一个网页链接,用描文本、友情链接交易方式教你如何制作?...
  6. Android—OkHttp同步异步请求过程源码分析与拦截器
  7. dotnet若干说明图片
  8. WIN7 Wireshark: There are no interfaces on which a capture can be done
  9. 循环体中调用[NSString stringWithFormat:@%@,Object] 方法的内存问题
  10. rz安装 xshell_在Linux系统中安装rzsz工具
  11. el-table对于超出长度限制的文本的处理(vue-cli)
  12. 新浪微博自动化运维平台实践
  13. SpringBoot自动装配原理,这一篇就够了!
  14. 若邻网络结盟职友集,共创人脉网络与职位搜索结合的求职新模式
  15. 马步站桩22个要领的几个关键问题解释
  16. antdesign 柱状图_你绝对想不到柱形图背后有这么多故事
  17. 流年祭.掩埋一场与青春有关的荒芜
  18. Learning Image Conditioned Label Space for Multilabel Classification
  19. H.264码流的分析
  20. 麦克斯韦方程的积分形式及应用、麦克斯韦方程组的微分形式及应用

热门文章

  1. centos 7 opera 安装flash player
  2. java // for // 俄文字母表
  3. 软件测试中 Bug 书写规范
  4. ORA-ALL Oracle连接报错
  5. ARM处理器指令集(精简指令集)
  6. 在线作图|如何在线画一张精美的和弦图
  7. 主流报表开发工具FastReport.Net全新发布,邀您体验最新版试用
  8. matlab鱼眼镜头,普通镜头,单目双目相机标定校正(四)
  9. 网络能看到计算机 但是进不去,共享文件夹 在网络邻居看到别人的电脑 进不去...
  10. c语言刷题(牛客网)