永远不会调用onServicesDiscovered(BluetoothGatt gatt,int status)

编程入门 行业动态 更新时间:2024-10-22 05:01:40
本文介绍了永远不会调用onServicesDiscovered(BluetoothGatt gatt,int status)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个从IntentService调用的BluetoothLeService. BLEService在连接之前可以正常工作.与iBeacon建立连接后,它将调用;

I have a BluetoothLeService which is called from IntentService. BLEService works fine until it connects. After it establishes the connection with iBeacon, it calls ;

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.i(TAG, "Connected to GATT server."); // Attempts to discover services after successful connection. Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { intentAction = ACTION_GATT_DISCONNECTED; mConnectionState = STATE_DISCONNECTED; Log.i(TAG, "Disconnected from GATT server."); broadcastUpdate(intentAction); } }

到目前为止,一切都还可以,但是在那之后,尽管mBluetoothGatt.discoverServices()返回true,但永不调用onServicesDiscovered(BluetoothGatt gatt,int status).

Everything is okay so far but after that point in spite of mBluetoothGatt.discoverServices() returns true, onServicesDiscovered(BluetoothGatt gatt, int status) is never called.

--------------------- UPDATE ---------------------- ------------

在调试时,它显示newState == BluetoothProfile.STATE_CONNECTED,但实际上并没有连接.对于属于不存在的设备的伪造id也会显示相同的结果.

On debug it shows newState == BluetoothProfile.STATE_CONNECTED but it does not really connect. It shows same result for fake ids which are belong to unexist devices.

-------------------------------------------- -----------------

这是我的回叫

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.i(TAG, "Connected to GATT server."); // Attempts to discover services after successful connection. Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { intentAction = ACTION_GATT_DISCONNECTED; mConnectionState = STATE_DISCONNECTED; Log.i(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.w(TAG, "onServicesDiscovered received: " + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } };

我的广播接收器

// Handles various events fired by the Service. // ACTION_GATT_CONNECTED: connected to a GATT server. // ACTION_GATT_DISCONNECTED: disconnected from a GATT server. // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services. // ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read // or notification operations. 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)) { } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { // Show all the supported services and characteristics on the user interface. mBluetoothLeService.getbattery(); } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { batteryLevels.add(Double.valueOf(intent.getStringExtra(BluetoothLeService.EXTRAS_DEVICE_BATTERY))); } } }; 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; }

我的BluetoothLeService类

My BluetoothLeService class

