开发系统:Android4.4.2 运行平台:广州微嵌安卓工业平板
安卓的蓝牙打开包括获取蓝牙模块、搜索蓝牙设备、蓝牙设备间的配对、连接跟通信等部分。
1、安卓中使用蓝牙模块需要蓝牙的使用权限,需要在AndroidMainfest.xml中声明:
允许程序连接到已配对的蓝牙设备允许程序发现和配对蓝牙设备1234
2、获取蓝牙适配器并打开蓝牙
//获取蓝牙适配器mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if(mBluetoothAdapter ==null){
Toast.makeText(this, "不支持蓝牙设备",Toast.LENGTH_LONG).show(); bluetoothSwitch.setEnabled(false); return;
}
打开蓝牙设备//判断蓝牙设备是否处于关闭状态,如果是则打开蓝牙if(!mBluetoothAdapter.isEnabled()){
if(mBluetoothManager.enable()){//打开蓝牙设备//开启蓝牙后,需设置蓝牙为可发现状态,这样其它的蓝牙设备才能搜索到。Intent discoverableIntent = new Intent
(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//最后的参数设置可见的时间,最长为300s,设为0表示一直可见discoverableIntent.putExtra(
BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
startActivity(discoverableIntent); //成功打开蓝牙后开始搜索附近的蓝牙设备
mBluetoothAdapter.startDiscovery(); //停止搜索:mBluetoothAdapter.cancelDiscovery();}
}else{//关闭蓝牙设备
mBluetoothManager.disable();
}//获取已配对的蓝牙设备Set Bondedlist =mBluetoothAdapter.getBondedDevices();123456789101112131415161718192021222324252627
3、定义广播接收,在开始搜索附近的蓝牙设备,系统回发出三个搜索状态的广播
BluetoothDevice.ACTION_FOUND //搜索到设备BluetoothAdapter.ACTION_DISCOVERY_STARTED //开始搜索BluetoothAdapter.ACTION_DISCOVERY_FINISHED //搜索结束 定义广播接收相应的广播状态private class BluetoothReceive extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) { // TODO 自动生成的方法存根
String action = intent.getAction(); //判断广播内容
//搜索到蓝牙设备广播
if(action.equals(BluetoothDevice.ACTION_FOUND)){ //获取搜素到的蓝牙设备
BluetoothDevice device =intent.getParcelableExtra
(BluetoothDevice.EXTRA_DEVICE);
if(device.getName()==null){ return;
} //获取搜素到的蓝牙设备是否已经配对
if(device.getBondState() == BluetoothDevice.BOND_BONDED){
deviceSet.add(device);
adapter.add(device.getName()+":可使用");
} else {
deviceSet.add(device);
adapter.add(device.getName()+":可配对");
}
}
//搜索结束的广播
else if(action.equals
(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
Toast.makeText(MainActivity.this, "扫描结束",Toast.LENGTH_LONG).show();
}
}
}
4、蓝牙设备的配对
//获取搜索到的蓝牙设备列表中的蓝牙设备及其状态BluetoothDevice device = deviceSet.get(position);int state = deviceSet.get(position).getBondState();//判断蓝牙设备状态Switch(state){ //蓝牙设备没有配对
case BluetoothDevice.BOND_NONE:
//配对方法一:
Method createBondMethod=
device.getClass().getMethod("createBond");
Boolean returnValue =(Boolean)createBondMethod.invoke(device);
//配对方法二:
device.createBond(); break; //蓝牙设备已经配对
case BluetoothDevice.BOND_BONDED: //可选操作:删除配对信息、连接蓝牙设备
//删除配对信息:
Method createBondMethod=
device.getClass().getMethod("removeBond");
Boolean returnValue =(Boolean)createBondMethod.invoke(device);
//连接蓝牙设备:
//建立蓝牙客户端并连接服务器
mBluetoothClient = new BluetoothClient(MainActivity.this,device,uuid);
mBluetoothClient.connect(); break;
}
上面的内容主要是获取蓝牙模块、打开蓝牙、搜素附近蓝牙设备跟进行配对。
下面的是蓝牙设备间建立连接并进行通信。
蓝牙设备的连接、通信跟网络通信TCP的类似,分别有服务器、客户端,先是新建一个服务器用于监听客户端的连接请求,客户端向服务器发送连接请求,连接成功后双方都获得BluetoothSocket的实例,双方可以通过BluetoothSocket的实例进行通信。
5、服务器:
新建一个蓝牙服务器并监听客户端的连接请求
在listenUsingRfcommWithServiceRecord中有一个参数叫做UUID,UUID(Universally Unique Identifier)是一个128位的字符串ID,被用于唯一标识我们的蓝牙服务。
String name = mBluetoothAdapter.getName();try {//创建一个BluetoothServerSocket蓝牙服务器,并开启接收线程等待客户端的连接
mServerSocket = mBluetoothAdapter
.listenUsingRfcommWithServiceRecord(name, uuid); new acceptThread().start();
} catch (IOException e) { // TODO 自动生成的 catch 块
e.printStackTrace();
};
等待客户端连接:public class acceptThread extends Thread{
@Override
public void run() { // TODO 自动生成的方法存根
try { //该方法是服务器阻塞等待客户端的连接,
//监听到有客户端连接返回一个BluetoothSocket的实例
socket = mServerSocket.accept();
Log.d("Server", "以连接"); //开启读取线程读取客户端发来的数据
read = new readThread();
read.start();
} catch (IOException e) { // TODO 自动生成的 catch 块
e.printStackTrace();
}
super.run();
}
}
读取数据:public class readThread extends Thread{
@Override
public void run() { // TODO 自动生成的方法存根
if(socket.isConnected()){ try { //获取socket的InputStream并不断读取数据
InputStream in = socket.getInputStream(); byte[] buff = new byte[1024]; while(!isInterrupted()){ int size = in.read(buff);; if(size>0){
Log.d("RECVDATA", String.valueOf(buff));
}
}
in.close();
} catch (IOException e) { // TODO 自动生成的 catch 块
e.printStackTrace();
}
} super.run();
}
}
发送数据:public void write(String str){ if(socket.isConnected()){ try {//获取socket的OutputStream并写入数据
OutputStream out = socket.getOutputStream();
out.write(str.getBytes());
out.close();
} catch (IOException e) { // TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}//关闭服务器:mServerSocket.close();//关闭BluetoothSocket:Socket.close();
6、客户端:
获取一个BluetoothSocket的实例并向服务器发送连接请求public class ConnectThread extends Thread{
@Override
public void run() { // TODO 自动生成的方法存根
try { //获取BluetoothSocket实例并连接服务器,该处的uuid需与服务器短
//的uuid一致才能连接成功,connect()是回阻塞的。
socket = mBluetoothDevice
.createRfcommSocketToServiceRecord(uuid);
socket.connect()
Log.d("TAG", "连接成功");
read = new ReadThread();
read.start();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} super.run();
}
}
客户端的读取跟发送与服务器的相同。
至此安卓系统的蓝牙的基本功能就基本完成了,在两块都开启了蓝牙的安卓设备上分别建议服务器跟客户端,并进行连接,连接成功后双方就可以通过蓝牙进行通信了。