蓝牙(英语:Bluetooth),一种无线通信技术标准,用来让固定与移动设备,在短距离间交换数据,以造成我的局域网(PAN)。蓝牙技术当前由蓝牙技术联盟(SIG)来负责维护其技术标准。java
蓝牙可分为经典蓝牙(Classic Bluetooth)、低功耗蓝牙(Bluetooth Low Energy)、双模蓝牙三大类。2009 年发布的蓝牙 3.0 及以前的蓝牙版本包括 BR、EDR 和 HS(AMP) 三种蓝牙技术,统称为经典蓝牙技术,只支持经典蓝牙技术的蓝牙称为经典蓝牙。2010 年 SIG 联盟合并了 Wibree 联盟,并把 Wibree 联盟提出的低功耗无线技术从新命名为低功耗蓝牙技术(BLE)。2010 年发布的蓝牙 4.0 规格就同时包含经典蓝牙和低功耗蓝牙,只支持低功耗蓝牙技术的蓝牙称为低功率蓝牙,同时支持经典蓝牙和低功率蓝牙技术的蓝牙称为双模蓝牙。低功耗蓝牙与经典蓝牙技术是不兼容的,因此低功耗蓝牙和经典蓝牙二者之间是不能相互通讯的。android
经典蓝牙技术持续保持链接,能够传输大数据,适合文件传输、音频播放等,兼容性高,广播信道多,缺点是链接成本高,功耗高;低功耗蓝牙链接速度快,低功耗,广播信道少,缺点是数据传输量有限制。git
Android 平台包含蓝牙网络堆栈支持,凭借此项支持,设备能以无线方式与其余蓝牙设备交换数据。应用框架提供了经过 Android Bluetooth API 访问蓝牙功能的途径。针对具备低功耗要求的蓝牙设备,Android 4.3(API 级别 18)中引入了面向低功耗蓝牙的 API 支持。即 SPP 协议(经典蓝牙)和 GATT 协议(低功耗蓝牙)的链接方式。 使用 Android 蓝牙功能须要在 Manifest.xml 文件中声明蓝牙权限,若是使用了蓝牙扫描功能还须要声明位置权限,由于蓝牙是具备定位功能的,目标版本是 Android 23 及以上版本须要添加动态权限申请。github
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> // 蓝牙扫描须要位置权限 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 复制代码
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter() if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } 复制代码
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } 复制代码
mBluetoothAdapter.startDiscovery(); // Create a BroadcastReceiver for ACTION_FOUND private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } }; // Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy 复制代码
private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectThread(BluetoothDevice device) { // Use a temporary object that is later assigned to mmSocket, // because mmSocket is final BluetoothSocket tmp = null; mmDevice = device; // Get a BluetoothSocket to connect with the given BluetoothDevice try { // MY_UUID is the app's UUID string, also used by the server code tmp = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { } mmSocket = tmp; } public void run() { // Cancel discovery because it will slow down the connection mBluetoothAdapter.cancelDiscovery(); try { // Connect the device through the socket. This will block // until it succeeds or throws an exception mmSocket.connect(); tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException connectException) { // Unable to connect; close the socket and get out try { mmSocket.close(); } catch (IOException closeException) { } return; } // Do work to manage the connection (in a separate thread) manageConnectedSocket(mmSocket); } /** Will cancel an in-progress connection, and close the socket */ public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } } 复制代码
private ScanCallback mLeScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); } }; mHandler.postDelayed(new Runnable() { @Override public void run() { bluetoothLeScanner.stopScan(mLeScanCallback); } }, SCAN_PERIOD); bluetoothLeScanner.startScan(mLeScanCallback); 复制代码
// Various callback methods defined by the BLE API. private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; if (newState == BluetoothProfile.STATE_CONNECTED) { intentAction = ACTION_GATT_CONNECTED; connectionState = STATE_CONNECTED; Log.i(TAG, "Connected to GATT server."); Log.i(TAG, "Attempting to start service discovery:" + bluetoothGatt.discoverServices()); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { intentAction = ACTION_GATT_DISCONNECTED; connectionState = STATE_DISCONNECTED; Log.i(TAG, "Disconnected from GATT server."); } } @Override // New services discovered public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { } else { Log.w(TAG, "onServicesDiscovered received: " + status); } } @Override // Result of a characteristic read operation public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } } ... }; BluetoothGatt bluetoothGatt; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { bluetoothGatt = device.connectGatt(context, false, mGattCallback, BluetoothDevice.TRANSPORT_LE); } else { bluetoothGatt = device.connectGatt(context, false, mGattCallback); } 复制代码
其实 Android 蓝牙相关的 API 使用仍是比较简单的,对于初次接触蓝牙开发的小白来讲,弄清楚蓝牙设备的类型以及链接方式就成功了一半(经典蓝牙 SPP,低功耗蓝牙 GATT)。另一半在于蓝牙设备的适配及细节的掌握,适配问题能够多联系蓝牙设备供应商的技术支持,细节问题就靠平时积累和多搜索查阅资料了。 最后安利两个 BLE 开源库:RxAndroidBle、flutter_blue。markdown
@123lxw123, 本文版权属于再惠研发团队,欢迎转载,转载请保留出处。网络