import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.UUID; /** * Service for managing connection and data communication with a GATT server hosted on a * given Bluetooth LE device. */ public class BluetoothLeService extends Service { private final static String TAG = BluetoothLeService.class.getSimpleName(); private BluetoothManager mBluetoothManager; private BluetoothAdapter mBluetoothAdapter; private String mBluetoothDeviceAddress; private BluetoothGatt mBluetoothGatt; 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 EXTRAS_DEVICE_BATTERY = "EXTRAS_DEVICE_BATTERY"; public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT); private static final UUID Battery_Service_UUID = UUID.fromString("0000180F-0000-1000-8000-00805f9b34fb"); private static final UUID Battery_Level_UUID = UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb"); // 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.i(TAG, "Connected to GATT server."); // Attempts to discover services after successful connection. Log.i(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices()); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { intentAction = ACTION_GATT_DISCONNECTED; mConnectionState = STATE_DISCONNECTED; Log.i(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.w(TAG, "onServicesDiscovered received: " + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } }; private void broadcastUpdate(final String action) { final Intent intent = new Intent(action); sendBroadcast(intent); } private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) { final Intent intent = new Intent(action); Log.v(TAG, "characteristic.getStringValue(0) = " + characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)); intent.putExtra(EXTRAS_DEVICE_BATTERY, characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)); sendBroadcast(intent); } public class LocalBinder extends Binder { BluetoothLeService getService() { return BluetoothLeService.this; } } public void getbattery() { Set pairedDevices = mBluetoothAdapter.getBondedDevices(); BluetoothGattService batteryService = mBluetoothGatt.getService(Battery_Service_UUID); List<BluetoothGattService> servicesList; servicesList = getSupportedGattServices(); Iterator<BluetoothGattService> iter = servicesList.iterator(); while (iter.hasNext()) { BluetoothGattService bService = (BluetoothGattService) iter.next(); if (bService.getUuid().toString().equals(Battery_Level_UUID)){ batteryService = bService; } } if(batteryService == null) { Log.d(TAG, "Battery service not found!"); return; } BluetoothGattCharacteristic batteryLevel = batteryService.getCharacteristic(Battery_Level_UUID); if(batteryLevel == null) { Log.d(TAG, "Battery level not found!"); return; } mBluetoothGatt.readCharacteristic(batteryLevel); Log.v(TAG, "batteryLevel = " + mBluetoothGatt.readCharacteristic(batteryLevel)); } @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public boolean onUnbind(Intent intent) { // After using a given device, you should make sure that BluetoothGatt.close() is called // such that resources are cleaned up properly. In this particular example, close() is // invoked when the UI is disconnected from the Service. close(); return super.onUnbind(intent); } private final IBinder mBinder = new LocalBinder(); /** * Initializes a reference to the local Bluetooth adapter. * * @return Return true if the initialization is successful. */ 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; } /** * Connects to the GATT server hosted on the Bluetooth LE device. * * @param address The device address of the destination device. * * @return Return true if the connection is initiated successfully. The connection result * is reported asynchronously through the * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} * callback. */ public boolean connect(final String address) { if (mBluetoothAdapter == null || address == null) { Log.w(TAG, "BluetoothAdapter not initialized or unspecified address."); return false; } // Previously connected device. Try to reconnect. if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) { Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection."); if (mBluetoothGatt.connect()) { mConnectionState = STATE_CONNECTING; return true; } else { return false; } } final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); if (device == null) { Log.w(TAG, "Device not found. Unable to connect."); return false; } // We want to directly connect to the device, so we are setting the autoConnect // parameter to false. mBluetoothGatt = device.connectGatt(this, false, mGattCallback); Log.d(TAG, "Trying to create a new connection."); mBluetoothDeviceAddress = address; mConnectionState = STATE_CONNECTING; return true; } /** * Disconnects an existing connection or cancel a pending connection. The disconnection result * is reported asynchronously through the * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} * callback. */ public void disconnect() { if (mBluetoothAdapter == null || mBluetoothGatt == null) { Log.w(TAG, "BluetoothAdapter not initialized"); return; } mBluetoothGatt.close(); } /** * After using a given BLE device, the app must call this method to ensure resources are * released properly. */ public void close() { if (mBluetoothGatt == null) { return; } mBluetoothGatt.close(); mBluetoothGatt = null; } /** * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)} * callback. * * @param characteristic The characteristic to read from. */ public void readCharacteristic(BluetoothGattCharacteristic characteristic) { if (mBluetoothAdapter == null || mBluetoothGatt == null) { Log.w(TAG, "BluetoothAdapter not initialized"); return; } mBluetoothGatt.readCharacteristic(characteristic); } public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if(status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } } /** * Enables or disables notification on a give characteristic. * * @param characteristic Characteristic to act on. * @param enabled If true, enable notification. False otherwise.*/ public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) { if (mBluetoothAdapter == null || mBluetoothGatt == null) { Log.w(TAG, "BluetoothAdapter not initialized"); return; } mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); // This is specific to Heart Rate Measurement. if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) { BluetoothGattDescriptor descriptor = characteristic.getDescriptor( UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG)); descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); mBluetoothGatt.writeDescriptor(descriptor); } if (Battery_Level_UUID.equals(characteristic.getUuid())) { BluetoothGattDescriptor descriptor = characteristic.getDescriptor( UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG)); descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); mBluetoothGatt.writeDescriptor(descriptor); } } /** * Retrieves a list of supported GATT services on the connected device. This should be * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully. * * @return A {@code List} of supported services. */ public List<BluetoothGattService> getSupportedGattServices() { if (mBluetoothGatt == null) return null; return mBluetoothGatt.getServices(); } }

推荐答案

我知道了.真正的问题是连接.它显示好像已连接,但未连接,我尝试使用错误的地址进行连接,但仍保持连接.

I figured it out. The real problem is connection. It shows like it is connected but it is not, I tried to connect with false address and it still connected.

添加后

mBluetoothGatt.connect();

BluetoothLeService.java的connect方法结束时,它开始起作用.

at the end of connect method of BluetoothLeService.java it started to work.

感谢Vikram Ezhil的帮助

Thanks for helps Vikram Ezhil

更多推荐

永远不会调用onServicesDiscovered(BluetoothGatt gatt,int status)

本文发布于:2023-11-26 20:58:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1635171.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:永远不会   onServicesDiscovered   BluetoothGatt   status   int

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!