Android 读取蓝牙设备信息开发
(1)Android手机一般以客户端的角色主动连接SPP协议设备(接上蓝牙模块的数字传感器),连接流程是:
1.使用registerReceiver注册BroadcastReceiver来获取蓝牙状态、搜索设备等消息;
2.使用BlueAdatper的搜索;
3.在BroadcastReceiver的onReceive()里取得搜索所得的蓝牙设备信息(如名称,MAC,RSSI);
4.通过设备的MAC地址来建立一个BluetoothDevice对象;
5.由BluetoothDevice衍生出BluetoothSocket,准备SOCKET来读写设备;
6.通过BluetoothSocket的createRfcommSocketToServiceRecord()方法来选择连接的协议/服务,这里用的是SPP(UUID:00001101-0000-1000-8000-00805F9B34FB);
7.Connect之后(如果还没配对则系统自动提示),使用BluetoothSocket的getInputStream()和getOutputStream()来读写蓝牙设备。
****************注意:对于UUID,必须使用Android的SSP(协议栈默认)的UUID:00001101-0000-1000-8000-00805F9B34FB才能正常和外部的,也是SSP串口的蓝牙设备去连接。
(2)添加权限:
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
(3)BluetoothAdapter类:
BluetoothAdapter类简单点来说就是代表了本设备(手机、电脑等)的蓝牙适配器对象,通过它我们可以蓝牙设备进行基本开发了。
主要有如下功能:
1、开关蓝牙设备
2、扫描蓝牙设备
3、设置/获取蓝牙状态信息,例如:蓝牙状态值、蓝牙Name、蓝牙Mac地址等;
BluetoothAdapter初始化并提示打开蓝牙使用:
private BluetoothAdapter mBluetoothAdapter;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!mBluetoothAdapter.isEnabled()) {
//弹出对话框提示用户是后打开
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(intent);
// startActivityForResult(intent, REQUEST_ENABLE);
//不做提示,强行打开
// mBluetoothAdapter.enable();
}
创建监听蓝牙状态的广播:
BroadcastReceiver mFoundReceiver = new BroadcastReceiver() { 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) {
Log.v(TAG, "find device:" + device.getName() + device.getAddress());
}
}
//搜索完成
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
cancelDiscovery(); }
}
};
注册广播监听蓝牙状态:
private void startDiscovery() { IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);//开启搜索
registerReceiver(mFoundReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成
registerReceiver(mFoundReceiver, filter); mBluetoothAdapter.startDiscovery(); }
开启和关闭蓝牙扫描:
// 开启
mBluetoothAdapter.startDiscovery();
// 关闭
mBluetoothAdapter.cancelDiscovery();
点击扫描到的列表,传递点击项的BluetoothDevice通过putExtra给蓝牙数据显示界面。
(4)进行BluetoothSocket socket 和 BluetoothDevice mBluetoothDevice 进行操作。
private class ConnectThread extends Thread { public ConnectThread(BluetoothDevice device) {
try {
socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
} catch (IOException e) {
e.printStackTrace();
}
} public void run() {
while (mAutoConnectInterruptTime < 5) {
try { socket.connect();
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO 显示连接成功
}
});
isConnect = true;
mAutoConnectInterruptTime = 0;
manageConnectedSocket(socket); // 创建新的线程对蓝牙进行数据读取。
break; } catch (Exception e) {
e.printStackTrace();
mAutoConnectInterruptTime++; try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
} runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO 显示连接失败
}
});
// TODO 进行对 inputStream outputStream socket 进行关闭 置空.
return;
}
} } public void cancel() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(5)通过BluetoothSocket socket 蓝牙数据读取:
public class Receive extends Thread {
// 变量 略过 // 构造方法
public Receive(BluetoothSocket socket) { // 获取输入流
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void run() {
final byte[] bytes = new byte[1024];// 缓冲数据流
int count;// 返回读取到的数据
// 监听输入流
try {
while (inputStream != null && (count = inputStream.read(bytes)) != -1) {
//获取有效部分
final byte[] contents = new byte[count];
for (int i = 0; i < contents.length; i++) {
contents[i] = bytes[i];
}
parse(contents); // TODO 对读取到数据进行转换
}
} catch (Exception e) {
e.printStackTrace();
} ConnectThread connectBtThread = new ConnectThread(mBluetoothDevice);
connectBtThread.start();
// TODO 进行对 inputStream outputStream socket 进行关闭 置空。
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO 关闭蓝牙连接
}
});
// TODO inputStream outputStream socket 进行关闭 置空
}
}
参考:
关于用到BluetoothServerSocket和BluetoothSocket两个类来建立Server端和Client端,还需要使用到一些关于流(Stream)的知识。
- BluetoothServerSocket——服务端(监听端、监听器、接受请求的一端)
- Accept()——阻塞宿主线程,直至收到客户端请求。返回BluetoothSocket对象。由于这个
- Accept(int timeout)——阻塞宿主线程,直至收到客户端请求或等待时间超过timeout。返回BluetoothSocket对象。
- Close()——关闭BluetoothServerSocket监听器。
可以看到,Accept方法是一个阻塞方法,所以在进行开发的时候,一般都需要用到多线程的知识。JAVA的多线程知识。
- BluetoothSocket——客户端(请求端)
- Close()——关闭BluetoothSocket请求端。
- Connect()——主动向服务端(监听端)发起连接请求。
可使用BluetoothAdapter类的listenUsingRfcommWithServiceRecord方法来新建一个ServerSocket。
可以使用web上的任何一款UUID产生器为你的程序获取一个UUID,然后使用fromString(String)初始化一个UUID。
使用ServerSocket实例的accept方法进行监听,当监听到带有我们初始化的UUID参数的连接请求后作出响应,连接成功后返回一个BluetoothSocket对象。连接完成后,调用close方法关闭该Socket监听。
使用BluetoothDevice的实例的createRfcommSocketToServiceRecord方法来创建一个BluetoothSocket实例。
传入我们服务端的UUID值。
然后使用BluetoothSocket实例的Connect方法对Server端进行连接请求,当连接成功后,Client端和Server端的传输通道就被打开。
参考链接:
Android中连接蓝牙设备时遇到createRfcommSocketToServiceRecord的UUID问题和BluetoothSocket的connect失败
http://www.cnblogs.com/cxcco/archive/2012/01/15/2322783.html
Android 读取蓝牙设备信息开发的更多相关文章
- Android读取logcat信息
测试的时候,经常遇到开发需要logcat分析定位bug,今天简单记录一下获取logcat的方法 前提条件:电脑中要安装好Android SDK 1.cmd 进入到这个界面 2.电脑连上手机,手机记得打 ...
- MTK Android 读取SIM卡参数,获取sim卡运营商信息
android 获取sim卡运营商信息(转) TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TE ...
- Java Web开发技术教程入门-项目-读取用户注册信息
昨天说要补个项目来巩固下这几天学的知识,于是今天咱们就写一个读取用户注册信息的小项目.读取用户信息注册信息这个功能在各大网站都是很常见的.好,话不多说.开始我们的编程之旅! 软件环境:JDK9.0 ...
- Android 低功耗蓝牙BLE 开发注意事项
基本概念和问题 1.蓝牙设计范式? 当手机通过扫描低功耗蓝牙设备并连接上后,手机与蓝牙设备构成了客户端-服务端架构.手机通过连接蓝牙设备,可以读取蓝牙设备上的信息.手机就是客户端,蓝牙设备是服务端. ...
- 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面
[Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界 ...
- 【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面
大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单, ...
- Android Developer -- Bluetooth篇 开发实例之一 扫描设备
第一步:声明Bluetooth Permissions <!-- 设置蓝牙访问权限 --> <uses-permission android:name="android.p ...
- ASP.NET Core的配置(1):读取配置信息
提到"配置"二字,我想绝大部分.NET开发人员脑海中会立马浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化 ...
- Android 图片Exif信息相关的获取与修改
1 Exif是什么 Exif是一种图像文件格式,它的数据存储于JPEG格式是完全相同的,实际上Exif格式就是JPEG格式头插入了 数码照片的信息,包括拍摄的光圈.快门.平衡白.ISO.焦距.日期时间 ...
随机推荐
- PHP中的常用魔术方法
魔术方法: 是指某些情况下,会自动调用的方法,称为魔术方法 php面向对象中,提供了这几个魔术方法,他们的特点都是 以双下划线__开头的 __construct() 构造方法 __destruct( ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper
前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...
- Jquery.Datatables 基本设置的中文注解
$(document).ready(function() { $('#example').dataTable({ "sScrollX": "100%", //表 ...
- web.config详解 -- asp.net夜话之十一
1.配置文件节点说明 1.1 <appSettings>节点 1.2 <connectionStrings>节点 1.3 <compilation> ...
- SQL分页存储过程——表名、返回的列、排序字段、排序类型、条件、页尺寸、页码
ALTER PROCEDURE [dbo].[SP_LGY_ICU_PAGECUT] ), -- 表名 ) = '*', -- 需要返回的列 )='''', -- 排序的欄位名 , -- 設置排序類型 ...
- Ubuntu下调整swap分区的大小
转自:http://blog.chinaunix.net/uid-7573623-id-2048964.html 由于安装oracle 的时候,swap太小不能继续安装,于是想有什么方法在不不用安装o ...
- 关于strcpy_s
#include"stdafx.h" #include<iostream> #include<cstring> int main() { using nam ...
- hdu 4010 动态树 @
kuangbin模板题,看起来十分高大上 /* *********************************************** Author :kuangbin Created Tim ...
- git分支使用
1.查看远程服务器分支 git branch -a 2.查看本地分支 git branch 3.切换分支 git checkout master 4.删除远程分支 git push origin :b ...
- How to install the zsh shell in Linux && how to set it as a default login shell
Z shell’s (zsh) popularity has increased in the last years. I have not moved too zsh yet, but I am g ...