Android Open Source - Pedometer Sensor Listener






From Project

Back to project page Pedometer.

License

The source code is released under:

Apache License

If you think the Android project Pedometer 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

/*
 * Copyright 2013 Thomas Hoffmann/*www. j  a  v  a 2 s  .c  om*/
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.j4velin.pedometer.background;

import java.text.NumberFormat;
import java.util.Locale;

import de.j4velin.pedometer.Activity_Main;
import de.j4velin.pedometer.BuildConfig;
import de.j4velin.pedometer.Database;
import de.j4velin.pedometer.R;
import de.j4velin.pedometer.util.Logger;
import de.j4velin.pedometer.util.Util;
import de.j4velin.pedometer.widget.WidgetUpdateService;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
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;

/**
 * Background service which keeps the step-sensor listener alive to always get
 * the number of steps since boot.
 * <p/>
 * This service won't be needed any more if there is a way to read the
 * step-value without waiting for a sensor event
 */
public class SensorListener extends Service implements SensorEventListener {

    public final static String ACTION_PAUSE = "pause";

    private static boolean WAIT_FOR_VALID_STEPS = false;
    private static int steps;

    @Override
    public void onAccuracyChanged(final Sensor sensor, int accuracy) {
        // nobody knows what happens here: step value might magically decrease
        // when this method is called...
        if (BuildConfig.DEBUG) Logger.log(sensor.getName() + " accuracy changed: " + accuracy);
    }

