Skip to content

Commit 57973f2

Browse files
committed
Merge branch 'foregroundservice'
2 parents b006ed2 + c315a7a commit 57973f2

File tree

9 files changed

+226
-88
lines changed

9 files changed

+226
-88
lines changed

src/main/AndroidManifest.xml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
package="de.j4velin.pedometer"
44
xmlns:android="http://schemas.android.com/apk/res/android"
55
xmlns:tools="http://schemas.android.com/tools"
6-
android:versionCode="156"
7-
android:versionName="1.5.6">
6+
android:versionCode="158"
7+
android:versionName="1.5.8">
88

99
<uses-sdk
10-
android:maxSdkVersion="27"
1110
android:minSdkVersion="19"
1211
android:targetSdkVersion="26"/>
1312

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*
22
* Copyright 2013 Thomas Hoffmann
3-
*
3+
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,18 +16,24 @@
1616

1717
package de.j4velin.pedometer;
1818

19-
import de.j4velin.pedometer.util.Logger;
2019
import android.content.BroadcastReceiver;
2120
import android.content.Context;
2221
import android.content.Intent;
22+
import android.os.Build;
23+
24+
import de.j4velin.pedometer.util.API26Wrapper;
25+
import de.j4velin.pedometer.util.Logger;
2326

2427
public class AppUpdatedReceiver extends BroadcastReceiver {
2528

26-
@Override
27-
public void onReceive(final Context context, final Intent intent) {
28-
if (BuildConfig.DEBUG)
29-
Logger.log("app updated");
30-
context.startService(new Intent(context, SensorListener.class));
31-
}
29+
@Override
30+
public void onReceive(final Context context, final Intent intent) {
31+
if (BuildConfig.DEBUG) Logger.log("app updated");
32+
if (Build.VERSION.SDK_INT >= 26) {
33+
API26Wrapper.startForegroundService(context, new Intent(context, SensorListener.class));
34+
} else {
35+
context.startService(new Intent(context, SensorListener.class));
36+
}
37+
}
3238

3339
}

src/main/java/de/j4velin/pedometer/BootReceiver.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import android.content.Context;
2121
import android.content.Intent;
2222
import android.content.SharedPreferences;
23+
import android.os.Build;
2324

25+
import de.j4velin.pedometer.util.API26Wrapper;
2426
import de.j4velin.pedometer.util.Logger;
2527

2628
public class BootReceiver extends BroadcastReceiver {
@@ -46,7 +48,11 @@ public void onReceive(final Context context, final Intent intent) {
4648
db.saveCurrentSteps(0);
4749
db.close();
4850
prefs.edit().remove("correctShutdown").apply();
49-
50-
context.startService(new Intent(context, SensorListener.class));
51+
52+
if (Build.VERSION.SDK_INT >= 26) {
53+
API26Wrapper.startForegroundService(context, new Intent(context, SensorListener.class));
54+
} else {
55+
context.startService(new Intent(context, SensorListener.class));
56+
}
5157
}
5258
}

