本文介绍从查找蓝牙到蓝牙间互相通信的几个基本开发步骤
(1)设置权限:在Android系统中使用蓝牙一般需要在AndroidManifest.xml中设置蓝牙权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
(2)启动蓝牙:启动蓝牙前需要检查设备是否支持蓝牙,然后获取蓝牙适配器对象
final int REQUEST_ENABLE_BT = 111;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if(adapter == null){
//设备不支持蓝牙的相关动作
return;
}
//蓝牙未开启
if(!adapter.isEnabled()){
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent,REQUEST_ENABLE_BT);
}
...
public void onActivityResult(int requestCode, int resultCode,Intent data){
if(resultCode == REQUEST_ENABLE_BT){
if(requestCode == RESULT_OK){
//蓝牙开启成功
}
}
}
(3)发现蓝牙设备
1、本机蓝牙调到可见模式,便于其他设备搜索发现
final int BLUETOOTH_DISCOVER_TIME = 300;//300s内对其他设备可见
private void ensureDiscoverable(){
if(adapter.getScanMode() != BlueToothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION
,BLUETOOTH_DISCOVER_TIME);
startActivity(intent);
}
}
2、查找已配对的蓝牙设备
Set<BluetoothDevice> devices = adapter.getBondedDevices();
if(devices.size > 0){
//存在配对过的蓝牙设备,进行展示会处理
}
else{
//没有配对过的设备
}
3、搜索设备,注册一个BroadcastReceiver获得搜索结果
//注册广播,发现设备
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this,registerReceiver(receiver,filter);
//搜索结束
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_DISCOVERY_FINISHED);
this,registerReceiver(receiver,filter);
...
private BroadcastReceiver receiver = 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){
//对未配对蓝牙的处理
}
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
//搜索结束处理
}
}
};
(4)建立连接:当查找到蓝牙设备后,需要建立本机与其他蓝牙设备之间的连接。一般在使用本机搜索其他蓝牙设备时,本机可以作为一个服务端来接收其他设备的连接。启动一个服务器端线程,死循环等待客户端的连接。
//UUID可以看成是一个随机生成的端口号
private static final UUID BT_UUID =
UUID.fromString("fa87c0d0-afac-l1de-8a39-0800200c9a66");
//创建一个新线程监听是否有连接建立
private class AcceptThread extends Thread{
private BluetoothServerSocket serverSocket;
public AcceptThread(boolean secure){
BluetoothServerSocket socket = null;
try{
socket = adapter.listenUsingRfcommWithServerRecord(NAME_INSECURE,BT_UUID);
}catch(IOException e){
Log.e("app","listen failed",e);
}
serverSocket = socket;
}
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","cancel failed",e);
}
}
}
(5)交换数据:当搜索到蓝牙设备后,接下来可以获取设备的地址,通过此地址获取一个BluetoothDevice对象,可以将其看成是一个客户端,通过device.createRfcommSocketToServiceRecord(BT_UUID)相同的UUID,可与服务器建立连接获取另一个Socket对象。因为此服务器与客户端各有一个Socket对象,因此此时它们可以互相交换数据
//另一个设备(客户端)连接本机
private class ConnectThread extends Thread{
private BluetoothSocket socket;
private BluetoothDevice device;
public ConnectThread(BluetoothDevice device,boolean secure){
this.device = device;
BluetoothSocket temp = null;
try{
temp = device.createRfcommSocketToServerRecord(BT_UUID);
}catch(IOException e){
Log.e("app","create failed",e);
}
}
public void run(){
adapter.cancelDiscovery();
try{
socket.connect();
}catch(IOException e){
try{
socket.close()
}catch(IOException e){
Log.e("app","close failed",e);
}
connectionFailed();//连接失败
return;
}
//此时可以新建一个数据交换线程,将该socket传进去
}
public void cancel(){
try{
socket.close();
}catch(IOException e){
Log.e("app","close failed",e);
}
}
}
(6)建立数据通信线程:此处的任务是进行数据读取
//建立连接后,进行数据通信的线程
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","socket error",e);
}
}
public void run(){
byte[] buff = new byte[1024];
int len = 0;
//读取数据需要不断监听,写则不需要
while(true){
try{
len = inStream.read(buff);
//把读到的数据发送给UI进行显示
Messsage 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);
handler.obtainMessage(BluetoothChat.MESSAGE_WRITE,-1,-1,buffer)
.sendToTarget();
}catch(IOException e){
Log.e("app","write failed",e);
}
}
public void cancel(){
try{
socket.close;
}catch(IOException e){
Log.e("app","close failed,e);
}
}
}