2016-05-12 5 views
2

kann ich keine Verbindung zu einem BLE-Gerät herstellen. Ich entwickle eine App, die sich mit einem BLE-Gerät verbinden und trennen kann. Ich kann eine Verbindung zu einem Gerät herstellen und die Verbindung zu diesem Gerät trennen. Aber wenn ich versuche, wieder auf das gleiche Gerät zu verbinden, funktioniert es nicht mehr.Nach BluetoothGatt.disconnect() in android

Ich verwende zwei Klassen, die MainActivity und die zweite, die sich vom Dienst erstreckt.

Meine zweite Aktivität:

public class RFduinoService extends Service { 
private final static String TAG = RFduinoService.class.getSimpleName(); 

private BluetoothManager mBluetoothManager; 
private BluetoothAdapter mBluetoothAdapter; 
private String mBluetoothDeviceAddress; 
private BluetoothGatt mBluetoothGatt; 
private BluetoothGattService mBluetoothGattService; 

public final static String ACTION_CONNECTED = 
     "com.rfduino.ACTION_CONNECTED"; 
public final static String ACTION_DISCONNECTED = 
     "com.rfduino.ACTION_DISCONNECTED"; 
public final static String ACTION_DATA_AVAILABLE = 
     "com.rfduino.ACTION_DATA_AVAILABLE"; 
public final static String EXTRA_DATA = 
     "com.rfduino.EXTRA_DATA"; 

public final static UUID UUID_SERVICE = BluetoothHelper.sixteenBitUuid(0x2220); 
public final static UUID UUID_RECEIVE = BluetoothHelper.sixteenBitUuid(0x2221); 
public final static UUID UUID_SEND = BluetoothHelper.sixteenBitUuid(0x2222); 
public final static UUID UUID_DISCONNECT = BluetoothHelper.sixteenBitUuid(0x2223); 
public final static UUID UUID_CLIENT_CONFIGURATION = BluetoothHelper.sixteenBitUuid(0x2902); 

// 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) { 
     if (newState == BluetoothProfile.STATE_CONNECTED) { 
      Log.i(TAG, "Connected to RFduino."); 
      Log.i(TAG, "Attempting to start service discovery:" + 
        mBluetoothGatt.discoverServices()); 
     } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 
      Log.i(TAG, "Disconnected from RFduino."); 
      broadcastUpdate(ACTION_DISCONNECTED); 
     } 
    } 

    @Override 
    public void onServicesDiscovered(BluetoothGatt gatt, int status) { 
     if (status == BluetoothGatt.GATT_SUCCESS) { 
      mBluetoothGattService = gatt.getService(UUID_SERVICE); 
      if (mBluetoothGattService == null) { 
       Log.e(TAG, "RFduino GATT service not found!"); 
       return; 
      } 

      BluetoothGattCharacteristic receiveCharacteristic = 
        mBluetoothGattService.getCharacteristic(UUID_RECEIVE); 
      if (receiveCharacteristic != null) { 
       BluetoothGattDescriptor receiveConfigDescriptor = 
         receiveCharacteristic.getDescriptor(UUID_CLIENT_CONFIGURATION); 
       if (receiveConfigDescriptor != null) { 
        gatt.setCharacteristicNotification(receiveCharacteristic, true); 

        receiveConfigDescriptor.setValue(
          BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 
        gatt.writeDescriptor(receiveConfigDescriptor); 
       } else { 
        Log.e(TAG, "RFduino receive config descriptor not found!"); 
       } 

      } else { 
       Log.e(TAG, "RFduino receive characteristic not found!"); 
      } 

      broadcastUpdate(ACTION_CONNECTED); 
     } 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, Manifest.permission.BLUETOOTH); 
} 

private void broadcastUpdate(final String action, 
          final BluetoothGattCharacteristic characteristic) { 
    if (UUID_RECEIVE.equals(characteristic.getUuid())) { 
     final Intent intent = new Intent(action); 
     intent.putExtra(EXTRA_DATA, characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)); 
     sendBroadcast(intent, Manifest.permission.BLUETOOTH); 
    } 
} 

public class LocalBinder extends Binder { 
    RFduinoService getService() { 
     return RFduinoService.this; 
    } 
} 

@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."); 
     return mBluetoothGatt.connect(); 
    } 

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 
    // 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; 
    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.disconnect(); 
} 

