0

I have toggle(Switch) buttons inside my fragment.After coming on the fragment I am reading BLE values and setting the toggle buttons.

 @Override
public void sosStatus(boolean sosvalue, BluetoothGattCharacteristic sosCharac) {
    if (sosvalue) {
        byte[] charValue = sosCharac.getValue();
        String valueOfCharInstring = StringUtils.byteToHex(charValue[0]);
        Log.d("+++++SosStatus",""+sosCharac.getUuid().toString() + " " + valueOfCharInstring);
        if (sosCharac.getUuid().toString().equalsIgnoreCase(BLEConstants._BUTTON_CHARACTERISTIC)) {
            if (valueOfCharInstring.equalsIgnoreCase(BLEConstants.EnableCharacInString)) {
                setButtonStatus(touchButton,R.id.switch_btn_device_touch,"Enabled");
               // touchButton.setChecked(true);
               // tvTouchButtonAction.setText("Enabled");
            } else if (valueOfCharInstring.equalsIgnoreCase(BLEConstants.DisableCharacInString)) {
                setButtonStatus(touchButton,R.id.switch_btn_device_touch,"Disabled");
               // touchButton.setChecked(false);
               // tvTouchButtonAction.setText("Disabled");
            }
        }


        if (characList.size() > 0) {
            gattclientCallBack.readCharacteristicMain(UUID.fromString(characList.remove(characList.size() - 1)));


        } else {
            useOnCheckedChangeMethod = true;
            showProgress(false);
        }
    } else {
        useOnCheckedChangeMethod = true;
        showProgress(false);
        HandleCharacListData(true,false,"");
    }
}

Now since Switch widget is used, what is happening is that when I read the values programatically for first time, it works fine.but when I toggle the button with touch, onCheckChanged is repeatedly getting called as if I set some value, it keeps on calling itself in infinite loop. This is my oncheckchanged code.

 @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        try {
            if (useOnCheckedChangeMethod) {
                switch (compoundButton.getId()) {
                    case R.id.switch_btn_device_touch:
                        touchButton.setOnCheckedChangeListener(null);
                        //showProgress(true);
                        HandleCharacListData(true,false,"");
                        HandleCharacListData(false,false,BLEConstants.TOUCH_BUTTON_CHARACTERISTIC);
                        if(characList!=null && characList.size()>0) {
                            if(b) {
                                gattclientCallBack.writeCharacteristic(characList.remove(characList.size() - 1), BLEConstants.DisableCharac);
                            }
                            else {
                                gattclientCallBack.writeCharacteristic(characList.remove(characList.size() - 1), BLEConstants.EnableCharac);
                            }
                        }
                        Log.d("Touch++++", "+++");
                        break;
}

So it continuously keep on toggling as on and off due to the check if(b). :)

what can I do to ensure that the onCheckChange methos only gets called once after the value is set ?

Things that I have also tried 1) Use onClick listener and disable call in oncheckchanged and enable on click. 2) Use onTouch

Thank you :)

Pritish
  • 1,284
  • 1
  • 19
  • 42

2 Answers2

0

That interesting, because inside of setChecked() it actually checks to see if it's in the middle of broadcasting and returns...

public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState();
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);

            // Avoid infinite recursions if setChecked() is called from a listener
            if (mBroadcasting) {
                return;
            }

            mBroadcasting = true;
            if (mOnCheckedChangeListener != null) {
                mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
            }
            if (mOnCheckedChangeWidgetListener != null) {
                mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
            }

            mBroadcasting = false;            
        }
    }

The only solution I know of is un-registering the callback before calling setChecked() and register the callback again after your call returns. This works because the callback isn't called asynchronously but instead, called immediately inside of setChecked().

cincy_anddeveloper
  • 1,140
  • 1
  • 9
  • 19
  • Thanks for the input :) . I found my answer, I have mentioned in my answer below .:) Actually view.isPressed() was what I required :) Please refer the answer in the link I have mentioned :) It is a same solution to a question framed little differently :) – Pritish Jan 03 '18 at 19:49
0

Hey I got my answer in the link below to a question framed little differently . Thanks to this guy :)

onCheckedChanged called automatically

Pritish
  • 1,284
  • 1
  • 19
  • 42