src/main/java/de/j4velin/pedometer/SensorListener.java

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
import de.j4velin.pedometer.ui.Activity_Main;
4141
import de.j4velin.pedometer.util.API23Wrapper;
42+
import de.j4velin.pedometer.util.API26Wrapper;
4243
import de.j4velin.pedometer.util.Logger;
4344
import de.j4velin.pedometer.util.Util;
4445
import de.j4velin.pedometer.widget.WidgetUpdateService;
@@ -52,7 +53,7 @@
5253
*/
5354
public class SensorListener extends Service implements SensorEventListener {
5455

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

6465
private final BroadcastReceiver shutdownReceiver = new ShutdownRecevier();
6566

66-
public final static String ACTION_UPDATE_NOTIFICATION = "updateNotificationState";
67-
6867
@Override
6968
public void onAccuracyChanged(final Sensor sensor, int accuracy) {
7069
// nobody knows what happens here: step value might magically decrease
@@ -83,7 +82,10 @@ public void onSensorChanged(final SensorEvent event) {
8382
}
8483
}
8584

86-
private void updateIfNecessary() {
85+
/**
86+
* @return true, if notification was updated
87+
*/
88+
private boolean updateIfNecessary() {
8789
if (steps > lastSaveSteps + SAVE_OFFSET_STEPS ||
8890
(steps > 0 && System.currentTimeMillis() > lastSaveTime + SAVE_OFFSET_TIME)) {
8991
if (BuildConfig.DEBUG) Logger.log(
@@ -105,8 +107,23 @@ private void updateIfNecessary() {
105107
db.close();
106108
lastSaveSteps = steps;
107109
lastSaveTime = System.currentTimeMillis();
108-
updateNotificationState();
110+
showNotification(); // update notification
109111
startService(new Intent(this, WidgetUpdateService.class));
112+
return true;
113+
} else {
114+
return false;
115+
}
116+
}
117+
118+
private void showNotification() {
119+
if (Build.VERSION.SDK_INT >= 26) {
120+
startForeground(NOTIFICATION_ID, getNotification(this));
121+
} else if (getSharedPreferences("pedometer", Context.MODE_PRIVATE)
122+
.getBoolean("notification", true)) {
123+
{
124+
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE))
125+
.notify(NOTIFICATION_ID, getNotification(this));
126+
}
110127
}
111128
}
112129

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

118135
@Override
119136
public int onStartCommand(final Intent intent, int flags, int startId) {
120-
if (intent != null && intent.getBooleanExtra(ACTION_UPDATE_NOTIFICATION, false)) {
121-
updateNotificationState();
122-
} else {
123-
reRegisterSensor();
124-
registerBroadcastReceiver();
125-
updateIfNecessary();
137+
reRegisterSensor();
138+
registerBroadcastReceiver();
139+
if (!updateIfNecessary()) {
140+
showNotification();
126141
}
127142

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

154167
@Override
@@ -174,41 +187,38 @@ public void onDestroy() {
174187
}
175188
}
176189

177-
private void updateNotificationState() {
178-
if (BuildConfig.DEBUG) Logger.log("SensorListener updateNotificationState");
179-
SharedPreferences prefs = getSharedPreferences("pedometer", Context.MODE_PRIVATE);
180-
NotificationManager nm =
181-
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
182-
if (prefs.getBoolean("notification", true)) {
183-
int goal = prefs.getInt("goal", 10000);
184-
Database db = Database.getInstance(this);
185-
int today_offset = db.getSteps(Util.getToday());
186-
if (steps == 0)
187-
steps = db.getCurrentSteps(); // use saved value if we haven't anything better
188-
db.close();
189-
Notification.Builder notificationBuilder = new Notification.Builder(this);
190-
if (steps > 0) {
191-
if (today_offset == Integer.MIN_VALUE) today_offset = -steps;
192-
notificationBuilder.setProgress(goal, today_offset + steps, false).setContentText(
193-
today_offset + steps >= goal ? getString(R.string.goal_reached_notification,
194-
NumberFormat.getInstance(Locale.getDefault())
195-
.format((today_offset + steps))) :
196-
getString(R.string.notification_text,
197-
NumberFormat.getInstance(Locale.getDefault())
198-
.format((goal - today_offset - steps))));
199-
} else { // still no step value?
200-
notificationBuilder
201-
.setContentText(getString(R.string.your_progress_will_be_shown_here_soon));
202-
}
203-
notificationBuilder.setPriority(Notification.PRIORITY_MIN).setShowWhen(false)
204-
.setContentTitle(getString(R.string.notification_title)).setContentIntent(
205-
PendingIntent.getActivity(this, 0, new Intent(this, Activity_Main.class),
206-
PendingIntent.FLAG_UPDATE_CURRENT))
207-
.setSmallIcon(R.drawable.ic_notification).setOngoing(true);
208-
nm.notify(NOTIFICATION_ID, notificationBuilder.build());
209-
} else {
210-
nm.cancel(NOTIFICATION_ID);
190+
public static Notification getNotification(final Context context) {
191+
if (BuildConfig.DEBUG) Logger.log("getNotification");
192+
SharedPreferences prefs = context.getSharedPreferences("pedometer", Context.MODE_PRIVATE);
193+
int goal = prefs.getInt("goal", 10000);
194+
Database db = Database.getInstance(context);
195+
int today_offset = db.getSteps(Util.getToday());
196+
if (steps == 0)
197+
steps = db.getCurrentSteps(); // use saved value if we haven't anything better
198+
db.close();
199+
Notification.Builder notificationBuilder =
200+
Build.VERSION.SDK_INT >= 26 ? API26Wrapper.getNotificationBuilder(context) :
201+
new Notification.Builder(context);
202+
if (steps > 0) {
203+
if (today_offset == Integer.MIN_VALUE) today_offset = -steps;
204+
notificationBuilder.setProgress(goal, today_offset + steps, false).setContentText(
205+
today_offset + steps >= goal ?
206+
context.getString(R.string.goal_reached_notification,
207+
NumberFormat.getInstance(Locale.getDefault())
208+
.format((today_offset + steps))) :
209+
context.getString(R.string.notification_text,
210+
NumberFormat.getInstance(Locale.getDefault())
211+
.format((goal - today_offset - steps))));
212+
} else { // still no step value?
213+
notificationBuilder.setContentText(
214+
context.getString(R.string.your_progress_will_be_shown_here_soon));
211215
}
216+
notificationBuilder.setPriority(Notification.PRIORITY_MIN).setShowWhen(false)
217+
.setContentTitle(context.getString(R.string.notification_title)).setContentIntent(
218+
PendingIntent.getActivity(context, 0, new Intent(context, Activity_Main.class),
219+
PendingIntent.FLAG_UPDATE_CURRENT)).setSmallIcon(R.drawable.ic_notification)
220+
.setOngoing(true);
221+
return notificationBuilder.build();
212222
}
213223

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

237-
if (Build.VERSION.SDK_INT >= 27) {
238-
// do not use batching on Android P and newer as we dont live long enough to recieve
239-
// those value due to aggressive power saving
240-
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
241-
SensorManager.SENSOR_DELAY_FASTEST);
242-
} else {
243-
// enable batching with delay of max 5 min
244-
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
245-
SensorManager.SENSOR_DELAY_NORMAL, (int) (5 * MICROSECONDS_IN_ONE_MINUTE));
246-
}
247+
// enable batching with delay of max 5 min
248+
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
249+
SensorManager.SENSOR_DELAY_NORMAL, (int) (5 * MICROSECONDS_IN_ONE_MINUTE));
247250
}
248251
}

