对于IOS与OSXBLE:实例化CBCentralManager-为iOS编码感兴趣的读者,本文将提供您所需要的所有信息,并且为您提供关于AndroidBLEApp只能订阅1个BLE设备的特性通知、A
对于IOS 与 OSX BLE:实例化 CBCentralManager - 为 iOS 编码感兴趣的读者,本文将提供您所需要的所有信息,并且为您提供关于Android BLE App 只能订阅 1 个 BLE 设备的特性通知、Android BLE:连接和订阅 2 个 BLE 外围设备的特征通知、BLE 设备在通过 iOS 上的免提配置文件呼叫时断开连接,原因为 722 步骤系统诊断日志、bleManager.startDeviceScan 不适用于 iOS react-native-ble-plx的宝贵知识。
本文目录一览:- IOS 与 OSX BLE:实例化 CBCentralManager - 为 iOS 编码
- Android BLE App 只能订阅 1 个 BLE 设备的特性通知
- Android BLE:连接和订阅 2 个 BLE 外围设备的特征通知
- BLE 设备在通过 iOS 上的免提配置文件呼叫时断开连接,原因为 722 步骤系统诊断日志
- bleManager.startDeviceScan 不适用于 iOS react-native-ble-plx
IOS 与 OSX BLE:实例化 CBCentralManager - 为 iOS 编码
如何解决IOS 与 OSX BLE:实例化 CBCentralManager - 为 iOS 编码
我正在学习 iOS 与 OSX BLE。
我注意到我无法在 iOS 中实例化 CBCentralManager 因为:
[CoreBluetooth] xpc connection invalid
Unsupported
与通过 OSX 相比,因为 iOS 平台没有“应用沙盒”特性,我可以在其中设置为 BLE 使用。
这是我的 iOS 代码:
import SwiftUI
struct ContentView: View {
@Observedobject var bleManager = BLEManager()
var body: some View {
ZStack {
Color("Background")
Text("Hello")
}
}
}
class BLEManager: NSObject,ObservableObject,CBCentralManagerDelegate {
var centralManager: CBCentralManager!
override init() {
super.init()
centralManager = CBCentralManager(delegate: self,queue: nil)
}
public func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
print("power is on")
case .resetting:
print("Resetting")
case .unsupported:
print("Unsupported")
case .unauthorized:
print("UnAuthorized")
case .unkNown:
print("UnKNown")
case .poweredOff:
print("Powered OFF")
@unkNown default:
print("**** Default ****")
}
}
}
这是必需的 .plist 条目:
我知道 iPhone 可以是 BLE 中心或外围设备。
简单问题:如何为真正的 iOS CBCentralMaster 编码?
我只是在这里采取一些小步骤:为外围检测编码。
...然后从那里继续。
解决方法
您是在模拟器上运行(不受支持)而不是在设备上运行?
,查看主要的 Core Bluetooth 文档:
如果它的 Info.plist 不包含它需要访问的数据类型的使用说明键,你的应用就会崩溃。要访问 iOS 13 或之后链接的应用程序上的核心蓝牙 API,请包含 NSBluetoothAlwaysUsageDescription 键。在 iOS 12 及更早版本中,包含 NSBluetoothPeripheralUsageDescription 以访问蓝牙外设数据。
Android BLE App 只能订阅 1 个 BLE 设备的特性通知
如何解决Android BLE App 只能订阅 1 个 BLE 设备的特性通知
我是 Android 新手。我正在尝试从 2 个 BLE 设备订阅特征通知。现在,我的应用程序只能从第一个设备接收 BLE 数据。 我知道 BLE 是串行通信,所以我必须等到 onDescriptorWrite() 回调被调用,然后才能为第二个设备启用通知。我们每次只能有 1 个 GATT 操作。 我的问题是:
-
如何修改onDescriptorWrite()? Thread.sleep() 延迟方法没有帮助。
-
有些人提到使用队列来添加/删除某些东西?
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,boolean enabled,int device) {
if (mBluetoothAdapter == null || mBluetoothGatt == null || mBluetoothGatt1 == null) {
Log.e(TAG,"BluetoothAdapter not initialized");
return;
}
if(device == 0) {
mBluetoothGatt.setCharacteristicNotification(characteristic,enabled);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHaraCTERISTIC_CONfig));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printstacktrace();
}
Log.e(TAG,"Device #0 is done for notification!");
}
else if(device == 1){
mBluetoothGatt1.setCharacteristicNotification(characteristic,"Device #1 is done for notification!");
}
}
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt,int status,int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.e(TAG,"Connected to GATT server #0.");
// Attempts to discover services after successful connection.
Log.e(TAG,"Attempting to start service discovery #0:" + mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_disCONNECTED) {
intentAction = ACTION_GATT_disCONNECTED;
mConnectionState = STATE_disCONNECTED;
Log.e(TAG,"disconnected from GATT server #0.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesdiscovered(BluetoothGatt gatt,int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_disCOVERED);
} else {
Log.e(TAG,"onServicesdiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE,characteristic,0);
}
try {
Thread.sleep(700);
}catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
Log.e(TAG,"onCHAR READ");
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE,0);
try {
Thread.sleep(700);
}catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
Log.e(TAG,"onCharacteristicChanged #0 = ACTION_DATA_AVAILABLE,Done! ");
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt,BluetoothGattDescriptor descriptor,int status) {
super.onDescriptorWrite(gatt,descriptor,status);
// Do something here ????????????
// Thread.sleep() delay method doesn''t help
try {
Thread.sleep(700);
}catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
Log.e(TAG,"onDescriptorWrite #0,Done! ");
}
};
解决方法
mBluetoothGatt1.setCharacteristicNotification(characteristic,enabled);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
我认为应该是:
mBluetoothGatt1.setCharacteristicNotification(characteristic,enabled);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt1.writeDescriptor(descriptor);
Android BLE:连接和订阅 2 个 BLE 外围设备的特征通知
如何解决Android BLE:连接和订阅 2 个 BLE 外围设备的特征通知
我使用了两个 BLE 外围传感器和 1 个手机(中央)。每个 BLE 外围设备都运行良好(单独测试)。
我遵循了 BluetoothLeGatt> 示例。我的手机是HUAWEI Mate 10,使用Android 10版本,支持BLE 4.2。
在我的 Android BLE 应用程序中,按下第一页上的连接按钮后,应用程序将自动连接到名称为“BC805M BLE ADC1”和“BC805M BLE ADC2”的 2 个 BLE 设备。
该应用程序似乎可以成功连接 2 个 BLE 设备。但是,没有收到数据(订阅特征通知失败)。 BluetoothGattCallback.onCharacteristicChanged() 方法永远不会被触发。因此,该操作永远不会变为“ACTION_DATA_AVAILABLE”。
BLE App screenshot 1
BLE App screenshot 2
我知道 BLE 通信是串行的。有些人建议在 BluetoothGattCallback() 中使用“onDescriptorWrite()”。但是,我不完全了解如何做到这一点。我在这里附上了我的 Android Studio 项目。如果有人能找到问题,我们将不胜感激。
public class DeviceControlActivity extends Activity {
private final static String TAG = DeviceControlActivity.class.getSimpleName();
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
public static final String NUMBER_OF_DEVICE = "NUMBER OF DEVICE";
public static final String EXTRAS_DEVICE_NAME_1 = "DEVICE_NAME1";
public static final String EXTRAS_DEVICE_ADDRESS_1 = "DEVICE_ADDRESS1";
public static final String NUMBER_OF_DEVICE_1 = "NUMBER OF DEVICE1";
private TextView mConnectionState;
private TextView mdatafield;
private TextView mThumb;
private TextView mIndex;
private TextView mThumb1;
private TextView mIndex1;
private String mDeviceName;
private String mDeviceAddress;
private String mDeviceName1;
private String mDeviceAddress1;
private int DEVICE_NUMBER;
private int DEVICE_NUMBER1;
private int TOTAL_DEVICE;
private BluetoothLeService mBluetoothLeService;
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattcharacteristics =
new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattcharacteristics1 =
new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private BluetoothGattCharacteristic mNotifyCharacteristic1;
private final String ServiceUUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
private final String CharUUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName,IBinder service) {
Log.d(TAG,"Service Connected Called");
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
finish();
}
mBluetoothLeService.connect(mDeviceAddress,0);
mBluetoothLeService.connect(mDeviceAddress1,1);
}
@Override
public void onServicedisconnected(ComponentName componentName) {
Log.d(TAG,"Service disConnected Called");
mBluetoothLeService = null;
}
};
private final broadcastReceiver mGattUpdateReceiver = new broadcastReceiver() {
@Override
public void onReceive(Context context,Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
Log.e(TAG,"ACTION_GATT_CONNECTED ");
} else if (BluetoothLeService.ACTION_GATT_disCONNECTED.equals(action)) {
Log.e(TAG,"WHEN IS ACTION GATT disCONNECTED");
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
Log.e(TAG,"ACTION_GATT_disCONNECTED ");
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_disCOVERED.equals(action)) {
Log.e(TAG,"ACTION_GATT_SERVICE_disCOVERED ");
updateGattServices(mBluetoothLeService.getSupportedGattServices(0),0);
try {
Thread.sleep(700);
}catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
Log.e(TAG,"getSupportedGattServices() is done for device #0");
updateGattServices(mBluetoothLeService.getSupportedGattServices(1),1);
try {
Thread.sleep(700);
}catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
Log.e(TAG,"getSupportedGattServices() is done for device #1");
updateDATA();
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
Log.d(TAG,"ACTION_DATA_AVAILABLE ");
mBluetoothLeService.readCharacteristic(mNotifyCharacteristic,0);
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA),0);
mBluetoothLeService.readCharacteristic(mNotifyCharacteristic1,1);
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA1),1);
}
}
};
private final boolean updateDATA(){
int servicePos = 0;
int charPos = 0;
if(mGattcharacteristics!=null&&mGattcharacteristics.size()!=0){
final BluetoothGattCharacteristic characteristic = mGattcharacteristics.get(servicePos).get(charPos);
final int charPro = characteristic.getProperties();
if((charPro|BluetoothGattCharacteristic.PROPERTY_READ)>0){
if(mNotifyCharacteristic!= null){
mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic,false,0);
}
}
mBluetoothLeService.readCharacteristic(characteristic,0);
if ((charPro | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
Log.d(TAG,"PROPER_NOTIFY > 0");
Log.d(TAG," ");
}
return true;
}
return false;
}
private void clearUI() {
mdatafield.setText(R.string.no_data);
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.e(TAG,"2.2 onCreate() starts! ");
super.onCreate(savedInstanceState);
setContentView(R.layout.gatt_services_characteristics);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
mDeviceName1 = intent.getStringExtra(EXTRAS_DEVICE_NAME_1);
mDeviceAddress1=intent.getStringExtra(EXTRAS_DEVICE_ADDRESS_1);
DEVICE_NUMBER=intent.getIntExtra(NUMBER_OF_DEVICE,0);
DEVICE_NUMBER1=intent.getIntExtra(NUMBER_OF_DEVICE_1,0);
((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress+" AND "+mDeviceAddress1);
mConnectionState = (TextView) findViewById(R.id.connection_state);
mdatafield = (TextView) findViewById(R.id.data_value);
mThumb = (TextView) findViewById(R.id.Thumb);
mIndex = (TextView) findViewById(R.id.Index);
mThumb1 = (TextView) findViewById(R.id.Thumb1);
mIndex1 = (TextView) findViewById(R.id.Index1);
Log.d(TAG,"MY DEVICE NAME "+mDeviceName);
Log.d(TAG,"MY DEVICE ADDRESS "+mDeviceAddress);
Log.d(TAG,"MY DEVICE NUMBER "+DEVICE_NUMBER);
Log.d(TAG,"MY DEVICE NAME1 "+mDeviceName1);
Log.d(TAG,"MY DEVICE ADDRESS1 "+mDeviceAddress1);
Log.d(TAG,"MY DEVICE NUMBER1 "+DEVICE_NUMBER1);
getActionBar().setTitle(mDeviceName+" "+mDeviceName1);
getActionBar().setdisplayHomeAsUpEnabled(true);
Intent gattServiceIntent = new Intent(this,BluetoothLeService.class);
bindService(gattServiceIntent,mServiceConnection,BIND_AUTO_CREATE);
}
@Override
protected void onResume() {
Log.e(TAG,"2.2 onResume is Called");
super.onResume();
registerReceiver(mGattUpdateReceiver,makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
boolean result = mBluetoothLeService.connect(mDeviceAddress,0);
boolean result1 = mBluetoothLeService.connect(mDeviceAddress1,1);
Log.d(TAG,"Connect request result = " + result+" "+result1);
}
}
@Override
protected void onPause() {
Log.d(TAG,"onPause is called");
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
}
@Override
protected void onDestroy() {
Log.d(TAG,"onDestroy is Called");
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_services,menu);
if (mConnected) {
menu.findItem(R.id.menu_connect).setVisible(false);
menu.findItem(R.id.menu_disconnect).setVisible(true);
} else {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(false);
}
return true;
}
@Override
public boolean onoptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
mBluetoothLeService.connect(mDeviceAddress,0);
mBluetoothLeService.connect(mDeviceAddress1,1);
return true;
case R.id.menu_disconnect:
Log.d(TAG,"FirsT DEVICE"+DEVICE_NUMBER);
mBluetoothLeService.disconnect();
return true;
case android.R.id.home:
Log.d(TAG,"HOME IS pressed");
onBackpressed();
return true;
}
return super.onoptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mConnectionState.setText(resourceId);
}
});
}
private void displayData(String data,int device) {
if (data != null && device ==0) {
mThumb1.setText(data.substring(1,4));
mIndex1.setText(data.substring(5,8));
}
else if(data != null && device == 1) {
mThumb.setText(data.substring(1,4));
mIndex.setText(data.substring(5,8));
}
}
private void updateGattServices(List<BluetoothGattService> gattServices,int device) {
if (gattServices == null) return;
String uuid = null;
String unkNownServiceString = getResources().getString(R.string.unkNown_service);
String unkNownCharaString = getResources().getString(R.string.unkNown_characteristic);
ArrayList<HashMap<String,String>> gattServiceData = new ArrayList<HashMap<String,String>>();
if(device ==0) {
mGattcharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
Log.e(TAG,"mGattcharacteristics is created for device #0");
}
else if(device ==1) {
mGattcharacteristics1 = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
Log.e(TAG,"mGattcharacteristics is created for device #1");
}
int i=0;
int j=0;
// Loops through available GATT Services.
Log.e(TAG,"Start For Loop");
for (BluetoothGattService gattService : gattServices) {
Log.e(TAG,"Service index = " + i);
HashMap<String,String> currentServiceData = new HashMap<String,String>();
uuid = gattService.getUuid().toString();
if(uuid.equals(ServiceUUID)) {
Log.e(TAG,"Selected Service index = " + i);
currentServiceData.put(LIST_NAME,SampleGattAttributes.lookup(uuid,unkNownServiceString));
currentServiceData.put(LIST_UUID,"");
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String,String>> gattCharacteristicGroupData = new ArrayList<HashMap<String,String>>();
List<BluetoothGattCharacteristic> gattcharacteristics = gattService.getcharacteristics();
ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();
// Loops through available characteristics.
for (BluetoothGattCharacteristic gattCharacteristic : gattcharacteristics) {
Log.e(TAG,"Characteristic index = " + j);
charas.add(gattCharacteristic);
HashMap<String,String> currentCharaData = new HashMap<String,String>();
uuid = gattCharacteristic.getUuid().toString();
if(uuid.equals(CharUUID)) {
Log.e(TAG,"Selected Characteristic index = " + j);
currentCharaData.put(
LIST_NAME,unkNownCharaString));
currentCharaData.put(LIST_UUID,"");
gattCharacteristicGroupData.add(currentCharaData);
if(device ==0){
mNotifyCharacteristic=gattCharacteristic;
}
else if(device ==1){
mNotifyCharacteristic1=gattCharacteristic;
}
}
j = j +1;
}
if(device ==0){
mGattcharacteristics.add(charas);
}
else if(device ==1){
mGattcharacteristics1.add(charas);
}
}
i = i + 1 ;
}
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_disCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_disCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
}
public class BluetoothLeService extends Service {
private final static String TAG = BluetoothLeService.class.getSimpleName();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private String mBluetoothDeviceAddress1;
private BluetoothGatt mBluetoothGatt;
private BluetoothGatt mBluetoothGatt1;
private int mConnectionState = STATE_disCONNECTED;
private static final int STATE_disCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
public final static String ACTION_GATT_CONNECTED =
"com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_disCONNECTED =
"com.example.bluetooth.le.ACTION_GATT_disCONNECTED";
public final static String ACTION_GATT_SERVICES_disCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_disCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
"com.example.bluetooth.le.EXTRA_DATA";
public final static String EXTRA_DATA1 =
"com.example.bluetooth.le.EXTRA_DATA1";
public final static UUID ServiceUUID2 = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
public final static UUID CharUUID2 = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
// Implements callback methods for GATT events that the app cares about. For example,// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt,int status,int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.e(TAG,"Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.e(TAG,"Attempting to start service discovery:" + mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_disCONNECTED) {
intentAction = ACTION_GATT_disCONNECTED;
mConnectionState = STATE_disCONNECTED;
Log.e(TAG,"disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesdiscovered(BluetoothGatt gatt,int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_disCOVERED);
} else {
Log.e(TAG,"onServicesdiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE,characteristic,0);
}
Log.e(TAG,"onCHAR READ");
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE,0);
Log.e(TAG,"onCharacteristicChanged #0 = ACTION_DATA_AVAILABLE,Done! ");
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt,BluetoothGattDescriptor descriptor,int status) {
super.onDescriptorWrite(gatt,descriptor,status);
Log.e(TAG,"onDescriptorWrite #0,Done! ");
}
};
private final BluetoothGattCallback mGattCallback1 = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt,"Connected to GATT server.");
Log.e(TAG,"Attempting to start service discovery:" +
mBluetoothGatt1.discoverServices());
} else if (newState == BluetoothProfile.STATE_disCONNECTED) {
intentAction = ACTION_GATT_disCONNECTED;
mConnectionState = STATE_disCONNECTED;
Log.e(TAG,1);
}
Log.e(TAG,"onCHAR READ in callback 1");
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,1);
Log.e(TAG,int status) {
Log.e(TAG,"onDescriptorWrite starts");
if (descriptor.getUuid().equals(SampleGattAttributes.CLIENT_CHaraCTERISTIC_CONfig)) {
BluetoothGattCharacteristic characteristic = gatt
.getService(ServiceUUID2)
.getCharacteristic(CharUUID2);
gatt.readCharacteristic(characteristic);
}
Log.e(TAG,"onDescriptorWrite #1,Done!");
}
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendbroadcast(intent);
}
private void broadcastUpdate(final String action,final BluetoothGattCharacteristic characteristic,int device) {
final Intent intent = new Intent(action);
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0&&device ==0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ",byteChar));
String DATA = stringBuilder.toString();
Log.d(TAG,"MY DATA IN HEX " + DATA);
String DecData =HexAsciiConverter.HexAscii2Decimal(DATA);
Log.d(TAG,"MY DATA IN DECIMAL "+ DecData);
intent.putExtra(EXTRA_DATA," " + DecData);
}
else if( data != null && data.length > 0 && device ==1 ){
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ","MY DATA IN DECIMAL "+ DecData);
intent.putExtra(EXTRA_DATA1," " + DecData);
}
sendbroadcast(intent);
}
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
close();
return super.onUnbind(intent);
}
private final IBinder mBinder = new LocalBinder();
public boolean initialize() {
// For API level 18 and above,get a reference to BluetoothAdapter through
// BluetoothManager.
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUetoOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e(TAG,"Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG,"Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
public boolean connect(final String address,int devicenum) {
if (mBluetoothAdapter == null || address == null) {
Log.e(TAG,"BluetoothAdapter not initialized or unspecified address.");
return false;
}
// PrevIoUsly connected device. Try to reconnect.
if ((mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress))
|| (mBluetoothDeviceAddress1!=null && address.equals(mBluetoothDeviceAddress1))) {
Log.e(TAG,"Trying to use an existing mBluetoothGatt for connection.");
if (devicenum==0&&mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
}
else if(devicenum==1 && mBluetoothGatt1.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
}
else{
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.e(TAG,"Device not found. Unable to connect.");
return false;
}
if(devicenum==0){
mBluetoothGatt1 = device.connectGatt(this,mGattCallback);
mBluetoothDeviceAddress= address;
mConnectionState = STATE_CONNECTING;
Log.e(TAG,"GATT CALLBACK #0 ! "+address);
}
else if(devicenum ==1){
mBluetoothGatt = device.connectGatt(this,mGattCallback1);
mBluetoothDeviceAddress1=address;
mConnectionState = STATE_CONNECTING;
Log.e(TAG,"GATT CALLBACK #1 ! "+address);
}
Log.e(TAG,"Trying to create a new connection.");
return true;
}
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.e(TAG,"BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
if(mBluetoothGatt1!=null){
mBluetoothGatt1.disconnect();
}
}
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt1.close();
mBluetoothGatt1 = null;
mBluetoothGatt = null;
}
public void readCharacteristic(BluetoothGattCharacteristic characteristic,int device) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.e(TAG,"BluetoothAdapter not initialized");
return;
}
if (device == 0) {
mBluetoothGatt.readCharacteristic(characteristic);
}
else if(device ==1){
mBluetoothGatt1.readCharacteristic(characteristic);
}
}
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,boolean enabled,"BluetoothAdapter not initialized");
return;
}
if(device == 0) {
mBluetoothGatt.setCharacteristicNotification(characteristic,enabled);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHaraCTERISTIC_CONfig));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printstacktrace();
}
Log.e(TAG,"Device #0 is done for notification!");
}
else if(device == 1){
mBluetoothGatt1.setCharacteristicNotification(characteristic,"Device #1 is done for notification!");
}
}
public List<BluetoothGattService> getSupportedGattServices(int device) {
if (mBluetoothGatt == null) return null;
if(device ==0) {
return mBluetoothGatt.getServices();
}
else {
return mBluetoothGatt1.getServices();
}
}
}
BLE 设备在通过 iOS 上的免提配置文件呼叫时断开连接,原因为 722 步骤系统诊断日志
如何解决BLE 设备在通过 iOS 上的免提配置文件呼叫时断开连接,原因为 722 步骤系统诊断日志
我们开发了自己的 BLE 设备并连接到 iPhone。我们发现通过 HFP 进行并行呼叫时,它会在 2 到 3 分钟后断开连接的问题。 (例如:使用汽车音响系统、信息娱乐 HUD 等)。
有谁知道 722
代表什么状态。我们如何解决这个问题? 谢谢。
步骤
iPhone
连接到Our Device
(在后台模式下持续收集数据。)iPhone
连接到Car Audio Systems
iPhone
使用 IM 应用(通过 HFP)拨打电话。- 2 ~ 3 分钟后,
iPhone
和Our Device
之间的连接因722
原因断开。
系统诊断日志
default 2021-02-09 17:04:57.813721 +0800 bluetoothd Server.LE.Connection LE Link disconnected for handle 0x14c804720 address <private> with reason 722 encryptionPending 0
default 2021-02-09 17:04:57.813774 +0800 bluetoothd Server.LE.Connection LE ConnManager disconnection complete reason 722 address=<private> localRole=Master
default 2021-02-09 17:04:57.816296 +0800 bluetoothd Stack.GATT _GATT_LE_disconnectedCB on handle 0x000000014C804720 with reason STATUS 722
default 2021-02-09 17:04:57.816977 +0800 bluetoothd Server.LE Device "E2278A91-B7B6-2122-696C-BE887487C8D7" set last connected time to 1612890297
default 2021-02-09 17:04:57.820707 +0800 bluetoothd Stack.CL Removing peer ID 0 for handle 0x000000014C804720
default 2021-02-09 17:04:57.820869 +0800 bluetoothd Stack.HCI Releasing LE connection 0x0041
default 2021-02-09 17:04:57.822551 +0800 bluetoothd Server.LE.Connection Device "E2278A91-B7B6-2122-696C-BE887487C8D7" does not require low latency
default 2021-02-09 17:04:57.822580 +0800 bluetoothd Server.LE.Connection Found link-ready device calling disconnection notification
default 2021-02-09 17:04:57.822582 +0800 bluetoothd Server.LE.Connection disconnected from device "E2278A91-B7B6-2122-696C-BE887487C8D7" successfully (locally-initiated)
default 2021-02-09 17:04:57.822585 +0800 bluetoothd Server.LE.Connection linkReady:1 disconnectDevice:0 localRole:0 reason:722 result:0
default 2021-02-09 17:04:57.824928 +0800 bluetoothd Server.LE.Security Removing temporary security keys for device <private>
bleManager.startDeviceScan 不适用于 iOS react-native-ble-plx
如何解决bleManager.startDeviceScan 不适用于 iOS react-native-ble-plx
我正在尝试使用 react-native-ble-plx 将网关与 React 本机应用程序配对。 下面的源代码在 Android 中运行良好,而在 iOS 中,bleManager.startDeviceScan() 不会被触发。这一步之后什么都没有发生。
非常感谢任何帮助!
源代码:
const connectBLE = () => {
const subscription = bleManager.onStateChange(async (state) => {
if (state === ''PoweredOn'') {
subscription.remove();
scanAndConnect();
}
};
}
const scanAndConnect = () => {
bleManager.startDeviceScan(null,null,async (error,device) => {
if (error) {
showToast(error,''error'');
console.log(''Handle error - scanning will be stopped automatically'');
return;
}
console.log(''Devices'');
console.log(device.name);
// Check if it is a device you are looking for based on device name
if (device.name === "BLE_0006") {
// Stop scanning as we have found the device.
bleManager.stopDeviceScan();
// Establish Device connection.
device
.connect()
.then((deviceData) => {
/** Show Toast on Device disconnect */
bleManager.onDevicedisconnected(
deviceData.id,(connectionError,connectionData) => {
if (connectionError) {
console.log(connectionError);
}
console.log(''Device is disconnected'');
console.log(connectionData);
},);
/** discover All Services and characteristics */
return device.discoverAllServicesAndcharacteristics();
})
.then(async (deviceObject) => {
console.log(''deviceObject'');
console.log(deviceObject);
/** Subscribe for the Readable service */
device.monitorCharacteristicForService(
Enum.bleConnectionInfo.customServiceUUID,Enum.bleConnectionInfo.readCharacteristicUUID,(error,characteristic) => {
if (error) {
console.log(''Error in monitorCharacteristicForService'');
console.log(error.message);
return;
}
console.log(characteristic.uuid,characteristic.value);
]);
},);
})
.catch((error) => {
console.warn(error);
showToast(error,''error'');
});
}
});
}
解决方法
这可能对某人有帮助!
通过将 bleManager() 初始化移到功能组件之外解决了该问题。
关于IOS 与 OSX BLE:实例化 CBCentralManager - 为 iOS 编码的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Android BLE App 只能订阅 1 个 BLE 设备的特性通知、Android BLE:连接和订阅 2 个 BLE 外围设备的特征通知、BLE 设备在通过 iOS 上的免提配置文件呼叫时断开连接,原因为 722 步骤系统诊断日志、bleManager.startDeviceScan 不适用于 iOS react-native-ble-plx的相关知识,请在本站寻找。
本文标签: