Android蓝牙通信
2015-07-30 16:58
531 查看
Android为蓝牙设备之间的通信封装好了一些调用接口,使得实现Android的蓝牙通信功能并不困难。可通过UUID使两个设备直接建立连接。
具体步骤:
1. 获取BluetoothAdapter实例,注册一个BroadcastReceiver监听蓝牙扫描过程中的状态变化
[java] view
plaincopyprint?
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
[java] view
plaincopyprint?
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
[java] view
plaincopyprint?
[java] view
plaincopyprint?
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
// 通过EXTRA_DEVICE附加域来得到一个BluetoothDevice设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
// 如果这个设备是不曾配对过的,添加到list列表
if (device.getBondState() != BluetoothDevice.BOND_BONDED)
{
list.add(new ChatMessage(device.getName() + "\n" + device.getAddress(), false));
clientAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
// When discovery is finished, change the Activity title
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
setProgressBarIndeterminateVisibility(false);
if (mListView.getCount() == 0)
{
list.add(new ChatMessage("没有发现蓝牙设备", false));
clientAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
}
}
};
2. 打开蓝牙(enable),并设置蓝牙的可见性(可以被其它设备扫描到,客户端是主动发请求的,可不设置,服务端必须设置可见)。
[java] view
plaincopyprint?
if (mBluetoothAdapter != null) {
if (!mBluetoothAdapter.isEnabled()) {
// 发送打开蓝牙的意图,系统会弹出一个提示对话框
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, RESULT_FIRST_USER);
// 设置蓝牙的可见性,最大值3600秒,默认120秒,0表示永远可见(作为客户端,可见性可以不设置,服务端必须要设置)
Intent displayIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
displayIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
startActivity(displayIntent);
// 直接打开蓝牙
mBluetoothAdapter.enable();
}
}
3. 扫描,startDiscovery()方法是一个很耗性能的操作,在扫描之前可以先使用getBondedDevices()获取已经配对过的设备(可直接连接),避免不必要的消耗。
[java] view
plaincopyprint?
private void scanDevice() {
// TODO Auto-generated method stub
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
} else {
// 每次扫描前都先判断一下是否存在已经配对过的设备
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
list.add(new ChatMessage(device.getName() + "\n" + device.getAddress(), true));
}
} else {
list.add(new ChatMessage("No devices have been paired", true));
clientAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
/* 开始搜索 */
mBluetoothAdapter.startDiscovery();
}
4. 通过Mac地址发送连接请求,在这之前必须使用cancelDiscovery()方法停止扫描。
[java] view
plaincopyprint?
mBluetoothAdapter.cancelDiscovery();
// 通过Mac地址去尝试连接一个设备
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(BluetoothMsg.BlueToothAddress);
5. 通过UUID使两个设备之间建立连接。
客户端:主动发请求
[java] view
plaincopyprint?
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
// 通过socket连接服务器,这是一个阻塞过程,直到连接建立或者连接失效
socket.connect();
服务端:接受一个请求
[java] view
plaincopyprint?
BluetoothServerSocket mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
/* 接受客户端的连接请求 */
// 这是一个阻塞过程,直到建立一个连接或者连接失效
// 通过BluetoothServerSocket得到一个BluetoothSocket对象,管理这个连接
BluetoothSocket socket = mServerSocket.accept();
6. 通过InputStream/outputStream读写数据流,已达到通信目的。
[java] view
plaincopyprint?
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
[java] view
plaincopyprint?
InputStream is = null;
try {
is = socket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
7. 关闭所有线程以及socket,并关闭蓝牙设备(disable)。
[java] view
plaincopyprint?
if (mClientThread != null) {
mClientThread.interrupt();
mClientThread = null;
if (mReadThread != null) {
mReadThread.interrupt();
mReadThread = null;
try {
if (socket != null) {
socket.close();
socket = null;
}
catch (IOException e) {
// TODO: handle exception
[java] view
plaincopyprint?
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
// 关闭蓝牙
mBluetoothAdapter.disable();
}
unregisterReceiver(mReceiver);
主要步骤就是这些,为了能够更好的理解,我将服务器端和客户端的代码分开来写了两个程序,下载地址:http://download.csdn.net/detail/visionliao/8417235
具体步骤:
1. 获取BluetoothAdapter实例,注册一个BroadcastReceiver监听蓝牙扫描过程中的状态变化
[java] view
plaincopyprint?
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
[java] view
plaincopyprint?
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
[java] view
plaincopyprint?
[java] view
plaincopyprint?
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
// 通过EXTRA_DEVICE附加域来得到一个BluetoothDevice设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
// 如果这个设备是不曾配对过的,添加到list列表
if (device.getBondState() != BluetoothDevice.BOND_BONDED)
{
list.add(new ChatMessage(device.getName() + "\n" + device.getAddress(), false));
clientAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
// When discovery is finished, change the Activity title
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
setProgressBarIndeterminateVisibility(false);
if (mListView.getCount() == 0)
{
list.add(new ChatMessage("没有发现蓝牙设备", false));
clientAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
}
}
};
2. 打开蓝牙(enable),并设置蓝牙的可见性(可以被其它设备扫描到,客户端是主动发请求的,可不设置,服务端必须设置可见)。
[java] view
plaincopyprint?
if (mBluetoothAdapter != null) {
if (!mBluetoothAdapter.isEnabled()) {
// 发送打开蓝牙的意图,系统会弹出一个提示对话框
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, RESULT_FIRST_USER);
// 设置蓝牙的可见性,最大值3600秒,默认120秒,0表示永远可见(作为客户端,可见性可以不设置,服务端必须要设置)
Intent displayIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
displayIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
startActivity(displayIntent);
// 直接打开蓝牙
mBluetoothAdapter.enable();
}
}
3. 扫描,startDiscovery()方法是一个很耗性能的操作,在扫描之前可以先使用getBondedDevices()获取已经配对过的设备(可直接连接),避免不必要的消耗。
[java] view
plaincopyprint?
private void scanDevice() {
// TODO Auto-generated method stub
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
} else {
// 每次扫描前都先判断一下是否存在已经配对过的设备
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
list.add(new ChatMessage(device.getName() + "\n" + device.getAddress(), true));
}
} else {
list.add(new ChatMessage("No devices have been paired", true));
clientAdapter.notifyDataSetChanged();
mListView.setSelection(list.size() - 1);
}
/* 开始搜索 */
mBluetoothAdapter.startDiscovery();
}
4. 通过Mac地址发送连接请求,在这之前必须使用cancelDiscovery()方法停止扫描。
[java] view
plaincopyprint?
mBluetoothAdapter.cancelDiscovery();
// 通过Mac地址去尝试连接一个设备
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(BluetoothMsg.BlueToothAddress);
5. 通过UUID使两个设备之间建立连接。
客户端:主动发请求
[java] view
plaincopyprint?
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
// 通过socket连接服务器,这是一个阻塞过程,直到连接建立或者连接失效
socket.connect();
服务端:接受一个请求
[java] view
plaincopyprint?
BluetoothServerSocket mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
/* 接受客户端的连接请求 */
// 这是一个阻塞过程,直到建立一个连接或者连接失效
// 通过BluetoothServerSocket得到一个BluetoothSocket对象,管理这个连接
BluetoothSocket socket = mServerSocket.accept();
6. 通过InputStream/outputStream读写数据流,已达到通信目的。
[java] view
plaincopyprint?
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
[java] view
plaincopyprint?
InputStream is = null;
try {
is = socket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
7. 关闭所有线程以及socket,并关闭蓝牙设备(disable)。
[java] view
plaincopyprint?
if (mClientThread != null) {
mClientThread.interrupt();
mClientThread = null;
if (mReadThread != null) {
mReadThread.interrupt();
mReadThread = null;
try {
if (socket != null) {
socket.close();
socket = null;
}
catch (IOException e) {
// TODO: handle exception
[java] view
plaincopyprint?
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
// 关闭蓝牙
mBluetoothAdapter.disable();
}
unregisterReceiver(mReceiver);
主要步骤就是这些,为了能够更好的理解,我将服务器端和客户端的代码分开来写了两个程序,下载地址:http://download.csdn.net/detail/visionliao/8417235
相关文章推荐
- iOS 与 Android 生命周期对比
- Android Wifi方法大全
- Android内核剖析
- Android内核剖析
- android异常:uncaught exception
- Android应用性能优化
- Android应用性能优化
- Android 通过应用程序来设置系统的日期和时间中的
- 从Android源码剖析Intent查询匹配的实现
- Gradle 1:为什么要用Gradle
- android应用程序中获取view的位置
- 打造高质量Android应用:Android开发必知的50个诀窍
- androidのXlist框架上拉下拉刷新案例
- Android Studio关联SVN相关操作
- Android中读取图片EXIF元数据之metadata-extractor的使用
- 看google怎样将android回归在自己的保护伞之下
- android异常:dialog窗口句柄泄露
- 【Android应用开发技术:数据存储】数据库
- 【Android应用开发技术:文件读写】Android文件系统
- Android adb命令唤醒屏幕