关于安卓蓝牙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; } } } };
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
阅读全文
1 0
- 关于安卓蓝牙2.0的app开发原理
- 安卓的蓝牙开发
- 关于安卓蓝牙开发总结
- 关于安卓蓝牙的一些研究
- 安卓蓝牙开发
- 安卓蓝牙开发
- 安卓蓝牙开发
- 安卓的蓝牙全面开发教程
- 编写安卓app程序连接指定的蓝牙设备
- 安卓4.0蓝牙开发
- 浅谈安卓蓝牙开发
- Android安卓蓝牙开发
- 安卓蓝牙开发知识
- 安卓蓝牙开发相关
- 安卓蓝牙4.0开发
- 关于安卓6.0无法查找蓝牙设备的问题
- 安卓App开发
- 安卓APP开发
- C语言值传递与地址传递
- Java的体系
- poj2387 Til the Cows Come Home (多种最短路算法)
- VirtualBox 报错VERR_VD_IMAGE_READ_ONLY
- Linux系统变慢原因?
- 关于安卓蓝牙2.0的app开发原理
- 计蒜客 2017 NOIP 提高组模拟赛(二)Day1 A. 邻家男孩
- 数组的初始化方式
- 初识junit
- activiti学习--04流程定义:流程定义组成+部署流程定义+查询流程定义+删除流程定义+删除流程定义+查询最新版本的流程定+查询最新版本的流程定义
- 互联网新闻报道中的突发事件识别研究
- Tensorflow--逻辑回归
- LeetCode:M-36. Valid Sudoku
- nvm、nrm、npm 安装和使用详解