前段時間公司裏要求做藍牙方面的開發,花了些時間在網上查找資料,已及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();
來分別獲得輸入和輸出流來進行數據的交互了
好了,收工,要是中間講的有不對的地方,請諒解,也希望能多多交流