Search code examples
androidserviceandroid-sensorsproximitybackground-thread

Problems reading data on onSensorChanged


There is data on onSensorChanged that comes continuously while the sensor is turn on.

I want to:

  1. Turn on the sensor for 10 seconds and read the data once in 10 seconds intervals.
  2. Turn off the sensor for 20 seconds.
  3. Repeat the same thing continuously (step 1 to 2).

I use the ScheduledExecutorService.scheduleAtFixedRate to periodically read data from onSensorChanged, but it doesn't work. What's the solution?

public class ProximityService extends Service {

    @Override
    public void onCreate() {
        HandlerThread t = new HandlerThread("ProximityServiceHandler", THREAD_PRIORITY_BACKGROUND);
        t.start();
        _serviceLooper = t.getLooper();
        _serviceHandler = new ProximityServiceHandler(_serviceLooper, this);
    }


    private final class ProximityServiceHandler extends Handler {
        private static final int ON_TIME = 10000;   // 10 seconds
        private static final int OFF_TIME = 20000;  // 20 seconds

        private void parseSensor(SensorEvent sensorEvent) {
            // data processing
        }

        @Override
        public void handleMessage(Message msg) {
            _sensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));
            if (_sensorManager != null) {

                _sensor = _sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
                if (_sensor != null) {

                    _sensorEventListener = new SensorEventListener() {
                        @Override
                        public void onSensorChanged(SensorEvent sensorEvent) {

                            if (sensorEvent != null) {
                                // collect data..
                                // data available in here, but not in _sensorScheduler?
                                parseSensor(sensorEvent); 
                            }
                        }

                        @Override
                        public void onAccuracyChanged(Sensor sensor, int i) {       
                            //
                        }
                    };

                    // why this function doesn't worked ?
                    _sensorScheduler = Executors.newScheduledThreadPool(1);
                    _sensorScheduler.scheduleAtFixedRate(
                            new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        // turnon sensor
                                        _sensorManager.registerListener(_sensorEventListener, _sensor, SensorManager.SENSOR_DELAY_NORMAL);

                                        // wait to collect data from sensor
                                        Thread.sleep(ON_TIME);

                                        // send data to main thread but data not available in here?
                                         sendData(sensorEvent)

                                        // turn off sensor
                                        _sensorManager.unregisterListener(_sensorEventListener, _sensor);

                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }, 0, OFF_TIME, TimeUnit.MILLISECONDS);
                }
            }
        }

    }
}

Solution

  • I found the solution, calling toast in the sendData(sensorEvent) which make the sensor stop working.

    I modified the toast to be able to call from a background thread like this:

    public static void showToast(final Context context, final String text, final int duration) {
        if (context != null && text != null) {
            new Handler(context.getMainLooper()).post(new Runnable() {
    
                @Override
                public void run() {
                    Toast.makeText(context, text, duration).show();
                }               
            });
        }
    }