@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_example4_advanced);
        ButterKnife.bind(this);
        final String macAddress = getIntent().getStringExtra(DeviceActivity.EXTRA_MAC_ADDRESS);
        final UUID characteristicUuid = (UUID) getIntent().getSerializableExtra(EXTRA_CHARACTERISTIC_UUID);
        final RxBleDevice bleDevice = SampleApplication.getRxBleClient(this).getBleDevice(macAddress);
        //noinspection ConstantConditions
        getSupportActionBar().setSubtitle(getString(R.string.mac_address, macAddress));

        /*
         * Since in this activity we use the same button for user interaction for connecting the peripheral, disconnecting before connection
         * is established and disconnecting after the connection is being made we need to share the same activatedClicksObservable.
         * It would be perfectly fine to use three different buttons and pass those observables to the Presenter.
         */
        final Observable<Boolean> sharedConnectButtonClicks = activatedClicksObservable(connectButton).share();
        // same goes for setting up notifications and indications below
        final Observable<Boolean> sharedNotifyButtonClicks = activatedClicksObservable(notifyButton).share();
        final Observable<Boolean> sharedIndicateButtonClicks = activatedClicksObservable(indicateButton).share();

        presenterEventObservable = Presenter.prepareActivityLogic(
                bleDevice,
                characteristicUuid,
                sharedConnectButtonClicks.compose(onSubscribeSetText(connectButton, R.string.connect)),
                sharedConnectButtonClicks.compose(onSubscribeSetText(connectButton, R.string.connecting)),
                sharedConnectButtonClicks.compose(onSubscribeSetText(connectButton, R.string.disconnect)),
                activatedClicksObservable(readButton),
                /*
                 * Write button clicks are then mapped to byte[] from the editText. If there is a problem parsing input then a notification
                 * is shown and we wait for another click to write to try to parse again.
                 */
                activatedClicksObservable(writeButton).map(aBoolean -> getInputBytes())
                        .doOnError(throwable -> showNotification("Could not parse input: " + throwable))
                        .retryWhen(errorNotificationHandler -> errorNotificationHandler),
                sharedNotifyButtonClicks.compose(onSubscribeSetText(notifyButton, R.string.setup_notification)),
                sharedNotifyButtonClicks.compose(onSubscribeSetText(notifyButton, R.string.setting_notification)),
                sharedNotifyButtonClicks.compose(onSubscribeSetText(notifyButton, R.string.teardown_notification)),
                sharedIndicateButtonClicks.compose(onSubscribeSetText(indicateButton, R.string.setup_indication)),
                sharedIndicateButtonClicks.compose(onSubscribeSetText(indicateButton, R.string.setting_indication)),
                sharedIndicateButtonClicks.compose(onSubscribeSetText(indicateButton, R.string.teardown_indication))
        );
    }
This activity allows for connecting to a device and interact with a given characteristic.
<p>
It may be used as a direct replacement for
{@link com.polidea.rxandroidble2.sample.example4_characteristic.CharacteristicOperationExampleActivity}
<p>
When the connection is not established only the "CONNECT" button is active.
When the user clicks on the "CONNECT" button the connection is established and other buttons are enabled according to the properties
of the characteristic.
Subsequent clicks on the "CONNECT" button (whose name will change according to the connection state) will close the connection.
<p>
When the connection is open other buttons are activated in regards of the characteristic's properties.
If the user clicks on "READ" a characteristic read is performed and the output is set on the TextView and EditText or a Snackbar is shown
in case of an error. "WRITE" clicks work the same as read but a write command is performed with data from the EditText.
If the characteristic has both of PROPERTY_NOTIFY and PROPERTY_INDICATE then only one of them is possible to be set at any given time.
Texts on notification and indication buttons will change accordingly to the current state of the notifications / indications.
sample/src/main/java/com/polidea/rxandroidble2/sample/example4_characteristic/advanced/AdvancedCharacteristicOperationExampleActivity.java