Android Open Source - jsense-collector Sensing Service






From Project

Back to project page jsense-collector.

License

The source code is released under:

MIT License

If you think the Android project jsense-collector listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.jsense.collector;
/* ww w  . j  a  v a  2s.  c  o  m*/
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.PowerManager;

import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import com.google.common.io.Closer;
import com.google.common.io.Files;
import com.google.inject.Inject;

import org.joda.time.Instant;
import org.jsense.AccelerometerEvent;
import org.jsense.serialize.protobuf.AccelerometerEventSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import roboguice.service.RoboService;

public class SensingService extends RoboService {

    private static final int MAX_EVENT_COUNT = 100000;

    private static final Logger log = LoggerFactory.getLogger(SensingService.class);

    private final String saveFileFilename = UUID.randomUUID().toString() + "-" + AccelerometerEvent.class.getSimpleName() + ".pbz";

    @Inject
    SensorManager sensorManager;

    @Inject
    PowerManager powerManager;
    private PowerManager.WakeLock wakelock;

    private HandlerThread sensingThread;
    private AccelerometerListener accelerometerListener;
    private final BlockingQueue<AccelerometerEvent> events = Queues.newArrayBlockingQueue(MAX_EVENT_COUNT);

    private final ExecutorService threadPool = Executors.newSingleThreadExecutor();

    @Override
    public void onCreate() {
        super.onCreate();

        log.info("Starting sensing service...");

        startEventWriter();
        startSensing();
    }

    private void startEventWriter() {
        threadPool.execute(new Runnable() {

            public static final int MAX_LOCAL_EVENTS = 200;
            private List<AccelerometerEvent> localEvents = Lists.newArrayList();

            @Override
            public void run() {
                File saveDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), SensingService.class.getPackage().getName());
                if (!saveDir.exists()) {
                    if (!saveDir.mkdirs()) {
                        log.error("Couldn't create save directory, no data saved.");
                        return;
                    }
                }

                File saveFile = new File(saveDir, saveFileFilename);
                log.info("Writing to {}.", saveFile);

                try {
                    Closer closer = Closer.create();
                    try {
                        AccelerometerEventSerializer serializer = closer.register(new AccelerometerEventSerializer(Files.asByteSink(saveFile)));
                        try {
                            while (!Thread.interrupted()) {
                                AccelerometerEvent event = events.take();
                                localEvents.add(event);
                                if (localEvents.size() < MAX_LOCAL_EVENTS) {
                                    continue;
                                }

                                log.debug("Writing {} events.", localEvents.size());
                                serializer.serialize(localEvents);
                                localEvents.clear();
                            }
                        } catch (InterruptedException e) {
                            // Ignore
                        }
                        log.info("Flushing data and preparing exit...");
                        serializer.flush();
                    } catch (Throwable e) {
                        throw closer.rethrow(e);
                    } finally {
                        closer.close();
                    }
                } catch (IOException e) {
                    log.warn("Error I/O with save file.", e);
                }

                log.info("Stopped event writer thread.");
            }
        });
    }

    private void startSensing() {
        wakelock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, SensingService.class.getName());
        wakelock.acquire();

        sensingThread = new HandlerThread("sensingThread");
        sensingThread.start();
        Handler sensorHandler = new Handler(sensingThread.getLooper());

        Sensor accelerometer;
        if ((accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)) == null) {
            log.error("No accelerometer present.");
            stopSelf();
            return;
        }

        accelerometerListener = new AccelerometerListener();
        if (!sensorManager.registerListener(accelerometerListener, accelerometer, SensorManager.SENSOR_DELAY_FASTEST, sensorHandler)) {
            log.error("Couldn't register accelerometer.");
            stopSelf();
            return;
        }

        log.info("Started sensing.");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        log.info("Stopping sensing service...");

        stopSensing();
        stopEventWriter();
    }

    private void stopSensing() {
        sensorManager.unregisterListener(accelerometerListener);
        sensingThread.quitSafely();
        wakelock.release();

        log.info("Stopped sensing.");
    }

    private void stopEventWriter() {
        threadPool.shutdownNow();
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    private class AccelerometerListener implements SensorEventListener {
        @Override
        public void onSensorChanged(SensorEvent event) {
            AccelerometerEvent accelerometerEvent = AccelerometerEvent.newBuilder()
                    .setAbsoluteTimestamp(new Instant(System.currentTimeMillis()))
                    .setRelativeTimestamp(event.timestamp)
                    .setX(event.values[0])
                    .setY(event.values[1])
                    .setZ(event.values[2])
                    .build();
            events.add(accelerometerEvent);
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // Do nothing
        }
    }
}




Java Source Code List

org.jsense.collector.MainActivity.java
org.jsense.collector.SensingService.java