    @Override
    public void onSensorChanged(final SensorEvent event) {
        steps = (int) event.values[0];
        if (WAIT_FOR_VALID_STEPS && steps > 0) {
            WAIT_FOR_VALID_STEPS = false;
            Database db = Database.getInstance(this);
            if (db.getSteps(Util.getToday()) == Integer.MIN_VALUE) {
                int pauseDifference = steps -
                        getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS)
                                .getInt("pauseCount", steps);
                db.insertNewDay(Util.getToday(), steps - pauseDifference);
                if (pauseDifference > 0) {
                    // update pauseCount for the new day
                    getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS).edit()
                            .putInt("pauseCount", steps).commit();
                }
                reRegisterSensor();
            }
            db.saveCurrentSteps(steps);
            db.close();
            updateNotificationState();
            startService(new Intent(this, WidgetUpdateService.class));
        }
    }

    @Override
    public IBinder onBind(final Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
        if (intent != null && ACTION_PAUSE.equals(intent.getStringExtra("action"))) {
            if (BuildConfig.DEBUG)
                Logger.log("onStartCommand action: " + intent.getStringExtra("action"));
            if (steps == 0) {
                Database db = Database.getInstance(this);
                steps = db.getCurrentSteps();
                db.close();
            }
            SharedPreferences prefs = getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS);
            if (prefs.contains("pauseCount")) { // resume counting
                int difference = steps -
                        prefs.getInt("pauseCount", steps); // number of steps taken during the pause
                Database db = Database.getInstance(this);
                db.updateSteps(Util.getToday(), -difference);
                db.close();
                prefs.edit().remove("pauseCount").commit();
                updateNotificationState();
            } else { // pause counting
                // cancel restart
                ((AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE))
                        .cancel(PendingIntent.getService(getApplicationContext(), 2,
                                new Intent(this, SensorListener.class),
                                PendingIntent.FLAG_UPDATE_CURRENT));
                prefs.edit().putInt("pauseCount", steps).commit();
                updateNotificationState();
                stopSelf();
                return START_NOT_STICKY;
            }
        }

        // restart service every hour to get the current step count
        ((AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE))
                .set(AlarmManager.RTC, System.currentTimeMillis() + AlarmManager.INTERVAL_HOUR,
                        PendingIntent.getService(getApplicationContext(), 2,
                                new Intent(this, SensorListener.class),
                                PendingIntent.FLAG_UPDATE_CURRENT));

        WAIT_FOR_VALID_STEPS = true;

        return START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (BuildConfig.DEBUG) Logger.log("SensorListener onCreate");
        reRegisterSensor();
        updateNotificationState();
    }

    @Override
    public void onTaskRemoved(final Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        if (BuildConfig.DEBUG) Logger.log("sensor service task removed");
        // Restart service in 500 ms
        ((AlarmManager) getSystemService(Context.ALARM_SERVICE))
                .set(AlarmManager.RTC, System.currentTimeMillis() + 500, PendingIntent
                        .getService(this, 3, new Intent(this, SensorListener.class), 0));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (BuildConfig.DEBUG) Logger.log("SensorListener onDestroy");
        try {
            SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
            sm.unregisterListener(this);
        } catch (Exception e) {
            if (BuildConfig.DEBUG) Logger.log(e);
            e.printStackTrace();
        }
    }

    private void updateNotificationState() {
        if (BuildConfig.DEBUG) Logger.log("SensorListener updateNotificationState");
        SharedPreferences prefs = getSharedPreferences("pedometer", Context.MODE_MULTI_PROCESS);
        NotificationManager nm =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (prefs.getBoolean("notification", true)) {
            int goal = prefs.getInt("goal", 10000);
            Database db = Database.getInstance(this);
            int today_offset = db.getSteps(Util.getToday());
            db.close();
            Notification.Builder notificationBuilder = new Notification.Builder(this);
            if (steps > 0) {
                if (today_offset == Integer.MIN_VALUE) today_offset = -steps;
                notificationBuilder.setProgress(goal, today_offset + steps, false).setContentText(
                        today_offset + steps >= goal ? getString(R.string.goal_reached_notification,
                                NumberFormat.getInstance(Locale.getDefault())
                                        .format((today_offset + steps))) :
                                getString(R.string.notification_text,
                                        NumberFormat.getInstance(Locale.getDefault())
                                                .format((goal - today_offset - steps))));
            } else {
                notificationBuilder
                        .setContentText(getString(R.string.your_progress_will_be_shown_here_soon));
            }
            boolean isPaused = prefs.contains("pauseCount");
            notificationBuilder.setPriority(Notification.PRIORITY_MIN).setShowWhen(false)
                    .setContentTitle(isPaused ? getString(R.string.ispaused) :
                            getString(R.string.notification_title)).setContentIntent(PendingIntent
                    .getActivity(this, 0, new Intent(this, Activity_Main.class),
                            PendingIntent.FLAG_UPDATE_CURRENT)).setSmallIcon(R.drawable.ic_notification)
                    .addAction(isPaused ? R.drawable.ic_resume : R.drawable.ic_pause,
                            isPaused ? getString(R.string.resume) : getString(R.string.pause),
                            PendingIntent.getService(this, 4, new Intent(this, SensorListener.class)
                                            .putExtra("action", ACTION_PAUSE),
                                    PendingIntent.FLAG_UPDATE_CURRENT)).setOngoing(true);
            nm.notify(1, notificationBuilder.build());
        } else {
            nm.cancel(1);
        }
    }

    private void reRegisterSensor() {
        if (BuildConfig.DEBUG) Logger.log("re-register sensor listener");
        SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
        try {
            sm.unregisterListener(this);
        } catch (Exception e) {
            if (BuildConfig.DEBUG) Logger.log(e);
            e.printStackTrace();
        }

        sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
                SensorManager.SENSOR_DELAY_NORMAL);
    }
}




Java Source Code List

