前段时间公司里要求做蓝牙方面的开发,花了些时间在网上查找资料,已及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 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();

来分别获得输入和输出流来进行数据的交互了




好了,收工,要是中间讲的有不对的地方,请谅解,也希望能多多交流j_0011.gif