蓝牙是一种支持设备短距离传输数据的无线技术。android在2.0以后提供了这方面的支持。
从查找蓝牙设备到能够相互通信要经过几个基本步骤(本机做为服务器):
1.设置权限
在manifest中配置
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
2.启动蓝牙
首先要查看本机是否支持蓝牙,获取BluetoothAdapter蓝牙适配器对象
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
//表明此手机不支持蓝牙
return;
}
if(!mBluetoothAdapter.isEnabled()){ //蓝牙未开启,则开启蓝牙
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
//......
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == REQUEST_ENABLE_BT){
if(requestCode == RESULT_OK){
//蓝牙已经开启
}
}
}
3。发现蓝牙设备
这里可以细分为几个方面
(1)使本机蓝牙处于可见(即处于易被搜索到状态),便于其他设备发现本机蓝牙
//使本机蓝牙在300秒内可被搜索
private void ensureDiscoverable() {
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
(2)查找已经配对的蓝牙设备,即以前已经配对过的设备
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
//device.getName() +" "+ device.getAddress());
}
} else {
mPairedDevicesArrayAdapter.add("没有找到已匹对的设备");
}
(3)通过mBluetoothAdapter.startDiscovery();搜索设备,要获得此搜索的结果需要注册
一个BroadcastReceiver来获取。先注册再获取信息,然后处理
//注册,当一个设备被发现时调用onReceive
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
//当搜索结束后调用onReceive
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
//.......
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 已经配对的则跳过
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); //保存设备地址与名字
}
}else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { //搜索结束
if (mNewDevicesArrayAdapter.getCount() == 0) {
mNewDevicesArrayAdapter.add("没有搜索到设备");
}
}
}
};
4.建立连接
查找到设备 后,则需要建立本机与其他设备之间的连接。
一般用本机搜索其他蓝牙设备时,本机可以作为一个服务端,接收其他设备的连接。
启动一个服务器端的线程,死循环等待客户端的连接,这与ServerSocket极为相似。
这个线程在准备连接之前启动
//UUID可以看做一个端口号
private static final UUID MY_UUID =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
//像一个服务器一样时刻监听是否有连接建立
private class AcceptThread extends Thread{
private BluetoothServerSocket serverSocket;
public AcceptThread(boolean secure){
BluetoothServerSocket temp = null;
try {
temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID);
} catch (IOException e) {
Log.e("app", "listen() failed", e);
}
serverSocket = temp;
}
public void run(){
BluetoothSocket socket=null;
while(true){
try {
socket = serverSocket.accept();
} catch (IOException e) {
Log.e("app", "accept() failed", e);
break;
}
}
if(socket!=null){
//此时可以新建一个数据交换线程,把此socket传进去
}
}
//取消监听
public void cancel(){
try {
serverSocket.close();
} catch (IOException e) {
Log.e("app", "Socket Type" + socketType + "close() of server failed", e);
}
}
}
搜索到设备后可以获取设备的地址,通过此地址获取一个BluetoothDeviced对象,可以看做客户端,通过此对象device.createRfcommSocketToServiceRecord(MY_UUID);同一个UUID可与服务器建立连接获取另一个socket对象,由此服务端与客户端各有一个socket对象,此时
他们可以互相交换数据了。
创立客户端socket可建立线程
//另一个设备去连接本机,相当于客户端
private class ConnectThread extends Thread{
private BluetoothSocket socket;
private BluetoothDevice device;
public ConnectThread(BluetoothDevice device,boolean secure){
this.device = device;
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} catch (IOException e) {
Log.e("app", "create() failed", e);
}
}
public void run(){
mBluetoothAdapter.cancelDiscovery(); //取消设备查找
try {
socket.connect();
} catch (IOException e) {
try {
socket.close();
} catch (IOException e1) {
Log.e("app", "unable to close() "+
" socket during connection failure", e1);
}
connetionFailed(); //连接失败
return;
}
//此时可以新建一个数据交换线程,把此socket传进去
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e("app", "close() of connect socket failed", e);
}
}
}
5.建立数据通信线程,进行读取数据
//建立连接后,进行数据通信的线程
private class ConnectedThread extends Thread{
private BluetoothSocket socket;
private InputStream inStream;
private OutputStream outStream;
public ConnectedThread(BluetoothSocket socket){
this.socket = socket;
try {
//获得输入输出流
inStream = socket.getInputStream();
outStream = socket.getOutputStream();
} catch (IOException e) {
Log.e("app", "temp sockets not created", e);
}
}
public void run(){
byte[] buff = new byte[1024];
int len=0;
//读数据需不断监听,写不需要
while(true){
try {
len = inStream.read(buff);
//把读取到的数据发送给UI进行显示
Message msg = handler.obtainMessage(BluetoothChat.MESSAGE_READ,
len, -1, buff);
msg.sendToTarget();
} catch (IOException e) {
Log.e("app", "disconnected", e);
connectionLost(); //失去连接
start(); //重新启动服务器
break;
}
}
}
public void write(byte[] buffer) {
try {
outStream.write(buffer);
// Share the sent message back to the UI Activity
handler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e("app", "Exception during write", e);
}
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e("app", "close() of connect socket failed", e);
}
}
}
到这里,蓝牙通信的基本操作已经全部完成。
分享到:
相关推荐
1、文件内容:GeoIP-data-1.5.0-14.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/GeoIP-data-1.5.0-14.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
PMSM永磁同步电机参数高精度辨识仿真:定子电阻、DQ电感及转子磁链辨识,适用于表贴与内嵌式电机,算法简洁,支持多种芯片,附Matlab原理说明,PMSM永磁同步电机参数辨识仿真,适用于表贴式,内嵌式永磁同步电机: 辨识内容: ① 定子电阻,精度在0.1%左右; ② DQ电感辨识(脉冲电压法),精度在0.02%左右; ③ 转子磁链辨识,精度在0.12%左右; 上述算法,是在实践工程中提炼出的算法,无复杂的矩阵计算,无复杂的滤波算法,TI ,ST 以及国产芯片都可实现,易于工程实现。 需要可以直接联系,发和matlab版本。 提供仿真的简要原理说明文档。 ,PMSM永磁同步电机;参数辨识;定子电阻辨识;DQ电感辨识;转子磁链辨识;易于工程实现;matlab版本;仿真原理说明文档,PMSM永磁同步电机参数辨识仿真:高精度算法与简易工程实现
光伏PV三相并网逆变器MATLAB仿真模型:高效逆变电技术、MPPT控制与LCL滤波的综合应用,光伏PV三相并网逆变器MATLAB仿真 好评后赠送相关参考 模型内容: 1.光伏+MPPT控制(boost+三相桥式逆变) 2.坐标变+锁相环+dq功率控制+解耦控制+电流内环电压外环控制+spwm调制 3.LCL滤波 仿真结果: 1.逆变输出与三项380V电网同频同相 2.直流母线电压600V稳定 3.d轴电压稳定311V;q轴电压稳定为0V,有功功率高效输出 ,光伏PV;三相并网逆变器;MATLAB仿真;MPPT控制;LCL滤波;dq功率控制;逆变输出;d轴电压;q轴电压。,基于MATLAB仿真的光伏PV三相并网逆变器:MPPT控制与LCL滤波技术的研究与实践
MATLAB与Carsim协同仿真:模型预测控制+路径跟踪+侧偏角软约束在车辆单移线与双移线的应用探究,模型预测控制(MPC)+路径跟踪(PTC)+侧偏角软约束+主动前轮转向(AFS),目前的范例是72km h,附着系数0.3的单移线,附着系数0.85双移线。 仿真使用的是MATLAB2020b版本和carsim2020。 MPC有两个:第一个为增量式方法编写,采用s-function实现,输入为跟踪误差、横摆角误差、侧向速度和横摆角速度,输出量为前轮转角,仅考虑横向控制。 考虑了前后轮的侧偏角软约束,在侧偏角到约束边界时减小控制律,保证侧偏角的稳定。 第二个采用Apollo中的模型,基于MATLAB function编写,不包括侧偏角软约束,作为对比参考使用。 其中包含carsim的cpar文件、模型mdl文件、绘图m文件(运行后一键出图)、说明文档和中文文献。 ,核心关键词:模型预测控制(MPC); 路径跟踪(PTC); 侧偏角软约束; 主动前轮转向(AFS); MATLAB2020b; carsim2020; 增量式MPC实现; Apollo中的模型; cpar文件; mdl文
宿舍管理源码(论文+源码)_kaic
格子玻尔兹曼方法模拟液滴分裂过程——伪势模型与MATLAB程序设计应用,使用格子玻尔兹曼方法(LBM)模拟液滴分裂,伪势模型,matlab程序 ,核心关键词:格子玻尔兹曼方法(LBM); 液滴分裂模拟; 伪势模型; MATLAB程序;,"LBM模拟液滴分裂:使用伪势模型与Matlab程序的探究"
全桥型MMC的降压控制与相间及桥臂电压均衡控制策略采用负序电流控制方法与载波移相调制技术,实现环流抑制,全桥型mmc,降压控制,相间电压均衡控制(负序电流控制方法),桥臂间电压均衡控制,桥臂内电压均衡控制,载波移相调制,环流抑制 ,核心关键词:全桥型MMC; 降压控制; 相间电压均衡控制(负序电流控制); 桥臂间电压均衡控制; 桥臂内电压均衡控制; 载波移相调制; 环流抑制。,全桥MMC的多元控制策略:载波移相、降压、均衡与环流抑制技术
基于PyTorch的图像分类模型研究:涵盖VGG、AlexNet、GoogleNet、ResNet、DenseNet、MobileNet、ShuffleNet、EfficientNet及Transformer等深度学习网络的应用与比较,pytorch图像分类:模型包括(VGG、alexnet、googlenet、resnet,densenet,mobilenet,shufflenet,efficientnet,transformer)。 ,核心关键词:PyTorch; 图像分类; 模型; VGG; AlexNet; GoogleNet; ResNet; DenseNet; MobileNet; ShuffleNet; EfficientNet; Transformer。,PyTorch图像分类:多模型比较(VGG等深度学习框架)与应用实践
天然气水合物降压开采的多场耦合模拟:储层特征与环空高压影响研究,天然气水合物降压开采,基于COMSOL热-流-固多场耦合实现,同时可以表征开采过程中的储层孔隙度、渗透率的演化,考虑水平井筒环空高压充填石英砂层,有水平井和压裂水平井模型。 ,核心关键词:天然气水合物降压开采; COMSOL热-流-固多场耦合; 储层孔隙度演化; 渗透率演化; 水平井筒环空高压充填石英砂层; 水平井模型; 压裂水平井模型。,基于COMSOL的天然气水合物降压开采模拟:多场耦合与储层孔渗演化研究
c语言做的播放器源码.zip
基于NGO-LSTM的优化长短期记忆神经网络数据回归预测模型——以北方苍鹰算法的实践与性能评估,NGO-LSTM回归预测,北方苍鹰算法(NGO)优化长短期记忆神经网络的数据回归预测 北方苍鹰属于22年到现在属于表现比较优秀的算法 1、运行环境要求MATLAB版本为2018b及其以上 2、评价指标包括:R2、MAE、MSE、RMSE等,图很多,符合您的需要 3、代码中文注释清晰,质量极高 4、测试数据集,可以直接运行源程序。 替你的数据即可用 适合新手小白 ,核心关键词:NGO-LSTM回归预测;北方苍鹰算法;长短期记忆神经网络;数据回归预测;MATLAB版本;评价指标;代码中文注释;测试数据集。,基于北方苍鹰算法优化的NGO-LSTM回归预测模型
基于卡尔曼滤波的分布式驱动电动汽车路面附着系数估计进阶模型:四种组合工况下的精准估计,基于分布式驱动电动汽车的路面附着系数估计,分别用卡尔曼滤波对电动汽车四个车轮的路面附着系数进行估计。 本模型参考scilunwen搭建,开发了分布式驱动电动汽车路面附着系数估计的进阶版本,可在高速,低速下,对开路面,对接路面四种组合工况下对路面附着系数进行准确估计估计。 ,分布式驱动; 电动汽车; 路面附着系数估计; 卡尔曼滤波; 不同工况。,"分布式驱动电动车辆的附着系数估计模型:高速低速下的准确估计进阶版"
QQ提取信息(论文+源码)_kaic
C语言之整数转换英文表示
该资源包含基于QT、C++、sqlite、tcp开发的网络辞典的所有相关源代码,分为服务端和客户端
基于PiecewiseJerkPathOptimizer的路径规划matlab动态案例及cpp实现速度规划,piecewiceJerkPathOptimizer路径规划 新增一个matlab动态案例,包含速度规划 包含cpp代码实现 ,piecewise_jerk_path_optimizer;matlab_dynamic_case_study;velocity_planning;cpp_code_implementation,"基于速度规划的Matlab动态案例与Cpp代码实现的路径规划优化器"
内容概要:本文详细介绍了CSDN博客之星评选活动的历史、意义及其带来的多方面好处。该评选活动自创立以来见证了许多技术人才的成长,并逐渐成为社区中最受瞩目的品牌活动之一。通过参加这一活动,博主可以获得个人品牌的极大提升,拓展人脉圈并与各界专业人士建立联系;更重要的是促进了个人技术水平的发展和对最新行业的认识。 适合人群:面向所有活跃在CSDN平台上的博客作者以及希望提高个人知名度和技术能力的技术从业者。 使用场景及目标:本文适用于计划参与或已经在参与CSDN博客之星评选的个人;帮助他们理解这项活动能带给自身的长远利益包括但不限于个人品牌塑造、人际网络扩张和技术能力增长等方面。并且指导大家怎样才能创作出更受欢迎的作品以增加赢得比赛的机会。 其他说明:本文由具体年度、获胜者的实例说明了参与博客之星的重要意义,并提出了关于如何创建高质量博客的一些建议,例如确保原创性、优化文章布局结构及积极维护与粉丝间的关系等内容。这不仅是一份指南同时也是一部激励参与者继续前进的动力源泉。
网上订餐系统设计与实现(论文+源码)_kaic.zip
指针初阶的基础知识
C#与halcon联合在RobotStudio中实现ABB机器人虚拟仿真视觉引导抓取(含九点标定与海康工业相机),abb机器人视觉引导抓取C#联合halcon联合RobotStudio实现仿真九点标定海康工业相机C#上位机视觉抓取 -本链接只出源码+工作站,不出任何硬件,工业相机请自备 -提供2个版本一个是有海康工业相机 和 无工业相机 1.有海康工业相机提供标定教程和咨询 2.没有海康工业相机的提供100张图片仿真和咨询 -本项目无需实体机器人一样能玩视觉引导非常适合新手学习 -使用的软件有 1.RobotStudio 6.08 Rapid编程,smart组件仿真 2.Visual Studio 2019 C#集成halcon代码+pc sdk二次开发 3.halcon视觉算法 ,关键词:ABB机器人;视觉引导抓取;C#;Halcon;RobotStudio;九点标定;海康工业相机;上位机视觉抓取;源码;工作站;实体机器人;虚拟仿真;Rapid编程;Smart组件仿真;PC SDK二次开发;Halcon视觉算法。,C#与Halcon联合的虚拟仿真:视觉引导抓取的自动化实践教程