android studio 藍芽透傳
阿新 • • 發佈:2019-02-13
藍芽透傳
關於藍芽透傳,基本步驟如下:
1、設定藍芽許可權
2、開啟藍芽
3、藍芽搜尋
4、藍芽連線與通訊
測試使用android4.4版本手機與藍芽4.0硬體模組;
1、設定藍芽許可權(android6.0以下)
藍芽許可權在AndroidManifest.xml中加入如下程式碼:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
如果想要只在支援BLE的安卓裝置上執行則需要再加如下:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
2、開啟藍芽
//開啟藍芽 public void ble_open() { //獲取藍芽介面卡例項 BluetoothAdapter ble_adapter = BluetoothAdapter.getDefaultAdapter(); if(ble_adapter !=null){ //判斷藍芽是否已開啟 if (!ble_adapter.isEnabled()) { //開啟藍芽,強制開啟,不安全 //ble_adapter.enable(); //彈窗詢問是否開啟,推薦,可以重新onActivityResult確認是否開啟 Intent ble_intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(ble_intent,0); } }else Toast.makeText(this, "該裝置不支援藍芽", Toast.LENGTH_SHORT).show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 0){ switch (resultCode){ case RESULT_OK: //藍芽開啟成功 break; case RESULT_CANCELED: //藍芽開啟失敗 break; } } }
3、藍芽搜尋
搜尋藍芽裝置有三種方法:
1、startLeScan(LeScanCallback)此方法適用於4.3以上版本,掃描結果通過實現BluetoothAdapter.LeScanCallback介面方法onLeScan來接收
2、此外startScan(ScanCallbackcallback)適用於5.0以上;
3、ble_adapter.startDiscovery()雖然說是相容經典藍芽和低功耗藍芽,但有些裝置無法檢測到低功耗藍芽;startDiscovery是一個非同步方法,其過程:系統傳送BluetoothAdapter.ACTIOINDISCOVERYSTARTED的廣播 ,然後搜到一個藍芽裝置就傳送一個BluetoothDevice.ACTIONFOUND的廣播,結束髮送BluetoothAdapter.ACTIONFINISHED的廣播,整個過程耗時12s,這也說明搜尋結果需要註冊一個廣播來接收;
public void ble_scan(View view) {
//判斷是否處於掃描狀態
if (isScan)
return;
//掃描時間設為10s
handler.postDelayed(new Runnable() {
@Override
public void run() {
ble_adapter.stopLeScan(MainActivity.this);
isScan = false;
}
}, 10000);
//開始掃描
if (ble_adapter.isEnabled()) {
ble_adapter.startLeScan(this);
isScan = true;
text_list.setVisibility(View.VISIBLE);
}
}
/**
* 返回掃描結果的回撥
* @param device 藍芽資訊相關類,可以獲取藍芽名稱,地址,繫結狀態等
* @param rssi 藍芽裝置訊號值,正常為負值,值越大訊號越強
* @param scanRecord 遠端裝置提供的配對號
*/
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device.getName().equals(ble_name)) {
BleDevice bleDevice = new BleDevice(device, rssi, false);
if (!ble_list.contains(bleDevice))
ble_list.add(bleDevice);
sendMSG(FIND_BLE_DEVICE);
ble_adapter.stopLeScan(this);
}
}
4、藍芽連線與通訊
//連線裝置
public void ble_connect(String address, final int position) {
BluetoothDevice device = ble_adapter.getRemoteDevice(address);
ble_gatt = device.connectGatt(this, true, new BluetoothGattCallback() {
//連線狀態改變回調
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
ble_list.get(position).setConnect(true);
sendMSG(CONNECT_SUCCESS);
//連線成功,開始搜尋服務,一定要呼叫此方法,否則獲取不到服務
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
ble_list.get(position).setConnect(false);
sendMSG(CONNECT_FAILED);
ble_gatt.close();
}
}
//發現服務時,呼叫回撥,表示可以通訊了
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
UUID service_UUID = Constants.CX21_SERVICE_UUID;
UUID characteristic_UUID = Constants.CX21_CHARACTERISTIC_UUID;
//通過UUID找到服務
ble_GattService = gatt.getService(service_UUID);
//找到服務後在通過UUID找到特徵
ble_Characteristic = ble_GattService.getCharacteristic(characteristic_UUID);
if (ble_Characteristic != null) {
//啟用onCharacteristicChanged(),用於接收資料
Boolean isTrue = gatt.setCharacteristicNotification(ble_Characteristic, true);
BluetoothGattDescriptor descriptor = ble_Characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
sendMSG(SERVICE_DISCOVERED);
} else {
sendMSG(SERVICE_DISCOVERED_FAILED);
return;
}
}
//由於遠端特徵通知而觸發的回撥
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
//使用的藍芽裝置傳送的是16進位制,需要處理,否則會亂碼
receive = bytesToHexString(characteristic.getValue());
sendMSG(RECEIVE_MSG);
}
//寫入成功的回撥
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if (BluetoothGatt.GATT_SUCCESS == status) {
sendMSG(WRITE_SUCCESS);
}
}
//讀取成功回撥
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if (BluetoothGatt.GATT_SUCCESS == status) {
String receive = "";
for (int i = 0; i < characteristic.getValue().length; i++) {
int v = characteristic.getValue()[i] & 0xFF;
receive += Integer.toHexString(v);
}
Log.e("connect", "read:" + receive);
}
}
});
}
1)、向藍芽模組寫資料如下:
String writeData = "00801001015A";
ble_Characteristic.setValue(getHexBytes(writeData));
gatt.writeCharacteristic(ble_Characteristic);
如果寫入成功會回撥onCharacteristicWrite方法;
2)、讀資料:
gatt.readCharacteristic(ble_Characteristic);
如果讀取成功,可以在onCharacteristicRead中獲取到資料;