关于安卓蓝牙2.0的app开发原理

来源:互联网 发布:android编程教程 编辑:程序博客网 时间:2024/06/05 23:48

最近时间比较宽裕,觉得自己可以写一些东西来总结一下工作,索性就写一篇关于安卓蓝牙的开发总结吧

安卓蓝牙开发其实也就是socket的开发,同时分为服务端和客户端,下面我就按照我的开发流程来降整个的安卓蓝牙2.0开发叙述一下,蓝牙4.0BLE我也会在之后给大家更新

首先,我们要注册蓝牙相关的广播并在manifest中给出相应的权限(安卓6.0之后由于相应的底层改变,注册权限的时候不仅要给蓝牙的权限,还要给相应的位置权限),我在这里只为大家提供相应的广播,权限自己百度吧哈哈:

if(BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//额外的设备

if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setSupportProgressBarIndeterminateVisibility(false);
setTitle("请选择要连接的设备");
if(mPairedDevicesArrayAdapter.getCount() == 0) {
String noDevices = getResources().getText(R.string.none_found).toString();
mPairedDevicesArrayAdapter.add(noDevices);//当没有设备的时候
pairedListView.setEnabled(false);
}
}

之后我们需要获得蓝牙模块的mac地址和模块名,所以我们要进行蓝牙设备的查找,在查找界面中 我们使用BluetoothAdapter这个适配器来存储我们搜索的设备,使用Set集合来降获得的设备进行存储通过for循环来循环出手机搜索到的所有设备,代码如下

Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
得到的设备名称和设备地址
for(BluetoothDevice device : pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "( "
+ getResources().getText(R.string.has) + " )"
+"\n"+ device.getAddress());
}
之后我们会将得到的设备传递到我们的主界面当中,传递使用Intent(感觉是废话)代码如下:
ntent intent =newIntent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
intent.putExtra(EXTRA_RE_PAIR, re_pair);
intent.putExtra(EXTRA_DEVICE_NAME, name);
setResult(Activity.RESULT_OK, intent);
这样关于蓝牙设备的扫描和获取大致已经完成
在我做的app中我已经将蓝牙的打开,关闭,连接,读取,接收做了一个封装类:话不多说直接上代码:
public class BluetoothPort implements BasePrinterPort {    private static final String TAG = "BluetoothPort";    private String mDeviceAddress;    private BluetoothSocket mSocket;    private BluetoothAdapter mAdapter;    private static InputStream inputStream;    private static OutputStream outputStream;    private Context mContext;    private Handler mHandler;    private int mState;    private BluetoothDevice mDevice;    private final UUID PRINTER_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");    public BluetoothPort(BluetoothDevice bluetoothDevice, Handler handler) {        this.mHandler = handler;        this.mDevice = bluetoothDevice;        this.mAdapter = BluetoothAdapter.getDefaultAdapter();        this.mState = 103;    }    public BluetoothPort(String address, Handler handler) {        this.mHandler = handler;        this.mAdapter = BluetoothAdapter.getDefaultAdapter();        this.mDevice = this.mAdapter.getRemoteDevice(address);        this.mState = 103;    }    public boolean open() {        boolean isConnected = false;        if(this.mState != 103) {            this.close();        }        isConnected = this.connect2Device();        return isConnected;    }    public void close() {        try {            if(this.mSocket != null) {                this.mSocket.close();            }        } catch (IOException var2) {            var2.printStackTrace();        }        this.mDevice = null;        this.mSocket = null;        if(this.mState != 102) {            this.setState(103);        }    }    public int write(byte[] srcData) {        try {            if(outputStream == null) {                return -3;            }            outputStream.write(srcData);            outputStream.flush();        } catch (IOException var3) {            var3.printStackTrace();            return -1;        } catch (Exception var4) {            var4.printStackTrace();            return -2;        }        return srcData.length;    }    public int read(byte[] buffer) {        int readLen = 0;        try {            if(inputStream != null && (readLen = inputStream.available()) > 0) {                inputStream.read(buffer);            }            return readLen;        } catch (IOException var4) {            var4.printStackTrace();            return -1;        } catch (Exception var5) {            var5.printStackTrace();            return -1;        }    }    public int read(int timeout, byte[] buffer) {        int readLen = -1;        try {            while((readLen = inputStream.available()) <= 0) {                timeout -= 50;                if(timeout <= 0) {                    break;                }                try {                    Thread.sleep(50L);                } catch (InterruptedException var5) {                    var5.printStackTrace();                }            }            if(readLen > 0) {                buffer = new byte[readLen];                inputStream.read(buffer);            }        } catch (IOException var6) {            var6.printStackTrace();        }        return readLen;    }    private boolean connect2Device() {        boolean hasError = false;        if(this.mAdapter.isDiscovering()) {            this.mAdapter.cancelDiscovery();        }        try {            this.mSocket = this.mDevice.createRfcommSocketToServiceRecord(this.PRINTER_UUID);            this.mSocket.connect();        } catch (IOException var9) {            var9.printStackTrace();            try {                if(this.mSocket != null) {                    this.mSocket.close();                }                Thread.sleep(2000L);            } catch (IOException var7) {                var7.printStackTrace();            } catch (InterruptedException var8) {                var8.printStackTrace();            }            hasError = this.ReTryConnect();        } catch (Exception var10) {            try {                if(this.mSocket != null) {                    this.mSocket.close();                }                Thread.sleep(2000L);            } catch (IOException var5) {                var5.printStackTrace();            } catch (InterruptedException var6) {                var6.printStackTrace();            }            hasError = this.ReTryConnect();        }        if(!hasError) {            try {                inputStream = this.mSocket.getInputStream();                outputStream = this.mSocket.getOutputStream();            } catch (IOException var4) {                hasError = true;                var4.printStackTrace();            }        }        if(hasError) {            this.setState(102);            this.close();        } else {            this.setState(101);        }        return !hasError;    }    @SuppressLint({"NewApi"})    private boolean ReTryConnect() {        try {            if(VERSION.SDK_INT >= 10) {                this.mSocket = this.mDevice.createInsecureRfcommSocketToServiceRecord(this.PRINTER_UUID);            } else {                Method var4 = this.mDevice.getClass().getMethod("createRfcommSocket", new Class[]{Integer.TYPE});                this.mSocket = (BluetoothSocket)var4.invoke(this.mDevice, new Object[]{Integer.valueOf(1)});            }            this.mSocket.connect();            return false;        } catch (Exception var41) {            if(this.mSocket != null) {                try {                    this.mSocket.close();                } catch (IOException var3) {                    var3.printStackTrace();                }            }            var41.printStackTrace();            return true;        }    }    private synchronized void setState(int state) {        if(this.mState != state) {            this.mState = state;            if(this.mHandler != null) {                this.mHandler.obtainMessage(this.mState).sendToTarget();            }        }    }}

在主界面中,我们需要将之前获得的address和port传递过来并与手机建立相对应的连接,接收address和port的代码我就不贴了,小儿科代码,下面我直接粘贴连接代码:
mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(devicesAddress);
2.使用端口打开连接
myPrinter= PrinterInstance_One.getPrinterInstance(mDevice,mHandler);
3.判断是否连接:
使用线程在连接状态下直接打开连接
private class connectThreadextendsThread {
@Override
public void run() {
super.run();
if(myPrinter!=null) {
isConnected=myPrinter.openConnection();
}
}
}
(其中myPrinter是主要的实现类,我会在最后给大家上传我的GitHub)
蓝牙在连接过程中会涉及到一个配对的过程,所以我们要做出相应的配对检测,来查看所连接的设备是否为一配对设别,如果为新设备,那么我们要让手机提示用户进行配对
判断是否配对:
private voidPairOrConnect(booleanpair) {
if(pair) {
IntentFilter boundFilter =newIntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mContext.registerReceiver(boundDeviceReceiver, boundFilter);
booleansuccess =false;
try{
Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
success = (boolean) createBondMethod.invoke(mDevice);
}catch(NoSuchMethodException e) {
e.printStackTrace();
}catch(InvocationTargetException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}
}else{
newconnectThread().start();
}
}

相应的,我们要发送广播来获取设备与手机的配对连接:
   private BroadcastReceiver boundDeviceReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                if (!mDevice.equals(device)) {                    return;                }                switch (device.getBondState()) {                    case BluetoothDevice.BOND_BONDING:                        break;                    case BluetoothDevice.BOND_BONDED:                        mContext.unregisterReceiver(boundDeviceReceiver);                        dialog.show();                        if (myPrinter != null) {                            new connectThread().start();//                            received();                        }                        break;                    case BluetoothDevice.BOND_NONE:                        mContext.unregisterReceiver(boundDeviceReceiver);                        break;                }            }        }    };

这里会看到一个连接线程,主要作用是为连接做的,其中当获取的设备为空的时候,线程直接pass:
private class connectThread extends Thread {    @Override    public void run() {        super.run();        if (myPrinter != null) {            isConnected = myPrinter.openConnection();                    }    }}

关于关闭连接我在我的封装类中已经做了相应的处理,大家直接可以调用close方法来关闭

下面是我的GitHub地址:
https://github.com/wenhao555/USB-BLE-Serial-Printer.git



原创粉丝点击