src/main/java/de/j4velin/pedometer/ui/Fragment_Overview.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import android.app.Fragment;
2020
import android.content.Context;
2121
import android.content.DialogInterface;
22+
import android.content.Intent;
2223
import android.content.SharedPreferences;
2324
import android.graphics.Color;
2425
import android.hardware.Sensor;
2526
import android.hardware.SensorEvent;
2627
import android.hardware.SensorEventListener;
2728
import android.hardware.SensorManager;
29+
import android.os.Build;
2830
import android.os.Bundle;
2931
import android.util.Pair;
3032
import android.view.LayoutInflater;
@@ -50,6 +52,8 @@
5052
import de.j4velin.pedometer.BuildConfig;
5153
import de.j4velin.pedometer.Database;
5254
import de.j4velin.pedometer.R;
55+
import de.j4velin.pedometer.SensorListener;
56+
import de.j4velin.pedometer.util.API26Wrapper;
5357
import de.j4velin.pedometer.util.Logger;
5458
import de.j4velin.pedometer.util.Util;
5559

@@ -67,11 +71,16 @@ public class Fragment_Overview extends Fragment implements SensorEventListener {
6771
public void onCreate(final Bundle savedInstanceState) {
6872
super.onCreate(savedInstanceState);
6973
setHasOptionsMenu(true);
74+
if (Build.VERSION.SDK_INT >= 26) {
75+
API26Wrapper.startForegroundService(getActivity(),
76+
new Intent(getActivity(), SensorListener.class));
77+
} else {
78+
getActivity().startService(new Intent(getActivity(), SensorListener.class));
79+
}
7080
}
7181

7282
@Override
73-
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
74-
final Bundle savedInstanceState) {
83+
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
7584
final View v = inflater.inflate(R.layout.fragment_overview, null);
7685
stepsView = (TextView) v.findViewById(R.id.steps);
7786
totalView = (TextView) v.findViewById(R.id.total);

0 commit comments

Comments
 (0)