/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bingo.assistant.common.remoteControl.bluetooth.client; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import com.infrastructure.util.LogUtils; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** * 蓝牙通信基础客户端框架 * BluetoothBaseClient */ public class BBC { private static final UUID MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); //private static final UUID MY_UUID_INSECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private static final UUID MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); private static final int MSG_BLUETOOTH_START = 0; //蓝牙开始 private static final int MSG_BLUETOOTH_CONNECT = 1; //蓝牙连接 private static final int MSG_BLUETOOTH_CONNECTED = 2; //蓝牙连接成功 private static final int MSG_BLUETOOTH_CONNECT_TIMEOUT = 3; //蓝牙连接超时 private static final int MSG_BLUETOOTH_CLOSE = 4; //蓝牙连接关闭 private final BluetoothAdapter mBluetoothAdapter; private ConnectManagerThread mConnectManagerThread; private BluetoothStatusChangeHandler mBluetoothStatusChangeHandler; private BluetoothReadHandler mBluetoothReadHandler; private volatile ConnectedHandler mConnectedHandler; private BluetoothDevice device; public BBC() { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); HandlerThread handlerThread1 = new HandlerThread("BluetoothStatusChangeHandler"); handlerThread1.start(); mBluetoothStatusChangeHandler = new BluetoothStatusChangeHandler(handlerThread1.getLooper()); HandlerThread handlerThread2 = new HandlerThread("BluetoothReadHandler"); handlerThread2.start(); mBluetoothReadHandler = new BluetoothReadHandler(handlerThread2.getLooper()); } private void clean(){ if(mBluetoothStatusChangeHandler != null){ mBluetoothStatusChangeHandler.removeMessages(MSG_BLUETOOTH_START); mBluetoothStatusChangeHandler.removeMessages(MSG_BLUETOOTH_CONNECT); mBluetoothStatusChangeHandler.removeMessages(MSG_BLUETOOTH_CLOSE); mBluetoothStatusChangeHandler.removeMessages(MSG_BLUETOOTH_CONNECT_TIMEOUT); mBluetoothStatusChangeHandler.removeMessages(MSG_BLUETOOTH_CONNECTED); } } /** * 设置设备 */ public synchronized void switchDevice(BluetoothDevice device){ this.device = device; } private static final int READ_OPEN = 1; private static final int READ_CLOSE = 2; private static final int READ = 3; private class BluetoothReadHandler extends Handler{ private AtomicBoolean isOpen = new AtomicBoolean(false); BluetoothReadHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { int what = msg.what; switch (what){ case READ: if(isOpen.get() && onPushListener != null){ LogUtils.bluetooth("读取流...."); try{ if(mConnectedHandler != null){ mConnectedHandler.read(); } sendEmptyMessage(READ); }catch (Exception e){ e.printStackTrace(); bluetoothErrorHandler(ERROR_BLUETOOTH_READ, e); } } break; case READ_OPEN: isOpen.set(true); synchronized (this){ notify(); } sendEmptyMessage(READ); break; case READ_CLOSE: removeMessages(READ); isOpen.set(false); break; } } public void open(){ synchronized (this){ try { sendEmptyMessage(READ_OPEN); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public void close(){ sendEmptyMessage(READ_CLOSE); isOpen.set(false); } } private class BluetoothStatusChangeHandler extends Handler{ private int BBCmsg; BluetoothStatusChangeHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { int what = msg.what; switch (what){ case MSG_BLUETOOTH_START: closeBluetoothDeviceHandler(); boolean openSucess = openBluetoothDeviceHandler(); if(openSucess){ BBCmsg = MSG_BLUETOOTH_START; //设置状态为蓝牙打开 bluetoothStatusChangeHandler(STATUS_BLUETOOTH_OPEN, "蓝牙打开!"); sendEmptyMessage(MSG_BLUETOOTH_CONNECT); }else { bluetoothErrorHandler(ERROR_BLUETOOTH_UNABLE, new RuntimeException("蓝牙不可用!")); } break; case MSG_BLUETOOTH_CONNECT: if(BBCmsg == MSG_BLUETOOTH_START){ BBCmsg = MSG_BLUETOOTH_CONNECT; connectBluetoothDeviceHandler(); bluetoothStatusChangeHandler(STATUS_BLUETOOTH_CONNECTING, "蓝牙正在建立连接!"); }else { LogUtils.bluetooth("状态不符合,不做处理:" + BBCmsg); } break; case MSG_BLUETOOTH_CONNECTED: //开始建立流 if(BBCmsg == MSG_BLUETOOTH_CONNECT){ Object o = msg.obj; if(o != null){ BluetoothSocket mmSocket = (BluetoothSocket) o; mConnectedHandler = new ConnectedHandler(mmSocket); if(mConnectedHandler.connectedSuccess()){ //打开读数据 mBluetoothReadHandler.open(); BBCmsg = MSG_BLUETOOTH_CONNECTED; bluetoothStatusChangeHandler(STATUS_BLUETOOTH_CONNECTED, "蓝牙连接成功!"); }else { bluetoothErrorHandler(ERROR_BLUETOOTH_CONNECT, new RuntimeException("蓝牙连接异常!")); } }else { bluetoothErrorHandler(ERROR_BLUETOOTH_CONNECT, new RuntimeException("蓝牙连接异常!")); } }else { LogUtils.bluetooth("状态不符合,不做处理:" + BBCmsg); } break; case MSG_BLUETOOTH_CONNECT_TIMEOUT: break; case MSG_BLUETOOTH_CLOSE: closeBluetoothDeviceHandler(); BBCmsg = MSG_BLUETOOTH_CLOSE; bluetoothStatusChangeHandler(STATUS_BLUETOOTH_CLOSE, "蓝牙关闭!"); break; } } } /** * 打开蓝牙 */ private boolean openBluetoothDeviceHandler() { if (mBluetoothAdapter == null) { //蓝牙模块不可用 return false; } //确保蓝牙打开 if (!mBluetoothAdapter.isEnabled()) { mBluetoothAdapter.enable(); int MAX_COUNT = 10; int tryCount = 0; boolean enable = false; while(!enable){ //检查是否打开完成 enable = mBluetoothAdapter.isEnabled(); if(tryCount > MAX_COUNT){ return false; } try { tryCount++; Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } return true; } /** * 关闭蓝牙 */ public void closeBluetoothDeviceHandler() { //停止读数据 mBluetoothReadHandler.close(); LogUtils.bluetooth("停止蓝牙连接服务"); if (mConnectedHandler != null) { mConnectedHandler.cancel(); mConnectedHandler = null; } if (mConnectManagerThread != null) { mConnectManagerThread.cancel(); mConnectManagerThread = null; } } /** * 连接远程蓝牙设备 */ public synchronized void connectBluetoothDeviceHandler() { closeBluetoothDeviceHandler(); mConnectManagerThread = new ConnectManagerThread(); mConnectManagerThread.start(); } /** * 打开 */ public void open(){ mBluetoothStatusChangeHandler.sendEmptyMessage(MSG_BLUETOOTH_START); } /** * 关闭 */ public void close(){ LogUtils.bluetooth("发送蓝牙关闭信息!"); clean(); mBluetoothStatusChangeHandler.sendEmptyMessage(MSG_BLUETOOTH_CLOSE); } private class ConnectManagerThread extends Thread{ //private final ConnectThread mSecureThread; private final ConnectThread mInSecureThread; ConnectManagerThread(){ //mSecureThread = new ConnectThread(device, true); mInSecureThread = new ConnectThread(device, false); } public void cancel(){ //mSecureThread.cancel(); mInSecureThread.cancel(); } @Override public void run() { //Future<BluetoothSocket> f1 = pool.submit(mSecureThread); Future<BluetoothSocket> f2 = pool.submit(mInSecureThread); try { //BluetoothSocket socket1 = f1.get(); BluetoothSocket socket2 = f2.get(20, TimeUnit.SECONDS); LogUtils.bluetooth("获得SOCKET"); // if(socket1 != null || socket2 != null){ // //启动链接流程 // Message message = Message.obtain(); // if(f1.get() != null){ // message.obj = f1.get(); // }else { // message.obj = f2.get(); // } // message.what = MSG_BLUETOOTH_CONNECTED; // mBluetoothStatusChangeHandler.sendMessage(message); // }else { // bluetoothErrorHandler(ERROR_BLUETOOTH_CONNECT, new RuntimeException("蓝牙服务建立失败!")); // } if(socket2 != null){ Message message = Message.obtain(); if(f2.get() != null){ message.obj = f2.get(); message.what = MSG_BLUETOOTH_CONNECTED; mBluetoothStatusChangeHandler.sendMessage(message); }else { bluetoothErrorHandler(ERROR_BLUETOOTH_CONNECT, new RuntimeException("蓝牙服务建立失败!")); } } } catch (Exception e) { e.printStackTrace(); bluetoothErrorHandler(ERROR_BLUETOOTH_CONNECT, e); } } } private static final ExecutorService pool = Executors.newFixedThreadPool(2); private class ConnectThread implements Callable<BluetoothSocket> { private final BluetoothSocket mmSocket; private String mSocketType; public ConnectThread(BluetoothDevice device, boolean secure) { BluetoothSocket tmp = null; mSocketType = secure ? "Secure" : "Insecure"; try { if (secure) { tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE); } else { tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE); } } catch (IOException e) { LogUtils.bluetooth("Socket Type: " + mSocketType + "create() failed " + e); } mmSocket = tmp; } public void cancel() { try { mmSocket.close(); } catch (IOException e) { LogUtils.bluetooth("close error :" + e.getMessage()); bluetoothErrorHandler(ERROR_BLUETOOTH_CLOSE, e); } } @Override public BluetoothSocket call() throws Exception { mBluetoothAdapter.cancelDiscovery(); try { LogUtils.bluetooth("等待服务端响应 mmSocket :" + mmSocket); //开始连接 mmSocket.connect(); LogUtils.bluetooth("收到服务端响应"); return mmSocket; } catch (IOException e) { e.printStackTrace(); LogUtils.bluetoothError(e); cancel(); bluetoothErrorHandler(ERROR_BLUETOOTH_CONNECT, e); return null; } } } private class ConnectedHandler { private static final int READ_MAX = 256; private final byte[] bytes = new byte[READ_MAX]; private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; private final String mmDevice; public ConnectedHandler(BluetoothSocket socket) { mmSocket = socket; mmDevice = socket.getRemoteDevice().getName(); InputStream tmpIn = null; OutputStream tmpOut = null; try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (Exception e) { e.printStackTrace(); } mmInStream = tmpIn; mmOutStream = tmpOut; } public boolean connectedSuccess(){ return mmInStream != null && mmOutStream != null; } public void read() throws Exception { int readCount = mmInStream.read(bytes); if(onPushListener != null){ byte[] datas = new byte[readCount]; System.arraycopy(bytes, 0, datas, 0, readCount); onPushListener.onDecode(datas); } } public void write(byte[] buffer) throws Exception { mmOutStream.write(buffer); if(onBluetoothStatusChangeListener != null) { onBluetoothStatusChangeListener.bluetoothSendSuccess(buffer); } } public void cancel() { try { mmOutStream.close(); mmInStream.close(); mmSocket.close(); } catch (Exception e) { e.printStackTrace(); bluetoothErrorHandler(ERROR_BLUETOOTH_CLOSE, e); } } public String getMmDevice() { return mmDevice; } } /** * 发送消息 */ public void write(byte[] out) { try{ if(mConnectedHandler != null) { mConnectedHandler.write(out); } }catch (Exception e){ e.printStackTrace(); bluetoothErrorHandler(ERROR_BLUETOOTH_WRITE, e); } } /** * 蓝牙状态变化 */ private static final int ERROR_BLUETOOTH_UNABLE = 1; //蓝牙不可用异常 private static final int ERROR_BLUETOOTH_CLOSE = 2; //蓝牙关闭异常 private static final int ERROR_BLUETOOTH_READ = 3; //蓝牙读取异常 private static final int ERROR_BLUETOOTH_WRITE = 4; //蓝牙写异常 private static final int ERROR_BLUETOOTH_CONNECT = 5; //蓝牙连接异常 private void bluetoothErrorHandler(int statusCount, Exception e){ switch (statusCount){ case ERROR_BLUETOOTH_UNABLE: if(onBluetoothErrorListener != null){ onBluetoothErrorListener.bluetoothUnableError(e); } break; case ERROR_BLUETOOTH_CONNECT: if(onBluetoothErrorListener != null){ onBluetoothErrorListener.bluetoothConnectError(e); } break; case ERROR_BLUETOOTH_READ: if(onBluetoothErrorListener != null){ onBluetoothErrorListener.bluetoothReadError(e); } break; case ERROR_BLUETOOTH_WRITE: if(onBluetoothErrorListener != null){ onBluetoothErrorListener.bluetoothWriteError(e); } break; case ERROR_BLUETOOTH_CLOSE: if(onBluetoothErrorListener != null){ onBluetoothErrorListener.bluetoothCloseError(e); } break; default: break; } } private static final int STATUS_BLUETOOTH_OPEN = 6; //蓝牙打开 private static final int STATUS_BLUETOOTH_CONNECTING = 7; //蓝牙正在建立连接 private static final int STATUS_BLUETOOTH_CONNECTED = 8; //蓝牙连接建立 private static final int STATUS_BLUETOOTH_CLOSE = 9; //蓝牙关闭 private void bluetoothStatusChangeHandler(int statusCount, String statusMessage){ LogUtils.bluetooth(statusMessage + " 状态号: " + statusCount); switch (statusCount){ case STATUS_BLUETOOTH_OPEN: if(onBluetoothStatusChangeListener != null){ //获取本机蓝牙信息 String localAddress = mBluetoothAdapter.getAddress(); String localName = mBluetoothAdapter.getName(); LogUtils.bluetooth("本机蓝牙信息[address:" + localAddress + ",name:" + localName); onBluetoothStatusChangeListener.bluetoothOpened(statusMessage, localAddress, localName); } break; case STATUS_BLUETOOTH_CONNECTED: if(onBluetoothStatusChangeListener != null){ LogUtils.bluetooth("蓝牙建立连接:" + mConnectedHandler.getMmDevice()); onBluetoothStatusChangeListener.bluetoothConnected(mConnectedHandler.getMmDevice()); } break; case STATUS_BLUETOOTH_CLOSE: if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothClosed(statusMessage); } break; default: break; } } public void setOnBluetoothStatusChangeListener(OnBluetoothStatusChangeListener onBluetoothStatusChangeListener) { this.onBluetoothStatusChangeListener = onBluetoothStatusChangeListener; } private volatile OnBluetoothStatusChangeListener onBluetoothStatusChangeListener; interface OnBluetoothStatusChangeListener { void bluetoothOpened(String message, String localAddress, String localName); void bluetoothConnected(String message); void bluetoothClosed(String message); void bluetoothSendSuccess(byte[] b); } public void setOnBluetoothErrorListener(OnBluetoothErrorListener onBluetoothErrorListener) { this.onBluetoothErrorListener = onBluetoothErrorListener; } private volatile OnBluetoothErrorListener onBluetoothErrorListener; interface OnBluetoothErrorListener{ void bluetoothUnableError(Exception error); void bluetoothConnectError(Exception error); void bluetoothReadError(Exception error); void bluetoothWriteError(Exception error); void bluetoothCloseError(Exception error); } public void setOnPushListener(OnPushListener onPushListener) { this.onPushListener = onPushListener; } private volatile OnPushListener onPushListener; interface OnPushListener{ void onDecode(byte[] datas); } }
package com.bingo.assistant.common.remoteControl.bluetooth.client; import android.bluetooth.BluetoothDevice; import com.infrastructure.util.LogUtils; public class BBCCommander implements BBC.OnBluetoothStatusChangeListener, BBC.OnBluetoothErrorListener, BBC.OnPushListener{ private static final BBC BBC = new BBC(); @Override public void bluetoothUnableError(Exception error) { LogUtils.bluetooth("蓝牙不能使用!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothUnable(error); } } @Override public void bluetoothConnectError(Exception error) { LogUtils.bluetooth(error + "蓝牙连接异常!:" + onBluetoothStatusChangeListener); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothError(error); } } @Override public void bluetoothReadError(Exception error) { LogUtils.bluetooth(error + "蓝牙读异常!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothError(error); } } @Override public void bluetoothWriteError(Exception error) { LogUtils.bluetooth(error + "蓝牙写异常!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothError(error); } } @Override public void bluetoothCloseError(Exception error) { LogUtils.bluetooth("蓝牙关闭异常!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothError(error); } } private static class SingletonInstance { private static final BBCCommander mInstance = new BBCCommander(); } public static BBCCommander getInstance(){ return SingletonInstance.mInstance; } @Override public void bluetoothOpened(String message, String localAddress, String localName) { LogUtils.bluetooth("蓝牙打开!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothOpened(message); } } @Override public void bluetoothConnected(String device) { LogUtils.bluetooth("蓝牙建立连接!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothConnected(device); } } @Override public void bluetoothClosed(String message) { LogUtils.bluetooth("蓝牙关闭!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothClosed(message); } } @Override public void bluetoothSendSuccess(byte[] b) { LogUtils.bluetooth("蓝牙发送成功!"); if(onBluetoothStatusChangeListener != null){ onBluetoothStatusChangeListener.bluetoothSendSuccess(b); } } public void switchDevice(BluetoothDevice device){ BBC.switchDevice(device); } public void init(){ BBC.setOnBluetoothStatusChangeListener(this); BBC.setOnBluetoothErrorListener(this); BBC.setOnPushListener(this); } public void open(){ BBC.open(); } public void close(){ BBC.close(); } public void write(byte[] bytes){ BBC.write(bytes); } @Override public void onDecode(byte[] datas) { if(mOnDecoder != null){ mOnDecoder.onDecode(datas); } } public void setOnBluetoothStatusChangeListener(OnBluetoothStatusChangeListener onBluetoothStatusChangeListener) { this.onBluetoothStatusChangeListener = onBluetoothStatusChangeListener; } private volatile OnBluetoothStatusChangeListener onBluetoothStatusChangeListener; public interface OnBluetoothStatusChangeListener{ void bluetoothUnable(Exception e); void bluetoothError(Exception e); void bluetoothOpened(String message); void bluetoothConnected(String message); void bluetoothClosed(String message); void bluetoothSendSuccess(byte[] b); } private volatile OnDecoder mOnDecoder; public void setOnDecoder(OnDecoder mOnDecoder) { this.mOnDecoder = mOnDecoder; } public interface OnDecoder { void onDecode(byte[] bytes); } }
Android 蓝牙客户端实现
最新推荐文章于 2023-06-13 10:41:23 发布