Java tutorial
/* Copyright (C) 2014 TU Darmstadt, Hessen, Germany. * Department of Computer Science Databases and Distributed Systems * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.tudarmstadt.dvs.myhealthassistant.myhealthhub.services; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.IMyHealthHubRemoteService; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.R; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.AbstractChannel; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.Event; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.SensorReadingEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.environmental.raw.AmbientLightEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.environmental.raw.AmbientPressureEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.environmental.raw.HumidityEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.environmental.raw.ProximityEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.environmental.raw.TemperatureEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.physical.AccDeviceSensorEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.physical.GyroscopeSensorEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.physical.MagneticSensorEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.graphActivities.Coordinate; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.services.transformationmanager.database.LocalTransformationDBMS; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.IBinder; import android.os.RemoteException; import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; import android.text.format.DateUtils; import android.util.Log; /** * * @author HieuHa * * A service that listens to SensorEvent, and sends the received Events * out (advertises those for any subscription) */ public class InternalSensorService extends Service implements SensorEventListener { private static final String TAG = InternalSensorService.class.getSimpleName(); private SensorManager mSensorManager; private SharedPreferences pref; private static final long timespan = DateUtils.MINUTE_IN_MILLIS; // FIXME if // needed @Override public void onCreate() { // The service is being created Log.e(TAG, "onCreate"); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); if (pref.getBoolean(getResources().getString(R.string.in_acc), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_lig), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_pres), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_prox), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_mag), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_gyrs), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_grav), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_hum), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_RELATIVE_HUMIDITY); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_lin_acc), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } if (pref.getBoolean(getResources().getString(R.string.in_tem), false)) { Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind Service"); return iservicestub; } private IMyHealthHubRemoteService.Stub iservicestub = new IMyHealthHubRemoteService.Stub() { @Override public int getStatus() throws RemoteException { // Write here, code to be executed in background Log.d(TAG, "Hello World From Remote Service!!"); return 0; } }; @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnBind Service"); // All clients unbound // super.onUnbind(intent); return true; } @Override public void onDestroy() { Log.e(TAG, "onDestroy"); if (mSensorManager != null) { // unregister all sensors mSensorManager.unregisterListener(this); } else Log.e(TAG, "mSensorManager is null!"); // The service is no longer used and is being destroyed // stopForeground(true); super.onDestroy(); } // ############################################################################### // SensorListerner Side @Override public void onAccuracyChanged(Sensor arg0, int arg1) { // not needed } @Override public void onSensorChanged(SensorEvent event) { if (pref == null) pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); int mSensorType = event.sensor.getType(); if (mSensorType == Sensor.TYPE_ACCELEROMETER) { int x = Math.round(event.values[0]); int y = Math.round(event.values[1]); int z = Math.round(event.values[2]); // using ACCELEROMETER_KNEE only as a demonstration, // in practice new event can be created AccDeviceSensorEvent accEvt = new AccDeviceSensorEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.ACCELEROMETER_ON_DEVICE, getTimestamp(), x, y, z, x, y, z); sendToChannel(accEvt, AbstractChannel.RECEIVER); // for external // apps // subscription gotAccEvent(getTimestamp(), Sensor.TYPE_ACCELEROMETER, x, y, z); // for // on device // graphViews // using } else if (mSensorType == Sensor.TYPE_LIGHT) { float x = event.values[0]; // using ambientLightEvent only as a demonstration, // in practice new event can be created AmbientLightEvent lightEvnt = new AmbientLightEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.AMBIENT_LIGHT, getTimestamp(), "location", "object", x, AmbientLightEvent.UNIT_LUX); sendToChannel(lightEvnt, AbstractChannel.RECEIVER); gotLightEvent(getTimestamp(), Sensor.TYPE_LIGHT, x); } else if (mSensorType == Sensor.TYPE_PRESSURE) { float x = event.values[0]; AmbientPressureEvent temEvnt = new AmbientPressureEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.AMBIENT_PRESSURE, getTimestamp(), "location", "object", x, AmbientPressureEvent.UNIT_HPA); sendToChannel(temEvnt, AbstractChannel.RECEIVER); gotLightEvent(getTimestamp(), Sensor.TYPE_PRESSURE, x); } else if (mSensorType == Sensor.TYPE_PROXIMITY) { float x = event.values[0]; ProximityEvent evnt = new ProximityEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.PROXIMITY, getTimestamp(), "location", "object", x, ""); sendToChannel(evnt, AbstractChannel.RECEIVER); gotLightEvent(getTimestamp(), Sensor.TYPE_PROXIMITY, x); } else if (mSensorType == Sensor.TYPE_AMBIENT_TEMPERATURE) { float x = event.values[0]; TemperatureEvent evnt = new TemperatureEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.ROOM_TEMPERATURE, getTimestamp(), "location", "object", x, TemperatureEvent.UNIT_CELSIUS); sendToChannel(evnt, AbstractChannel.RECEIVER); gotLightEvent(getTimestamp(), Sensor.TYPE_AMBIENT_TEMPERATURE, x); } else if (mSensorType == Sensor.TYPE_RELATIVE_HUMIDITY) { float x = event.values[0]; HumidityEvent evnt = new HumidityEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.HUMIDITY, getTimestamp(), "location", "object", x); sendToChannel(evnt, AbstractChannel.RECEIVER); gotLightEvent(getTimestamp(), Sensor.TYPE_RELATIVE_HUMIDITY, x); } else if (mSensorType == Sensor.TYPE_GYROSCOPE) { int x = Math.round(event.values[0]); int y = Math.round(event.values[1]); int z = Math.round(event.values[2]); GyroscopeSensorEvent gSEvnt = new GyroscopeSensorEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.GYROSCOPE, getTimestamp(), x, y, z, x, y, z); sendToChannel(gSEvnt, AbstractChannel.RECEIVER); gotAccEvent(getTimestamp(), Sensor.TYPE_GYROSCOPE, x, y, z); } else if (mSensorType == Sensor.TYPE_MAGNETIC_FIELD) { int x = Math.round(event.values[0]); int y = Math.round(event.values[1]); int z = Math.round(event.values[2]); MagneticSensorEvent gSEvnt = new MagneticSensorEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.MAGNETIC_FIELD, getTimestamp(), x, y, z, x, y, z); sendToChannel(gSEvnt, AbstractChannel.RECEIVER); gotAccEvent(getTimestamp(), Sensor.TYPE_MAGNETIC_FIELD, x, y, z); } else if (mSensorType == Sensor.TYPE_LINEAR_ACCELERATION) { int x = Math.round(event.values[0]); int y = Math.round(event.values[1]); int z = Math.round(event.values[2]); // using ACCELEROMETER_KNEE only as a demonstration, // in practice new event can be created AccDeviceSensorEvent accEvt = new AccDeviceSensorEvent("eventID", getTimestamp(), "producerID", SensorReadingEvent.ACCELEROMETER_ON_DEVICE, getTimestamp(), x, y, z, x, y, z); sendToChannel(accEvt, AbstractChannel.RECEIVER); gotAccEvent(getTimestamp(), Sensor.TYPE_LINEAR_ACCELERATION, x, y, z); } } private String getTimestamp() { return (String) android.text.format.DateFormat.format(dateFormat, new java.util.Date()); } private void sendToChannel(Event evt, String channel) { Intent i = new Intent(); i.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, evt.getEventType()); i.putExtra(Event.PARCELABLE_EXTRA_EVENT, evt); i.setAction(channel); // getApplicationContext().sendBroadcast(i); LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i); } // ############################################################################### // working with SensorEvent // normally a new app can subscript to myHealthHub to receive these events private static final String dateFormat = "yyyy-MM-dd_kk:mm:ss"; private static String lastAddedLightData = ""; private ArrayList<Coordinate> listLightData; private double readingLightValue; private int lightDataCounter; private void gotLightEvent(String dateOfMeasurement, int typeId, float value) { // if (lastAddedLightData == null || lastAddedLightData.isEmpty()) { // lastAddedLightData = dateOfMeasurement; // listLightData = new ArrayList<Coordinate>(); // readingLightValue = 0.0d; // lightDataCounter = 1; // } else { // if (timeDiff(lastAddedLightData, dateOfMeasurement, timespan)) { // // after each min the added up data being divided by // // average and stored // double yValue = readingLightValue / lightDataCounter; // String xValue = dateOfMeasurement; // // if (listLightData == null) // listLightData = new ArrayList<Coordinate>(); // // listLightData.add(new Coordinate(xValue, yValue)); // // // store to dbs each 10 min (when size of list reach xxx0) // if (listLightData.size() % 10 == 0) { // addTrafficToDB(dateOfMeasurement, typeId, listLightData); // add // // only // // 10 // // data // // to // // dbs // listLightData = new ArrayList<Coordinate>(); // } // // the data being reset after that // readingLightValue = Double.parseDouble(Float.toString(value)); // lightDataCounter = 1; // // lastAddedLightData = dateOfMeasurement; // } else { // // within a minute value being added up only // readingLightValue += Double.parseDouble(Float.toString(value)); // lightDataCounter++; // // } // } } private static String lastAddedAccData = ""; private ArrayList<Double> accValues = new ArrayList<Double>(); private ArrayList<Coordinate> listAccData; private void gotAccEvent(String dateOfMeasurement, int typeId, int x, int y, int z) { // if (lastAddedAccData == null || lastAddedAccData.isEmpty()) { // lastAddedAccData = dateOfMeasurement; // listAccData = new ArrayList<Coordinate>(); // accValues = new ArrayList<Double>(); // } else { // if (timeDiff(lastAddedAccData, dateOfMeasurement, timespan)) { // // String xValue = dateOfMeasurement; // double mean = 0.0d; // double variance = 0.0d; // int n = accValues.size(); // for (double b : accValues) { // mean += b; // } // mean = mean / n; // for (double b : accValues) { // variance += (mean - b) * (mean - b); // } // variance = variance / n; // // double yValue = variance; // // double yValue = Math.sqrt(variance); // standard Deviation // // if (listAccData == null) // listAccData = new ArrayList<Coordinate>(); // // listAccData.add(new Coordinate(xValue, yValue)); // // // store to dbs each 10 min (when size of list reach 10) // if (listAccData.size() % 10 == 0) { // // addTrafficToDB(dateOfMeasurement, typeId, listAccData); // listAccData = new ArrayList<Coordinate>(); // } // // // the data being reset after each min // accValues = new ArrayList<Double>(); // // lastAddedAccData = dateOfMeasurement; // } else { // // within a minute value being added up only // // readingAccValue += Math.sqrt(x * x + y * y + z * z); // accValues.add(Math.sqrt(x * x + y * y + z * z)); // } // } } /** * calculate the difference in minutes between two dates in millisecond * * @param first * @param second * @param timespan * : the different of (e.g, ONE minute, ONE day...) * @return true if two dates are difference by time span */ public boolean timeDiff(String firstDate, String secondDate, long timespan) { SimpleDateFormat dfDate = new SimpleDateFormat(dateFormat); try { Date first = dfDate.parse(firstDate); Date second = dfDate.parse(secondDate); long diff = ((second.getTime() / timespan) - (first.getTime() / timespan)); return (diff < 1) ? false : true; } catch (ParseException e) { Log.e(TAG, e.toString()); e.printStackTrace(); } return false; } private LocalTransformationDBMS transformationDB; private void addTrafficToDB(String timeOfMeasurement, int typeID, ArrayList<Coordinate> listData) { ArrayList<String> dateToAdd = new ArrayList<String>(); transformationDB = new LocalTransformationDBMS(this.getApplicationContext()); transformationDB.open(); ArrayList<String> databaseListData = transformationDB.getAllAvalDate(); // add to traffic table Log.e(TAG, "Add traffic to table with type:" + typeID + "; " + timeOfMeasurement); for (Coordinate d : listData) { String date = getDayFromDate(d.getX(), dateFormat, "dd-MM-yyyy"); double xDouble = convertTimeToDouble(d.getX(), dateFormat, "kk.mm"); transformationDB.addTraffic(date, typeID, xDouble, d.getY()); if (!databaseListData.contains(date) && !dateToAdd.contains(date)) { dateToAdd.add(date); } } for (String s : dateToAdd) { transformationDB.addDateOfTraffic(s, -1); } transformationDB.close(); } private String getDayFromDate(String timeOfMeasurement, String dateFormat, String applyPattern) { SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); try { Date today = sdf.parse(timeOfMeasurement); sdf.applyPattern(applyPattern); return sdf.format(today); } catch (ParseException e) { e.printStackTrace(); Log.e(TAG, e.toString()); } return ""; } private static double convertTimeToDouble(String fullTime, String dateFormat, String applyPattern) { SimpleDateFormat fullDate = new SimpleDateFormat(dateFormat); SimpleDateFormat timeDate = new SimpleDateFormat(applyPattern); try { Date now = fullDate.parse(fullTime); String strDate = timeDate.format(now); double parseDate = Double.parseDouble(strDate); if (parseDate >= 24.00d) return parseDate - 24; return parseDate; } catch (ParseException e) { Log.e(TAG, e.toString()); e.printStackTrace(); } return Double.parseDouble("00.00"); } }