/** 
* 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; 
} 

public void read() { 
    if (mBluetoothGatt == null || mBluetoothGattService == null) { 
     Log.w(TAG, "BluetoothGatt not initialized"); 
     return; 
    } 

    BluetoothGattCharacteristic characteristic = 
      mBluetoothGattService.getCharacteristic(UUID_RECEIVE); 

    mBluetoothGatt.readCharacteristic(characteristic); 
} 

public boolean send(byte[] data) { 
    if (mBluetoothGatt == null || mBluetoothGattService == null) { 
     Log.w(TAG, "BluetoothGatt not initialized"); 
     return false; 
    } 

    BluetoothGattCharacteristic characteristic = 
      mBluetoothGattService.getCharacteristic(UUID_SEND); 

    if (characteristic == null) { 
     Log.w(TAG, "Send characteristic not found"); 
     return false; 
    } 

    characteristic.setValue(data); 
    characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); 
    return mBluetoothGatt.writeCharacteristic(characteristic); 
} 

public static IntentFilter getIntentFilter() { 
    IntentFilter filter = new IntentFilter(); 
    filter.addAction(ACTION_CONNECTED); 
    filter.addAction(ACTION_DISCONNECTED); 
    filter.addAction(ACTION_DATA_AVAILABLE); 
    return filter; 
} 

}

Und mein MainActivity:

public class MainActivity extends Activity implements BluetoothAdapter.LeScanCallback { 

@Override 
protected void onStart() { 
    Log.d("ONSTART", "ONSTART"); 
    super.onStart(); 
    registerReceiver(scanModeReceiver, new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)); 
    registerReceiver(bluetoothStateReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); 
    registerReceiver(rfduinoReceiver, RFduinoService.getIntentFilter()); 

} 

@Override 
public void onLeScan(BluetoothDevice device, final int rssi, final byte[] scanRecord) { 
    scanLeDevice(false); 
    bluetoothDevice = device; 

    MainActivity.this.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      Log.d("ONLESCAN", "ONLESCAN"); 
      /*obtain the name of the device based on the scanRecord*/ 
      BleAdvertisedData badata = BleUtil.parseAdertisedData(scanRecord); 

      ListView list = discoveredDevicesDialog.getListView(); 
      list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
       @Override 
       public void onItemClick(AdapterView<?> parent, View view, 
             int position, long id) { 
        indexListClicked = position; 
        Intent rfduinoIntent = new Intent(MainActivity.this, RFduinoService.class); 
        bindService(rfduinoIntent, rfduinoServiceConnection, BIND_AUTO_CREATE); 

       } 
      }); 
      createNotification(); 
     } 
    }); 
} 

@Override 
public void onBackPressed() { 
    Log.d("CDA", "onBackPressed Called"); 
    if(!DisplayDiapers.getShowButton()) { 
     unregisterReceiver(scanModeReceiver); 
     unregisterReceiver(bluetoothStateReceiver); 
     unregisterReceiver(rfduinoReceiver); 
     finish(); 
    }else { 
     moveTaskToBack(true); 
    } 
} 


private void scanLeDevice(boolean scan){ 
    if(bluetoothAdapter.isEnabled()) { 
     if (scan) { 
      loadLoadingScanDialog(true); 
      bluetoothAdapter.startLeScan(
        new UUID[]{RFduinoService.UUID_SERVICE}, 
        MainActivity.this); 
     } else { 
      bluetoothAdapter.stopLeScan(this); 
     } 
    } 
} 

public static void disconnect(int position){ 
    rfduinoService.disconnect(); 
} 

private final BroadcastReceiver bluetoothStateReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d("bluetoothStateReceiver", "bluetoothStateReceiver"); 
     int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0); 
     if (state == BluetoothAdapter.STATE_ON) { 
      Log.d("STATE_DISCONNECTED", "STATE_DISCONNECTED"); 
     } else if (state == BluetoothAdapter.STATE_OFF) { 
      Log.d("STATE_BLUETOOTH_OFF", "STATE_BLUETOOTH_OFF"); 
     } 
    } 
}; 

private final BroadcastReceiver scanModeReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d("scanModeReceiver", "scanModeReceiver"); 
    } 
}; 

private final ServiceConnection rfduinoServiceConnection = new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     Log.d("rfduinoServiceConnec", "rfduinoServiceConnection_onServiceConnected"); 
     rfduinoService = ((RFduinoService.LocalBinder) service).getService(); 
     if (rfduinoService.initialize()) { 
      if (rfduinoService.connect(bluetoothDevice.getAddress())) { 
       Log.d("STATE_CONNECTING", "STATE_CONNECTING"); 
      } 
     } 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     Log.d("rfduinoServiceConnec", "rfduinoServiceConnection_onServiceDisconnected"); 
    } 
}; 

private final BroadcastReceiver rfduinoReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d("rfduinoReceiver", "rfduinoReceiver"); 
     final String action = intent.getAction(); 
     if (RFduinoService.ACTION_CONNECTED.equals(action)) { 
      showToast("Connected to " + diapersNames.get(indexListClicked)); 
     } 
    } 
}; 

} 

In beiden Zeiten kann ich die Geräte scannen, und mein Gerät finden, aber das zweite Mal, wenn Ich klicke auf das Gerät, mit dem ich mich verbinden möchte, ich kann diese Aktion nicht ausführen.

Der Ablauf geht so: in onLeScan() ich klicke auf das Gerät, das ich verbinden möchte, als der Code geht zu onServiceConnected() und ruft die Methoden meiner zweiten Klasse. Wenn ich die Verbindung trennen möchte, wird die disconnect(int) angerufen, aber der Code wird onServiceDisconnected() nicht eingeben. Das zweite Mal onLeScan() wird nichts tun, ich weiß, dass der Code auf onLeScan() eingeben, aber das ist der letzte Druck, den ich habe, ich verstehe nicht, warum das passiert. Warum ist das Verhalten nicht das gleiche wie beim ersten Mal?

Danke für Ihre Hilfe.

Antwort

0

Sie rufen nie public static void disconnect(int position).

Ich denke, Sie sollten es im RfduinoReceiver nennen. Etwas wie dieses:

private final BroadcastReceiver rfduinoReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d("rfduinoReceiver", "rfduinoReceiver"); 
     if (RFduinoService.ACTION_CONNECTED.equals(action)) { 
       Log.d(TAG, "RFduinoServer connected"); 
      } else if (RFduinoService.ACTION_DISCONNECTED.equals(action)) { 
       Log.d(TAG, "RFduinoServer disconnected"); 
       rfduinoService.disconnect(); 
      } else if (RFduinoService.ACTION_DATA_AVAILABLE.equals(action)) { 
       Log.d(TAG, "RFduinoServer data available"); 
       // Process data from intent.getByteArrayExtra(RFduinoService.EXTRA_DATA) 
      } 
     } 
    } 
};