com.google.example.games.basegameutils.ApplicationTest.java
com.google.example.games.basegameutils.BaseGameActivity.java
com.google.example.games.basegameutils.GameHelperUtils.java
com.google.example.games.basegameutils.GameHelper.java
com.nineoldandroids.ApplicationTest.java
com.nineoldandroids.animation.AnimatorInflater.java
com.nineoldandroids.animation.AnimatorListenerAdapter.java
com.nineoldandroids.animation.AnimatorSet.java
com.nineoldandroids.animation.Animator.java
com.nineoldandroids.animation.ArgbEvaluator.java
com.nineoldandroids.animation.FloatEvaluator.java
com.nineoldandroids.animation.FloatKeyframeSet.java
com.nineoldandroids.animation.IntEvaluator.java
com.nineoldandroids.animation.IntKeyframeSet.java
com.nineoldandroids.animation.KeyframeSet.java
com.nineoldandroids.animation.Keyframe.java
com.nineoldandroids.animation.ObjectAnimator.java
com.nineoldandroids.animation.PreHoneycombCompat.java
com.nineoldandroids.animation.PropertyValuesHolder.java
com.nineoldandroids.animation.TimeAnimator.java
com.nineoldandroids.animation.TypeEvaluator.java
com.nineoldandroids.animation.ValueAnimator.java
com.nineoldandroids.util.FloatProperty.java
com.nineoldandroids.util.IntProperty.java
com.nineoldandroids.util.NoSuchPropertyException.java
com.nineoldandroids.util.Property.java
com.nineoldandroids.util.ReflectiveProperty.java
com.nineoldandroids.view.ViewHelper.java
com.nineoldandroids.view.ViewPropertyAnimatorHC.java
com.nineoldandroids.view.ViewPropertyAnimatorICS.java
com.nineoldandroids.view.ViewPropertyAnimatorPreHC.java
com.nineoldandroids.view.ViewPropertyAnimator.java
com.nineoldandroids.view.animation.AnimatorProxy.java
de.j4velin.pedometer.Activity_Main.java
de.j4velin.pedometer.AppUpdatedReceiver.java
de.j4velin.pedometer.ApplicationTest.java
de.j4velin.pedometer.BootReceiver.java
de.j4velin.pedometer.Database.java
de.j4velin.pedometer.Dialog_Split.java
de.j4velin.pedometer.Dialog_Statistics.java
de.j4velin.pedometer.Fragment_Overview.java
de.j4velin.pedometer.Fragment_Settings.java
de.j4velin.pedometer.PlayServices.java
de.j4velin.pedometer.background.SensorListener.java
de.j4velin.pedometer.background.ShutdownRecevier.java
de.j4velin.pedometer.util.ColorPreview.java
de.j4velin.pedometer.util.Logger.java
de.j4velin.pedometer.util.TimeZoneListener.java
de.j4velin.pedometer.util.Util.java
de.j4velin.pedometer.widget.DashClock.java
de.j4velin.pedometer.widget.WidgetConfig.java
de.j4velin.pedometer.widget.WidgetUpdateService.java
de.j4velin.pedometer.widget.Widget.java
net.margaritov.preference.colorpicker.AlphaPatternDrawable.java
net.margaritov.preference.colorpicker.ApplicationTest.java
net.margaritov.preference.colorpicker.ColorPickerDialog.java
net.margaritov.preference.colorpicker.ColorPickerPanelView.java
net.margaritov.preference.colorpicker.ColorPickerPreference.java
net.margaritov.preference.colorpicker.ColorPickerView.java
net.margaritov.preference.colorpicker.Test.java
org.eazegraph.lib.ApplicationTest.java
org.eazegraph.lib.charts.BarChart.java
org.eazegraph.lib.charts.BaseBarChart.java
org.eazegraph.lib.charts.BaseChart.java
org.eazegraph.lib.charts.PieChart.java
org.eazegraph.lib.charts.StackedBarChart.java
org.eazegraph.lib.charts.ValueLineChart.java
org.eazegraph.lib.communication.IOnBarClickedListener.java
org.eazegraph.lib.communication.IOnItemFocusChangedListener.java
org.eazegraph.lib.communication.IOnPointFocusedListener.java
org.eazegraph.lib.models.BarModel.java
org.eazegraph.lib.models.BaseModel.java
org.eazegraph.lib.models.LegendModel.java
org.eazegraph.lib.models.PieModel.java
org.eazegraph.lib.models.Point2D.java
org.eazegraph.lib.models.StackedBarModel.java
org.eazegraph.lib.models.StandardValue.java
org.eazegraph.lib.models.ValueLinePoint.java
org.eazegraph.lib.models.ValueLineSeries.java
org.eazegraph.lib.utils.Utils.java