0

我试图连接到外设。当我在Scancallback中找到想要的设备时,我会向设备发送一条带有设备的消息。尝试连接BluetoothGatt时未处理的回调异常

11-16 10:31:12.471 25907-25907/I/BleManager: START SCAN 
11-16 10:31:12.471 25907-25907/ D/BluetoothAdapter: startLeScan(): null 
11-16 10:31:12.481 25907-25918/ D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5 
11-16 10:31:12.731 25907-25918/ W/BleOlderScanCallback: Try to connect device 
11-16 10:31:12.731 25907-25907/ I/BleManager: STOP SCAN 
11-16 10:31:12.731 25907-25907/ D/BluetoothAdapter: stopLeScan() 
11-16 10:31:12.741 25907-25907/ I/BleManager: connect device 
11-16 10:31:12.741 25907-25907/ I/Runnable: connectGatt 
11-16 10:31:12.741 25907-25907/ D/BluetoothGatt: connect() - device: [hidden], auto: false 
11-16 10:31:12.741 25907-25907/ D/BluetoothGatt: registerApp() 
11-16 10:31:12.741 25907-25907/ D/BluetoothGatt: registerApp() - UUID=[hidden] 
11-16 10:31:12.751 25907-25919/ D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5 
11-16 10:31:15.441 25907-25918/ D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=[hidden] 
11-16 10:31:15.441 25907-25918/ W/BluetoothGatt: Unhandled exception in callback java.lang.NullPointerException 

     at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:168) 
     at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:71) 
     at android.os.Binder.execTransact(Binder.java:404) 
     at dalvik.system.NativeStart.run(Native Method) 

这里是我的代码:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 

public class BleOlderScanCallback implements BluetoothAdapter.LeScanCallback { 

    private static final String TAG = BleOlderScanCallback.class.getSimpleName(); 

    private static final int START_BYTE_I = 2; 
    private static final int MAC_BYTE_I = 7; 
    private static final int MAC_SIZE = 6; 

    private Handler handler; 
    private String mac; 

    public BleOlderScanCallback(Handler handler, String mac) { 
     this.handler = handler; 
     this.mac = mac; 
    } 
    protected void onResult(BluetoothDevice device, byte[] scanRecord){ 
     byte[] macBytes; 
     String mac; 

     if (device != null && scanRecord != null) { 
      macBytes = new byte[MAC_SIZE]; 
      System.arraycopy(scanRecord, MAC_BYTE_I, macBytes, 0, MAC_SIZE); // copy MAC_SIZE positions (since index MAC_BYTE_I) of array scanRecord to array mac 
      mac = formatMAC(macBytes); 

      Logg.i(TAG, mac + " device: " + device.getName()); 
      if (this.mac.equals(mac)) { 
       Logg.w(TAG, "Try to connect device"); 
       handler.obtainMessage(BleHandler.SCANNED_DEVICE, device).sendToTarget(); 
      } 
      else{ 
       Logg.i(TAG, "Other mac "); 
      } 
     } 
    } 

    /** 
    * API lower Lollipop (21) 
    * @param device 
    * @param rssi 
    * @param scanRecord 
    */ 
    @Override 
    public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { 
     onResult(device, scanRecord); 
    } 
} 

这里是我的处理程序。它要求我的经理类连接BluetoothGatt

public class BleHandler extends Handler { 
    private static final String TAG = BleHandler.class.getSimpleName(); 

    public static final int SCANNED_DEVICE = 1; 

    private BleManager bleManager; // should I use WeakReference? 

    public BleHandler (BleManager bleManager){ 
     this.bleManager = bleManager; 
    } 

    @Override 
    public void handleMessage(Message message){ 
     BluetoothDevice device; 
     switch (message.what){ 
      case SCANNED_DEVICE: 
       bleManager.stopBtScan(); 
       device = (BluetoothDevice) message.obj; 
       bleManager.connect(device); 
       break; 
     } 
    } 
} 

而且在我管理器类,连接方法是这样的:

public void connect(final BluetoothDevice device){ 
    Logg.i(TAG, "connect device"); 
    if (device == null){ 
     Logg.i(TAG, "device to connect is null"); 
     return; 
    } 
    Handler handler = new Handler(context.getMainLooper()); 
    handler.post(new Runnable() { 
     @Override 
     public void run() { 
      Logg.i("Runnable", "connectGatt"); 
      bluetoothGatt = device.connectGatt(context, false, bluetoothGattCallback); 
     } 
    }); 
} 

我重写BluetoothGatt.onConnectionStateChange,但执行不来到这里

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 
public class BleGattCallback extends BluetoothGattCallback { 
    private static final String TAG = BleGattCallback.class.getSimpleName(); 


    private int connectionState = STATE_DISCONNECTED; 

    protected static final int STATE_DISCONNECTED = 0; 
    protected static final int STATE_CONNECTING = 1; 
    protected static final int STATE_CONNECTED = 2; 

// public static final String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED"; 
    @Override 
    public void onConnectionStateChange(BluetoothGatt gatt, int status, 
             int newState) { 
     Logg.i(TAG, "onConnectionStateChange"); 
     try { 
      super.onConnectionStateChange(gatt, status, newState); 

      if (newState == BluetoothProfile.STATE_CONNECTED) { 
       connectionState = STATE_CONNECTED; 
       Logg.w(TAG, "Connected to GATT server"); 
       Logg.i(TAG, "Attempting to start service discovery:" + gatt.discoverServices()); 
      } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 
       connectionState = STATE_DISCONNECTED; 
       Logg.w(TAG, "Disconnected from GATT server."); 
       try { 
        gatt.close(); 
       } catch (Exception e) { 
        Logg.d(TAG, "close ignoring: " + e); 
       } 
      } 
     }catch(NullPointerException e){ 
      Logg.i(TAG, "NullPointerException onConnectionStateChange"); 
     } 
    } 
} 

我在这里看到在stackoverflow类似的错误,当试图断开连接,并且解决方案是不在gatt.disconnect后立即调用gatt.close(),但这是一个不同的问题,我无法解决它。我是用蓝牙LE进行的新编程,并陷入这部分。

回答

0

尝试做回调是这样的:

// Various callback methods defined by the BLE API. 
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."); 
      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); 
     } 
    } 
} 

来源:https://developer.android.com/guide/topics/connectivity/bluetooth-le.html

并确保你保持你的BluetoothGatt bluetoothGatt。如果你写入null,回调不再被调用。也许这解决了你的问题。

+0

感谢您的帮助。按照您的建议,我一定会改善回调。但问题是一个愚蠢的错误,我打电话连接一个空回调。 – Jessica

0

我刚发现这个问题。这是一个愚蠢的事情,我用一个空的bluetoothGattCallback调用device.connect。写这个问题真的帮了我很大的忙,我在这个问题上是个不错的日子。