开发系统:Android4.4.2
安卓的蓝牙的打开包括获取蓝牙模块、搜索蓝牙设备、蓝牙设备间的配对、连接跟通信等部分。
1、安卓中使用蓝牙模块需要蓝牙的使用权限,需要在AndroidMainfest.xml中声明:
允许程序连接到已配对的蓝牙设备
<uses-permission android:name="android.permission.BLUETOOTH"/>
允许程序发现和配对蓝牙设备
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
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<BluetoothDevice> Bondedlist =mBluetoothAdapter.getBondedDevices();
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();
}
}
客户端的读取跟发送与服务器的相同。
至此安卓系统的蓝牙的基本功能就基本完成了,在两块都开启了蓝牙的安卓设备上分别建议服务器跟客户端,并进行连接,连接成功后双方就可以通过蓝牙进行通信了。