Skip to content

Commit

Permalink
Merge branch 'foregroundservice'
Browse files Browse the repository at this point in the history
  • Loading branch information
j4velin committed Nov 5, 2018
2 parents b006ed2 + c315a7a commit 57973f2
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 88 deletions.
5 changes: 2 additions & 3 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
package="de.j4velin.pedometer"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="156"
android:versionName="1.5.6">
android:versionCode="158"
android:versionName="1.5.8">

<uses-sdk
android:maxSdkVersion="27"
android:minSdkVersion="19"
android:targetSdkVersion="26"/>

Expand Down
26 changes: 16 additions & 10 deletions src/main/java/de/j4velin/pedometer/AppUpdatedReceiver.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
* Copyright 2013 Thomas Hoffmann
*
*
* 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.
Expand All @@ -16,18 +16,24 @@

package de.j4velin.pedometer;

import de.j4velin.pedometer.util.Logger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

import de.j4velin.pedometer.util.API26Wrapper;
import de.j4velin.pedometer.util.Logger;

public class AppUpdatedReceiver extends BroadcastReceiver {

@Override
public void onReceive(final Context context, final Intent intent) {
if (BuildConfig.DEBUG)
Logger.log("app updated");
context.startService(new Intent(context, SensorListener.class));
}
@Override
public void onReceive(final Context context, final Intent intent) {
if (BuildConfig.DEBUG) Logger.log("app updated");
if (Build.VERSION.SDK_INT >= 26) {
API26Wrapper.startForegroundService(context, new Intent(context, SensorListener.class));
} else {
context.startService(new Intent(context, SensorListener.class));
}
}

}
10 changes: 8 additions & 2 deletions src/main/java/de/j4velin/pedometer/BootReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;

import de.j4velin.pedometer.util.API26Wrapper;
import de.j4velin.pedometer.util.Logger;

