Search code examples
javaandroidbluetoothsensors

How to send constantly changing sensor data using bluetooth?


I am trying to send light data from a light sensor using Bluetooth in Android Studio. Once the user presses the button, the sensor value should be constantly updating and sent to the other phone.

I've modified some Bluetooth code I found online; however, the light sensor value does not constantly update, it just shows the value of the sensor when the button was pressed.

I've tried putting in a timer that runs every 5 seconds after the start flag is set, so that a new value from the light sensor is constantly sent, but it does not work.

Is there a way I can sample the sensor and send the constantly updating sensor data after the button is pressed? Thanks in advance.

This is the code which gets the sensor readings and passes it onto the button listeners code:

@Override
public void onSensorChanged(SensorEvent sensorEvent) {

    Sensor sensor = sensorEvent.sensor;

    if (sensor.getType() == Sensor.TYPE_LIGHT) {
        lightText.setText("Light = " + sensorEvent.values[0]);

        float lightTemp = sensorEvent.values[0];
        implementListeners(lightTemp);
    }
}

Button listeners - listens for the user pressing the start button and then writes the sensor reading to the bluetooth part of the code (to then send to the other phone):

private void implementListeners(final float lightTemp) {
.
.
.
.
    startBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int startFlag=1;
           checkStartFlag(startFlag);
        }

        private void checkStartFlag(int startFlag) {
            if (startFlag==1){
                Timer timer = new Timer ();
                TimerTask checkSec = new TimerTask () {
                    @Override
                    public void run () {
                        String string= String.valueOf(lightTemp);
                        sendReceive.write(string.getBytes());
                    }
                };
                timer.schedule (checkSec, 0l, 5000);   // Check every 1 sec
            }
        }
    });
}

Solution

  • There's a lot going on in your code here, so let me try to explain what's currently happening. When you get a new light value, you change the start button's click listener to start sending the value over bluetooth. However, since you're passing lightTemp into your implementListeners function, it won't get changed when onSensorChanged fires again. Thus, having a timer run every 5 seconds is likely working, but instead of sending a new value it's just sending the old one from before. So, what we need to do is have the data sent whenever the sensor value changes instead of when the button gets pressed.

    The best way of going about this would likely be to have a state variable in your class that gets updated when you tap the start button.

    private boolean sendData = false;
    
    //...
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Your existing code in onCreate goes here
    
        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendData = !sendData; // Toggles whether we're sending data or not.
                                      // You can also just set it to true if you don't
                                      // want toggling behaviour.
            }
        });
    }
    

    Now, we need to actually send the data if we have enabled data sending. We can change your onSensorChanged method to check the state variable we defined before, then send data if our state is true:

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
    
        Sensor sensor = sensorEvent.sensor;
    
        if (sensor.getType() == Sensor.TYPE_LIGHT) {
            lightText.setText("Light = " + sensorEvent.values[0]);
    
            if(sendData) { // check if we've enabed data sending
                String lightTemp = String.valueOf(sensorEvent.values[0]); // get the sensor value as a string
                  sendReceive.write(lightTemp.getBytes()); // send the string over bluetooth
            }
    
        }
    }
    

    Your app should now send data over bluetooth every time the light sensor value updates after you tap the start button.