(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. php导出excel封装类

    因为实际情况的需要,导出excel表格在后台开发的过程中会经常用到.下面是我在实际应用中自己整理的一个导出excel类,需要PHPExcel支持,本类很好的完成导出表格的基本样式,保存路径,切换工作薄 ...

  2. Error parsing 'file:///media/RHEL_5.5\\ x86_64\\ DVD/Server'

    Error parsing 'file:///media/RHEL_5.5\\ x86_64\\ DVD/Server' http://lindows.iteye.com/blog/456637 ht ...

  3. ****CodeIgniter使用cli模式运行,把php作为shell编程

    shell简介 在计算机科学中,Shell俗称壳(用来区别于核).而我们常说的shell简单理解就是一个命令行界面,它使得用户能与操作系统的内核进行交互操作. 常见的shell环境有:MS-DOS.B ...

  4. 【转载】python super的用法

    转载地址: http://blog.csdn.net/cxm19830125/article/details/20610533 super的用法是调用继承类的初始化方法,如下面的代码: class A ...

  5. maven 错误: 程序包org.junit不存在

    该错误在入门例子中使用mvn clean test时出现该错误. 原因: 测试用例应该放在src/test/java/...路径下,我是放在了src/main/java/..路径下了. 因为没有遵守其 ...

  6. hdu 4046 2011北京赛区网络赛G 线段树 ***

    还带这么做的,卧槽,15分钟就被A了的题,居然没搞出来 若某位是1,则前两个为wb,这位就是w #include<cstdio> #include<cstring> #defi ...

  7. javascript中的true和false

    今天遇到一个问题,执行下面的代码返回true还是false?请说明理由 console.log([] == ![]) 在浏览器中运行了一下,发现结果是true.为什么会这样呢?于是查找了相关的资料. ...

  8. Android使用JNI实现Java与C之间传递数据(转)

    介绍Java如何将数据传递给C和C回调Java的方法.  java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java.C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需 ...

  9. DateTime时间格式

    DateTime dt = DateTime.Now; Label1.Text = dt.ToString();//2005-11-5 13:21:25 Label2.Text = dt.ToFile ...

  10. jquery中append()、prepend()、after()、before()的区别详解

    append() - 在被选元素的结尾插入内容(内容的结尾,比如说有个a标签,则是在</a>这个标签之前添加东西) prepend() - 在被选元素的开头插入内容(内容的开始,比如说有个 ...