(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 读取蓝牙设备信息开发的更多相关文章

  1. Android读取logcat信息

    测试的时候,经常遇到开发需要logcat分析定位bug,今天简单记录一下获取logcat的方法 前提条件:电脑中要安装好Android SDK 1.cmd 进入到这个界面 2.电脑连上手机,手机记得打 ...

  2. MTK Android 读取SIM卡参数,获取sim卡运营商信息

    android 获取sim卡运营商信息(转)   TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TE ...

  3. Java Web开发技术教程入门-项目-读取用户注册信息

    昨天说要补个项目来巩固下这几天学的知识,于是今天咱们就写一个读取用户注册信息的小项目.读取用户信息注册信息这个功能在各大网站都是很常见的.好,话不多说.开始我们的编程之旅! 软件环境:JDK9.0  ...

  4. Android 低功耗蓝牙BLE 开发注意事项

    基本概念和问题 1.蓝牙设计范式? 当手机通过扫描低功耗蓝牙设备并连接上后,手机与蓝牙设备构成了客户端-服务端架构.手机通过连接蓝牙设备,可以读取蓝牙设备上的信息.手机就是客户端,蓝牙设备是服务端. ...

  5. 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面

    [Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界 ...

  6. 【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

    大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单, ...

  7. Android Developer -- Bluetooth篇 开发实例之一 扫描设备

    第一步:声明Bluetooth Permissions <!-- 设置蓝牙访问权限 --> <uses-permission android:name="android.p ...

  8. ASP.NET Core的配置(1):读取配置信息

    提到"配置"二字,我想绝大部分.NET开发人员脑海中会立马浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化 ...

  9. Android 图片Exif信息相关的获取与修改

    1 Exif是什么 Exif是一种图像文件格式,它的数据存储于JPEG格式是完全相同的,实际上Exif格式就是JPEG格式头插入了 数码照片的信息,包括拍摄的光圈.快门.平衡白.ISO.焦距.日期时间 ...

随机推荐

  1. centos(x86 64位系统)使用boost

    1. 安装gcc,g++,make等开发环境 yum groupinstall "Development Tools" 2. 安装boost yum install boost b ...

  2. ASP.NET 自定义URL重写 分类: ASP.NET 2014-10-31 16:05 175人阅读 评论(0) 收藏

    一.功能说明: 可以解决类似 http://****/news 情形,Url路径支持正则匹配. 二.操作步骤: 1.增加URL重写模块: using System; using System.IO; ...

  3. angularjs 权威指南 版本 1.2.6

    1 $rootScope  run  : run 方法初始化全局的数据 ,只对全局作用域起作用 如$rootScope <script src="http://apps.bdimg.c ...

  4. 安卓app设计规范整理和Android APP设计篇(转)

    随着安卓智能手机不停的更新换代.安卓手机系统越来越完美,屏幕尺寸也越来越大啦!比如最近小米的miui 6的发布和魅族手机系统的更新等等. 以小米MIUI6的安卓手机来说,MIUI6进行了全新设计,坚持 ...

  5. hdu 3001(状压dp, 3进制)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 由于本题中一个点最多能够访问2次,由此可以联想到3进制; visited[i][j]表示在状态i ...

  6. 开始我的PostgreSQL的学习之旅

    经过这么长时间的学习,终于确定了我的研究方向是PostgreSQL的空间数据库的设计流程,具体怎样实现这个过程,其难度是挺大的,我必须克服掉,尽量得往前看.大家有相同的研究方向的,可以一同来学习,相互 ...

  7. 【SSH】 之 Struts2环境搭建及简单应用开发

    在上一篇文章中,我们一起了解了一下struts2的工作机制原理,接下来让我们进行一下简单应用的开发 (一)配置环境 1.建立web项目 2.导入jar包 其中struts2中有很多jar包,我们不需要 ...

  8. SQLServer 维护脚本分享(10)索引

    --可添加索引的字段 migs.user_seeks,migs.avg_total_user_cost,migs.avg_user_impact,migs.last_user_seek ,mid.st ...

  9. HDU 4496 D-City (并查集)

    题意:有n个城市,m条路,首先m条路都连上,接着输出m行,第i行代表删除前i行的得到的连通块个数 题解:正难则反,我们反向考虑使用并查集添边.首先每个点都没有相连,接着倒着来边添加边计算,当两个点父节 ...

  10. 编解码-protobuf

    Google的Protobuf在业界非常流行,很多商业项目选择Protobuf作为编解码框架,Protobuf的优点. (1)在谷歌内部长期使用,产品成熟度高: (2)跨语言,支持多种语言,包括C++ ...