前段时间公司里要求做蓝牙方面的开发,花了些时间在网上查找资料,已及Google API。下面是我整理总结后的内容。
做蓝牙开发之前需要了解必备几个类和接收的广播action
BluetoothAddapter类
BluetoothDevice类
BluetoothSocket类
BluetoothDevice.ACTION_FOUND
关于这些类以及action的解释就不细说了,不清楚的请自觉查阅API以及百度
android蓝牙开发可以分为以下几个步骤:
1)判断手机设备是否存在蓝牙,若存在则打开蓝牙设备
2)搜索附近蓝牙设备
3)蓝牙配对
4)socket连接
现在我们来详细地解说一下各个步骤:
1)BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefalutAdapter();
if(mBluetoothAdapter != null){ //当mBluetoothAdapter == null说明该手机没有蓝牙设备
if(!mBluetoothAdapter.isEnabled() ){ //返回值为true,说明蓝牙已打开
mBluetoothAdapter.enable(); //返回值为true,则打开蓝牙设备 ,这个方法不会有界面反馈,缺乏人机交互,下面是显示Dialog的一个方法
//Intent enableBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableBTIntent,0);
}
}
2)搜索附近设备前,你需要先查询配对好了的蓝牙设备集(可能你现在需要配对的设备在之前就已经配对好了的,这样就能直接进行连 接,能节约很多资源)
Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
if(devices.size()>0){
for(BluetoothDevice device : devices){
pairedArray.add(device.getName()+"\n"+"device.getAddress()");
}
}
搜索蓝牙方法:mBluetoothAdapter.startDiscovery();
3)我们需要先注册一个广播来接收搜索蓝牙过后的结果,之后才能进行配对
registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
public BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
String action = arg1.getAction();
btDevice = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (action.equals(BluetoothDevice.ACTION_FOUND)) {
if (btDevice.getName().equals(BT_NAME)) {
mBluetoothAdapter.cancelDiscovery(); //停止查找
btDevice_Target = btDevice;
if( btDevice_Target.getBondState() != BluetoothDevice.BOND_BONDED){ //判断给设备是否已经配对
createBond(); //配对
}
}
}
};
//这个方法是一个映射的方法,找了好长时间才找到
private void createBond() throws Exception {
Method createBondMethod = btDevice_Target.getClass().getMethod("createBond");
createBondMethod.invoke(btDevice_Target);
}
4)socket连接
在蓝牙通信中,由于这是一个交互的过程,所以不管哪一端,必须同时具备接收和发送数据的能力,当一方主动连接时,另一方就要像服务器一般用来接收,同时客户端也能变成服务器来接收信息,而且主动连接和被动接收这两个过程都会进入阻塞状态,所以需要
创建两个线程来进行
客户端主动连接:
private class ConnectThread extends Thread {
private BluetoothDevice mDevice;
private BluetoothSocket mSocket;
public ConnectThread(BluetoothDevice device) {
mDevice = device;
BluetoothSocket tmp;
try {
tmp = mDevice.createInsecureRfcommSocketToServiceRecord(UUID
.fromString(BT_TargetDevice_UUID));
mSocket = tmp;
btSocket_Target = mSocket;
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
super.run();
btAdapter.cancelDiscovery();
try {
mSocket.connect(); //客户端能连接最重要的方法
isClient = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void cancel(){
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器端接收:
private class AcceptThread extends Thread {
BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
SERVER_SOCKET, UUID.fromString(BT_TargetDevice_UUID));
} catch (IOException e) {
e.printStackTrace();
}
mmServerSocket = tmp;
}
@Override
public void run() {
while(true){
if(isAccept){
try {
mAcceptSocket = mmServerSocket.accept(); //能接收的最重要的方法
if(mAcceptSocket != null ){
System.out.println("accept != null ---------------------");
btSocket_Target = mAcceptSocket;
btSocket_Target.connect();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
当我们建立连接后就可以通过
btSocket_Target.getInputStream();
btSocket_Target.getOutputStream();
来分别获得输入和输出流来进行数据的交互了,
好了,收工,要是中间讲的有不对的地方,请谅解,也希望能多多交流