com.developer.shade.sensors.SensorService.java Source code

Java tutorial

Introduction

Here is the source code for com.developer.shade.sensors.SensorService.java

Source

/* Java File:: SensorService.java / Note: Service Class To Run Sensor Algorithm Within Background
* Author: Shaid Khan / Last Updated: 30/08/2015 */
package com.developer.shade.sensors;

import android.app.Notification;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.content.Intent;
import android.os.Vibrator;
import android.app.Service;
import android.hardware.*;
import android.os.IBinder;
import android.util.Log;

import com.developer.shade.activities.TimerActivity;
import com.developer.shade.sound.R;

/**
 *   SOUND: Fall Detection For Android Wear
 *
 *   @author: Shaid Khan
 *   Copyright (C) 2015 Shaid Khan.
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2,
 *   as published by the Free Software Foundation.
 *
 *   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/>.
 *
 */
public class SensorService extends Service implements SensorEventListener {
    ////////////////////////////////////////////////////////////////////////////////////////////////
    // SensorService Class Fields & Members -------------------------------------------------------
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /* Warning: Ensure Sensors Are unregister When Not In Use To Save Battery
     * Todo: Testing Of Linear Acceleration Is Also Require At Later Date
     * Todo: Test Additional Algorithms At Later Stage Of Development */
    private final int NOTIFICATION_ID = 768972134;
    private NotificationManagerCompat notiManager;
    private SensorManager senManager;
    protected double x, y, z;

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Inherited Service Class Methods ------------------------------------------------------
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /* Note: Method To Start The Initialise Of Sensor Service Class Attributes & Properties
     * Todo: Initialise Of SensorService Class Components Required */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v("Running onStart", "Starting SensorService Service ID: " + startId);
        senManager.registerListener(this, senManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_NORMAL);
        return START_STICKY;
    }

    /* Note: Method To Return the Communication Channel to the System Service */
    @Override
    public IBinder onBind(Intent intent) {
        Log.v("Running onBind", "Method don't required Implementation");
        throw new UnsupportedOperationException("Not Implemented");
    }

    /* Note: Method To Destroy The Service When Not Required
     * Todo: Additional Removal Of Notification Required */
    @Override
    public void onDestroy() {
        Log.d("Running onDestroy", "Stop Sensors & Current Background Service");
        senManager.unregisterListener(this);
        notiManager.cancel(NOTIFICATION_ID);
        super.onDestroy();
    }

    /* Note: Method To Build The Background Service (Init Sensors & Notification)
     * Todo: Implementation Of Notification Is Required */
    @Override
    public void onCreate() {
        Log.d("Running onCreate", "Obtaining Device Accelerometer Hardware Sensor");
        senManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        Sensor sensor = senManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        Log.d("NAME: ", sensor.getName());
        initNotification();
        super.onCreate();
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Internal Class Methods / Notification ------------------------------------------------
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /* Note: Method To Run & Maintain Notification Within The System Intent */
    private void initNotification() {
        Log.v("Running initNot", "Method To Create Notification For Monitoring Service");
        NotificationCompat.Builder notiBuilder = new NotificationCompat.Builder(this);
        notiBuilder.setContentTitle("Running Fall Detection");
        notiBuilder.setSmallIcon(R.mipmap.ic_launcher);
        notiBuilder.setAutoCancel(false);

        Notification noti = notiBuilder.build();
        noti.flags = Notification.FLAG_ONGOING_EVENT;

        notiManager = NotificationManagerCompat.from(this);
        notiManager.notify(NOTIFICATION_ID, noti);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Euclidean Norm Algorithms ------------------------------------------------------------------
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /* Note: Method To Return The Value Of The Euclidean Norm Algorithms (Fall Detection Algorithm)
     * Todo: Access To Threshold Rate Value Is Required */
    private double EuclideanNorm(double X, double Y, double Z) {
        // Note: Cancel Logging For Performance (Or Each Movement Will Display)
        return Math.sqrt((X * X) + (Y * Y) + (Z * Z));
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // System Vibrator Method ---------------------------------------------------------------------
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /* Note: Method To Vibrate The Device (Using Internal Vibrator Of Course) */
    private void onSystemVibrate(int milli) {
        Log.d("Running onSystem", "Running Internal Device Vibrator");
        Vibrator oVibrate = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        if (oVibrate.hasVibrator()) {
            oVibrate.vibrate(milli);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // TimerActivity Activate Method --------------------------------------------------------------
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /* */
    private void onActivateTimerActivity() {
        Log.d("Running onActivate...", "Starting ActivityTimer Activity Intent");
        Intent in = new Intent(this, TimerActivity.class);
        in.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(in);
        onDestroy();
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // SensorEventListener Interface Methods --------------------------------------------------
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /* Note: Method does not need to Implemented for Application (Only Changes Record Rate) */
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Note: Method does not need to Implemented for Application
    }

    /* Note: Method To Detect Changes Of Sensor Which Are Being Applied To The Device
     * Note: Euclidean Norm Highest & Lowest Range: 3.0 + 25.0
     * Todo: Remove Notification When Range Has Been Met */
    @Override
    public void onSensorChanged(SensorEvent event) {
        Log.d("Running onSensorChanged", "Implementing Devices Sensors");
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            x = event.values[0]; // Note: Obtained X Coordinate
            y = event.values[1]; // Note: Obtained Y Coordinate
            z = event.values[2]; // Note: Obtained Z Coordinate
            double value = EuclideanNorm(x, y, z);
            Log.d("Sensor", "Value: " + value);

            if ((value > 25) || (value < 1)) {
                onActivateTimerActivity();
                onSystemVibrate(15000);
                onDestroy();
            }
        }
    }
}