Android项目开发中的蓝牙类的编写,总结一下
蓝牙相关类的总结:
1.BluetoothSocket 类的定义格式如下:
public static class Gallery.LayoutParams extends ViewGroup.LayoutParams
累BluetoothSocket的定义结构如下:
java.lang.Object
android.view.ViewGroup.LayoutParams
android.widget.Gallery.LayoutParams
Android的蓝牙系统与Socket套接字密切相关,蓝牙端的监听接口和TCP的端口类似,均使用了Socket和ServerSocket类。在服务器端,使用BlueServerSocket类来创建一个监听服务器端口,当一个连接被BluetoothServerSocket所接受,会返回一个新的BluetoothSocket来管理该连接,在客户端,使用一个单独的BlueSocket类去初始化一个外界连接和管理该连接。
为了创建一个Bluetooth去连接到一个已知设备,使用方法BluetoothDevice。createRfcommSocketToServiceRecord()。然后调用connect()方法去尝试一个面向远程设备的连接,这个调用将被阻塞,直到一个连接已经建立或者该连接失效。
为了创建一个BluetoothSocket作为服务器,每当该端口连接成功后,无论它初始化为客户端,或者被接收为服务端,都是通过方法getInputStream()和getOutputStream()来打开I/O流,从而获得各自的InputStream和OutputStream对象
2.BluetoothServerSocket类的格式如下:
public final class BluetoothServerSocket extends Object implements Closeable
类BluetoothServerSocket的结构如下:
java.lang.Object
android.bluetooth.BluetoothServerSocket
3.BluetoothAdapter类的格式如下:
public final class BluetoothAdapter extends Object
类BluetoothAdapter结构如下:
java.lang.Object
android.bluetooth.BluetoothAdapter
BluetoothAdapter代表本地的蓝牙配适器设备,通过此类可以让用户执行基本的蓝牙任务,例如,初始化设备的搜索,查询可匹配的设备集,使用一个已知的MAC地址来初始化一个BluetoothDevice类,创建一个BluetoothServerSocket类似监听其他设备对本机的连接请求等。
为了得到这个代表本地蓝牙配适器的BluetoothAdapter类,需要调用静态方法getDefaultAdapter(),这是所有蓝牙动作的第一步,当拥有本地配适器之后,用户可以获得一系列的BluetoothDevice对象,这些对象代表所有拥有getBondedDevice()方法的已经匹配的设备,用startDiscovery()方法来开始设备的搜寻,或者创建一个BluetoothServerSocket类,通过listenUsingRfcommWithServiceRecord(String, UUID)方法来监听新来的连接请求。
注:大部分需要BLUETOOTH权限,一些方法同时需要BLUETOOTH——ADMIN权限
首先,该导的包,该声明的常量,变量,对象等,如下
import android.annotation.SuppressLint;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@SuppressLint("NewApi")
public class Bluetooth extends Service {
static final String dbg = "bluetooth";
static final int MSG_CONNECTED=1;
static final int MSG_DISCONNECTED=2;
static final int MSG_RX = 3;
static final int MSG_FOUNDDEVICE = 4;
static final int MSG_CONNECT_FAIL = 5;
static final int MSG_DISCOVERY_FINISHED = 6;
static final int MSG_RX_FIRMUPLOAD = 7;
static final int REQUEST_CONNECT_DEVICE = 1;
static final int REQUEST_ENABLE_BT = 2;
BluetoothAdapter mBTAdapter;
static final String BTName = "BTMakeblock";
static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
BluetoothDevice connDev;
ConnectThread mConnectThread;
ConnectedThread mConnectedThread;
ArrayList<BluetoothDevice> btDevices;
ArrayList<BluetoothDevice> prDevices; // paired bt devices
//public ArrayAdapter<String> devAdapter;
Handler mHandler;
static final int MODE_LINE = 0;
static final int MODE_FORWARD = 1;
public int commMode = MODE_LINE;
private static Bluetooth _instance;
开始构建管理共享的方法:
public static Bluetooth sharedManager() {
if (_instance == null) {
_instance = new Bluetooth();
}
return _instance;
}
以及Bluetooth()和onCreate()方法
public Bluetooth(){
// bluetooth classic
btDevices = new ArrayList<BluetoothDevice>();
prDevices = new ArrayList<BluetoothDevice>();
mBTAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBTAdapter==null){
Log.i(dbg, "blue tooth not support");
}
}
@Override
public void onCreate() {
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBTDevDiscover,filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBTDevDiscover,filter);
_instance = this;
if(!mBTAdapter.isEnabled()){
mBTAdapter.enable();
}else{
startDiscovery();
}
}
销毁方法:
public void onDestroy() {
unregisterReceiver(mBTDevDiscover);
}
public void startDiscovery(){
mBTAdapter.startDiscovery();
}
public boolean isDiscovery(){
return mBTAdapter.isDiscovering();
}
public boolean isEnabled(){
return mBTAdapter.isEnabled();
}
以下是连接线程的方法:
private class ConnectThread extends Thread {
private BluetoothSocket mmSocket = null;
private BluetoothDevice mmDevice = null;
public ConnectThread(BluetoothDevice device)
{
mmDevice = device;
}
public void run(){
// stop discovery, otherwise the pair window won't popup
mBTAdapter.cancelDiscovery();
try {
mmSocket = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
mmSocket.connect();
} catch (IOException e) {
try {
Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
Object[] params = new Object[] {Integer.valueOf(1)};
mmSocket = (BluetoothSocket)m.invoke(mmDevice, params);
mmSocket.connect();
} catch (IOException err) {
Log.d("mb", "connect:"+err.getMessage());
e.printStackTrace();
try {
mmSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if(mHandler!=null){
Message msg = mHandler.obtainMessage(MSG_CONNECT_FAIL);
mHandler.sendMessage(msg);
}
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InvocationTargetException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return;
}
// start connection manager in another thread
bluetoothConnected(mmDevice,mmSocket);
}
public void cancel(){
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
接下来就是处理已连接的线程:
public ConnectedThread(BluetoothSocket socket){
mmSocket = socket;
mRx = new ArrayList<Byte>();
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes;
while(true){
try {
bytes = mmInStream.read(buffer);
if (bytes > 0) {
for (int i = 0; i < bytes; i++) {
Byte c = buffer[i];
mRx.add(c);
// line end or bootloader end
if ((c == 0x0a && commMode==MODE_LINE) || (c==0x10 && commMode==MODE_FORWARD)) {
// TODO: post msg to UI
//write(mReceiveString.getBytes());
Byte[] rxbtyes = mRx.toArray(new Byte[mRx.size()]);
///*
String hexStr="";
int[] buf = new int[mRx.size()];
for(int i1=0;i1<rxbtyes.length;i1++){
hexStr+= String.format("%02X ", rxbtyes[i1]);
buf[i1] = rxbtyes[i1];
}
Log.i("mb", "rx:"+hexStr);
//*/
mHandler.obtainMessage(MSG_RX,buf).sendToTarget();
mRx.clear();
}
}
}
} catch (IOException e) {
Log.i(dbg, "disconnected");
connDev = null;
if(mHandler!=null){
Message msg = mHandler.obtainMessage(MSG_DISCONNECTED);
mHandler.sendMessage(msg);
}
break;
}
}
}
public void write(byte[] bytes){
try {
txBusy=true;
mmOutStream.write(bytes);
mmOutStream.flush();
txBusy=false;
} catch (IOException e) {
Log.e(dbg, "Exception during write", e);
}
}
public void cancel(){
try {
mmSocket.close();
} catch (IOException e) {
Log.e(dbg, "Exception during cancel", e);
}
}
}
public void devListClear(){
btDevices.clear();
// don't forget the connecting device
if(connDev!=null){
btDevices.add(connDev);
}
}
final BroadcastReceiver mBTDevDiscover = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("mb", "broadcast:"+action);
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Log.d("mb", "bluetooth found:"+device.getName()+" "+device.getAddress()+" "+device.getBondState()+" "+BluetoothDevice.BOND_NONE+" "+BluetoothDevice.BOND_BONDED);
if(btDevices.indexOf(device)==-1){
btDevices.add(device);
if(mHandler!=null){
Message msg = mHandler.obtainMessage(MSG_FOUNDDEVICE);
mHandler.sendMessage(msg);
}
}
//bluetoothConnect(device);
}else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
if(mHandler!=null){
Message msg = mHandler.obtainMessage(MSG_DISCOVERY_FINISHED);
mHandler.sendMessage(msg);
}
Log.i(dbg,"bluetooth discover finished");
}else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
Log.i(dbg,"bluetooth ACTION_STATE_CHANGED:"+mBTAdapter.isEnabled());
}else if (action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//setBluetoothPairingPin(device);
}
}
}
};
public List<String> getPairedList(){
List<String> data = new ArrayList<String>();
Set<BluetoothDevice> pairedDevices = mBTAdapter.getBondedDevices();
prDevices.clear();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
prDevices.add(device);
}
}
for(BluetoothDevice dev : prDevices){
String s = dev.getName();
s=s+" "+dev.getAddress();
if(connDev!=null && connDev.equals(dev)){
s="-> "+s;
}
data.add(s);
}
return data;
}
public List<String> getBtDevList(){
List<String> data = new ArrayList<String>();
Set<BluetoothDevice> pairedDevices = mBTAdapter.getBondedDevices();
// prDevices.clear();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if(!btDevices.contains(device))
btDevices.add(device);
}
}
for(BluetoothDevice dev : btDevices){
String s = dev.getName();
if(s!=null){
if(s.indexOf("null")>-1){
s = "Bluetooth";
}
}else{
s = "Bluetooth";
}
//String[] a = dev.getAddress().split(":");
s=s+" "+dev.getAddress()+" "+(dev.getBondState()== BluetoothDevice.BOND_BONDED?((connDev!=null && connDev.equals(dev))?getString(R.string.connected):getString(R.string.bonded)):getString(R.string.unbond));
data.add(s);
}
return data;
}
public void bluetoothWrite(byte[] data){
if(mConnectedThread==null) return;
///*
String hexStr="";
for(int i1=0;i1<data.length;i1++){
hexStr+= String.format("%02X ", data[i1]);
}
Log.d("mb", "tx:"+hexStr);
//*/
if(mConnectedThread.txBusy==false){
mConnectedThread.write(data);
}else{
Log.d("mb", "tx busy");
}
}
public void bluetoothDisconnect(BluetoothDevice device){
Log.i(dbg, "disconnect to "+device.getName());
if(mConnectThread != null){mConnectThread.cancel();mConnectThread = null;}
if(mConnectedThread != null){mConnectedThread.cancel();mConnectedThread = null;}
}
public void bluetoothConnect(BluetoothDevice device) throws Exception {
Log.i(dbg, "try connect to "+device.getName());
if(mConnectThread != null){mConnectThread.cancel();mConnectThread = null;}
if(mConnectedThread != null){mConnectedThread.cancel();mConnectedThread = null;}
mConnectThread = new ConnectThread(device);
mConnectThread.start();
Intent intent =new Intent(this,DialogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("msg", getString(R.string.connecting));
startActivity(intent);
}
public void bluetoothConnected(BluetoothDevice device, BluetoothSocket socket){
Log.i(dbg, "bluetooth connected:"+device.getAddress());
connDev = device;
if(mHandler!=null){
Message msg = mHandler.obtainMessage(MSG_CONNECTED);
mHandler.sendMessage(msg);
}
if(mConnectedThread != null){mConnectedThread.cancel();mConnectedThread = null;}
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
Intent intent =new Intent(this,DialogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("msg", "connected");
startActivity(intent);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}