public class BootReceiver extends BroadcastReceiver {
Expand All @@ -46,7 +48,11 @@ public void onReceive(final Context context, final Intent intent) {
db.saveCurrentSteps(0);
db.close();
prefs.edit().remove("correctShutdown").apply();

context.startService(new Intent(context, SensorListener.class));

if (Build.VERSION.SDK_INT >= 26) {
API26Wrapper.startForegroundService(context, new Intent(context, SensorListener.class));
} else {
context.startService(new Intent(context, SensorListener.class));
}
}
}
117 changes: 60 additions & 57 deletions src/main/java/de/j4velin/pedometer/SensorListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import de.j4velin.pedometer.ui.Activity_Main;
import de.j4velin.pedometer.util.API23Wrapper;
import de.j4velin.pedometer.util.API26Wrapper;
import de.j4velin.pedometer.util.Logger;
import de.j4velin.pedometer.util.Util;
import de.j4velin.pedometer.widget.WidgetUpdateService;
Expand All @@ -52,7 +53,7 @@
*/
public class SensorListener extends Service implements SensorEventListener {

private final static int NOTIFICATION_ID = 1;
public final static int NOTIFICATION_ID = 1;
private final static long MICROSECONDS_IN_ONE_MINUTE = 60000000;
private final static long SAVE_OFFSET_TIME = AlarmManager.INTERVAL_HOUR;
private final static int SAVE_OFFSET_STEPS = 500;
Expand All @@ -63,8 +64,6 @@ public class SensorListener extends Service implements SensorEventListener {

private final BroadcastReceiver shutdownReceiver = new ShutdownRecevier();

public final static String ACTION_UPDATE_NOTIFICATION = "updateNotificationState";

@Override
public void onAccuracyChanged(final Sensor sensor, int accuracy) {
// nobody knows what happens here: step value might magically decrease
Expand All @@ -83,7 +82,10 @@ public void onSensorChanged(final SensorEvent event) {
}
}

private void updateIfNecessary() {
/**
* @return true, if notification was updated
*/
private boolean updateIfNecessary() {
if (steps > lastSaveSteps + SAVE_OFFSET_STEPS ||
(steps > 0 && System.currentTimeMillis() > lastSaveTime + SAVE_OFFSET_TIME)) {
if (BuildConfig.DEBUG) Logger.log(
Expand All @@ -105,8 +107,23 @@ private void updateIfNecessary() {
db.close();
lastSaveSteps = steps;
lastSaveTime = System.currentTimeMillis();
updateNotificationState();
showNotification(); // update notification
startService(new Intent(this, WidgetUpdateService.class));
return true;
} else {
return false;
}
}

private void showNotification() {
if (Build.VERSION.SDK_INT >= 26) {
startForeground(NOTIFICATION_ID, getNotification(this));
} else if (getSharedPreferences("pedometer", Context.MODE_PRIVATE)
.getBoolean("notification", true)) {
{
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE))
.notify(NOTIFICATION_ID, getNotification(this));
}
}
}

Expand All @@ -117,12 +134,10 @@ public IBinder onBind(final Intent intent) {

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
if (intent != null && intent.getBooleanExtra(ACTION_UPDATE_NOTIFICATION, false)) {
updateNotificationState();
} else {
reRegisterSensor();
registerBroadcastReceiver();
updateIfNecessary();
reRegisterSensor();
registerBroadcastReceiver();
if (!updateIfNecessary()) {
showNotification();
}

// restart service every hour to save the current step count
Expand All @@ -147,8 +162,6 @@ public int onStartCommand(final Intent intent, int flags, int startId) {
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) Logger.log("SensorListener onCreate");
reRegisterSensor();
updateNotificationState();
}

@Override
Expand All @@ -174,41 +187,38 @@ public void onDestroy() {
}
}

private void updateNotificationState() {
if (BuildConfig.DEBUG) Logger.log("SensorListener updateNotificationState");
SharedPreferences prefs = getSharedPreferences("pedometer", Context.MODE_PRIVATE);
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());
if (steps == 0)
steps = db.getCurrentSteps(); // use saved value if we haven't anything better
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 { // still no step value?
notificationBuilder
.setContentText(getString(R.string.your_progress_will_be_shown_here_soon));
}
notificationBuilder.setPriority(Notification.PRIORITY_MIN).setShowWhen(false)
.setContentTitle(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).setOngoing(true);
nm.notify(NOTIFICATION_ID, notificationBuilder.build());
} else {
nm.cancel(NOTIFICATION_ID);
public static Notification getNotification(final Context context) {
if (BuildConfig.DEBUG) Logger.log("getNotification");
SharedPreferences prefs = context.getSharedPreferences("pedometer", Context.MODE_PRIVATE);
int goal = prefs.getInt("goal", 10000);
Database db = Database.getInstance(context);
int today_offset = db.getSteps(Util.getToday());
if (steps == 0)
steps = db.getCurrentSteps(); // use saved value if we haven't anything better
db.close();
Notification.Builder notificationBuilder =
Build.VERSION.SDK_INT >= 26 ? API26Wrapper.getNotificationBuilder(context) :
new Notification.Builder(context);
if (steps > 0) {
if (today_offset == Integer.MIN_VALUE) today_offset = -steps;
notificationBuilder.setProgress(goal, today_offset + steps, false).setContentText(
today_offset + steps >= goal ?
context.getString(R.string.goal_reached_notification,
NumberFormat.getInstance(Locale.getDefault())
.format((today_offset + steps))) :
context.getString(R.string.notification_text,
NumberFormat.getInstance(Locale.getDefault())
.format((goal - today_offset - steps))));
} else { // still no step value?
notificationBuilder.setContentText(
context.getString(R.string.your_progress_will_be_shown_here_soon));
}
notificationBuilder.setPriority(Notification.PRIORITY_MIN).setShowWhen(false)
.setContentTitle(context.getString(R.string.notification_title)).setContentIntent(
PendingIntent.getActivity(context, 0, new Intent(context, Activity_Main.class),
PendingIntent.FLAG_UPDATE_CURRENT)).setSmallIcon(R.drawable.ic_notification)
.setOngoing(true);
return notificationBuilder.build();
}

private void registerBroadcastReceiver() {
Expand All @@ -234,15 +244,8 @@ private void reRegisterSensor() {
Logger.log("default: " + sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER).getName());
}

if (Build.VERSION.SDK_INT >= 27) {
// do not use batching on Android P and newer as we dont live long enough to recieve
// those value due to aggressive power saving
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
SensorManager.SENSOR_DELAY_FASTEST);
} else {
// enable batching with delay of max 5 min
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
SensorManager.SENSOR_DELAY_NORMAL, (int) (5 * MICROSECONDS_IN_ONE_MINUTE));
}
// enable batching with delay of max 5 min
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
SensorManager.SENSOR_DELAY_NORMAL, (int) (5 * MICROSECONDS_IN_ONE_MINUTE));
}
}
13 changes: 11 additions & 2 deletions src/main/java/de/j4velin/pedometer/ui/Fragment_Overview.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Pair;
import android.view.LayoutInflater;
Expand All @@ -50,6 +52,8 @@
import de.j4velin.pedometer.BuildConfig;
import de.j4velin.pedometer.Database;
import de.j4velin.pedometer.R;
import de.j4velin.pedometer.SensorListener;
import de.j4velin.pedometer.util.API26Wrapper;
import de.j4velin.pedometer.util.Logger;
import de.j4velin.pedometer.util.Util;

Expand All @@ -67,11 +71,16 @@ public class Fragment_Overview extends Fragment implements SensorEventListener {
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
if (Build.VERSION.SDK_INT >= 26) {
API26Wrapper.startForegroundService(getActivity(),
new Intent(getActivity(), SensorListener.class));
} else {
getActivity().startService(new Intent(getActivity(), SensorListener.class));
}
}

@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_overview, null);
stepsView = (TextView) v.findViewById(R.id.steps);
totalView = (TextView) v.findViewById(R.id.total);
Expand Down
Loading

0 comments on commit 57973f2

Please sign in to comment.