Compare commits

...

11 commits

Author SHA1 Message Date
Tobias Länge
3d0d88b525
Add F-Droid badge to README.md 2026-01-13 13:08:34 +01:00
Izzy
a5afddb770 fastlane: slightly improve formatting for full descriptions 2025-11-24 13:10:13 +01:00
Tobias Länge
4611d41c40
Merge pull request #33 from SecUSo/changelog-v1.2.6
Update changelog for v1.2.6
2025-11-24 11:56:38 +01:00
coderPaddyS
6c5d5c6b81 update changelog for v1.2.6 changes
This commit was created by changelog-from-release in 'Changelog Generation' CI workflow
2025-08-22 10:30:19 +00:00
Patrick Schneider
f07974daee [fix] Adds missing canScheduleExactAlarm guard. 2025-08-22 12:26:27 +02:00
Patrick Schneider
1917800db5 [bump] version. 2025-08-22 09:48:27 +02:00
Patrick Schneider
8b4b0293b1 [fix] Adds missing RECEIVER_NOT_EXPORTED. 2025-08-22 09:47:46 +02:00
Patrick Schneider
cb98c61dbd [fix] Adds missing RECEIVER_NOT_EXPORTED. 2025-08-22 09:40:39 +02:00
coderPaddyS
00aacafa85
Merge pull request #28 from SecUSo/development
Change versionCode to differentiate from last Google Play version
2025-08-03 14:59:15 +02:00
Patrick Schneider
ca48a56dde Change versionCode to differentiate from last Google Play version 2025-08-03 14:53:58 +02:00
Patrick Schneider
5fb7ca4180 [update] Removes the foreground service requirement for the timer service. 2025-08-03 14:52:01 +02:00
10 changed files with 236 additions and 27 deletions

108
CHANGELOG.md Normal file
View file

@ -0,0 +1,108 @@
# Changelog
<a id="v1.2.6"></a>
## [Aktivpause to Go v1.2.6](https://github.com/SecUSo/Aktivpause/releases/tag/v1.2.6) - 2025-08-22
Fixes missing canScheduleExactAlarm check.
**Full Changelog**: https://github.com/SecUSo/Aktivpause/compare/v1.2.5...v1.2.6
[Changes][v1.2.6]
<a id="v1.2.5"></a>
## [Aktivpause to Go v1.2.5](https://github.com/SecUSo/Aktivpause/releases/tag/v1.2.5) - 2025-08-22
Fixes crashes due to missing receiver flags.
**Full Changelog**: https://github.com/SecUSo/Aktivpause/compare/v1.2.4...v1.2.5
[Changes][v1.2.5]
<a id="v1.2.3"></a>
## [Aktivpause to Go v1.2.3](https://github.com/SecUSo/Aktivpause/releases/tag/v1.2.3) - 2025-08-03
## What's Changed
* Change versionCode to differentiate from last Google Play version by [@coderPaddyS](https://github.com/coderPaddyS) in [#28](https://github.com/SecUSo/Aktivpause/pull/28)
**Full Changelog**: https://github.com/SecUSo/Aktivpause/compare/v1.2.2...v1.2.3
[Changes][v1.2.3]
<a id="v1.2.2"></a>
## [Aktivpause to Go v1.2.2](https://github.com/SecUSo/Aktivpause/releases/tag/v1.2.2) - 2025-07-23
## What's Changed
* documentation: Added info re: Privacy Friendly Backup by [@jahway603](https://github.com/jahway603) in [#16](https://github.com/SecUSo/Aktivpause/pull/16)
* Updates Copyright by [@coderPaddyS](https://github.com/coderPaddyS) in [#17](https://github.com/SecUSo/Aktivpause/pull/17)
* Update to SDK 34; Fixes a bug hindering the training to start. by [@coderPaddyS](https://github.com/coderPaddyS) in [#21](https://github.com/SecUSo/Aktivpause/pull/21)
* Adds ci and changelog workflows. by [@coderPaddyS](https://github.com/coderPaddyS) in [#24](https://github.com/SecUSo/Aktivpause/pull/24)
* Updates App-Info by [@coderPaddyS](https://github.com/coderPaddyS) in [#22](https://github.com/SecUSo/Aktivpause/pull/22)
## New Contributors
* [@jahway603](https://github.com/jahway603) made their first contribution in [#16](https://github.com/SecUSo/Aktivpause/pull/16)
**Full Changelog**: https://github.com/SecUSo/Aktivpause/compare/v1.2...v1.2.2
[Changes][v1.2.2]
<a id="v1.2"></a>
## [v1.2](https://github.com/SecUSo/Aktivpause/releases/tag/v1.2) - 2023-05-28
## What's Changed
* Backup integration by [@coderPaddyS](https://github.com/coderPaddyS) in [#14](https://github.com/SecUSo/Aktivpause/pull/14)
## New Contributors
* [@coderPaddyS](https://github.com/coderPaddyS) made their first contribution in [#14](https://github.com/SecUSo/Aktivpause/pull/14)
**Full Changelog**: https://github.com/SecUSo/Aktivpause/compare/v1.1.2...v1.2
[Changes][v1.2]
<a id="v1.1.2"></a>
## [Aktivpause to Go v1.1.2](https://github.com/SecUSo/Aktivpause/releases/tag/v1.1.2) - 2020-07-09
- Evaluation is done. Thank you for participating.
- Removed evaluation link
[Changes][v1.1.2]
<a id="v1.1.1"></a>
## [Aktivpause to Go v1.1.1](https://github.com/SecUSo/Aktivpause/releases/tag/v1.1.1) - 2020-04-02
- Release für PlayStore
[Changes][v1.1.1]
<a id="v1.1"></a>
## [Aktivpause to Go v1.1](https://github.com/SecUSo/Aktivpause/releases/tag/v1.1) - 2020-04-02
- Online-Umfrage Link hinzugefügt
[Changes][v1.1]
<a id="v1.0"></a>
## [Aktivpause to Go (v1.0)](https://github.com/SecUSo/Aktivpause/releases/tag/v1.0) - 2019-10-28
- Initial release
[Changes][v1.0]
[v1.2.6]: https://github.com/SecUSo/Aktivpause/compare/v1.2.5...v1.2.6
[v1.2.5]: https://github.com/SecUSo/Aktivpause/compare/v1.2.3...v1.2.5
[v1.2.3]: https://github.com/SecUSo/Aktivpause/compare/v1.2.2...v1.2.3
[v1.2.2]: https://github.com/SecUSo/Aktivpause/compare/v1.2...v1.2.2
[v1.2]: https://github.com/SecUSo/Aktivpause/compare/v1.1.2...v1.2
[v1.1.2]: https://github.com/SecUSo/Aktivpause/compare/v1.1.1...v1.1.2
[v1.1.1]: https://github.com/SecUSo/Aktivpause/compare/v1.1...v1.1.1
[v1.1]: https://github.com/SecUSo/Aktivpause/compare/v1.0...v1.1
[v1.0]: https://github.com/SecUSo/Aktivpause/tree/v1.0
<!-- Generated by https://github.com/rhysd/changelog-from-release v3.9.0 -->

View file

@ -14,6 +14,8 @@
## Aktivpause
[<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="60">](https://f-droid.org/repository/browse/?fdid=org.secuso.aktivpause)
The Aktivpause to Go App allows you to integrate planned breaks into your daily work. You can decide when, where and for how long you want to take breaks and this app will help shape your break in a healthy way. It offers a wide variety of exercises from the well-established Aktivpause program at KIT and was developed by Scientists at the Institute of Sports and Sports Science (IfSS) of KIT. Exercises are currently only provided in german.
## Download and more Information

View file

@ -10,8 +10,8 @@ android {
applicationId "org.secuso.aktivpause"
minSdkVersion 21
targetSdkVersion 34
versionCode 11
versionName "1.2.2"
versionCode 102
versionName "1.2.6"
vectorDrawables.useSupportLibrary = true
}
buildTypes {

View file

@ -10,8 +10,6 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<application
android:name=".PFAktivpause"
@ -120,8 +118,7 @@
<service
android:name="org.secuso.aktivpause.service.TimerService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="specialUse"/>
android:exported="false" />
<service
android:name=".backup.PFABackupService"
android:enabled="true"

View file

@ -2,9 +2,11 @@ package org.secuso.aktivpause.activities;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
@ -12,6 +14,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.preference.PreferenceManager;
@ -117,14 +120,39 @@ public class ExerciseActivity extends AppCompatActivity implements LoaderManager
private SharedPreferences pref;
private Handler mHandler;
private TimerService timerService = null;
private boolean serviceBound = false;
/**
* Defines callbacks for service binding, passed to bindService()
* Performs an initial GUI update when connection is established.
**/
private final ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
TimerService.TimerServiceBinder binder = (TimerService.TimerServiceBinder) service;
timerService = binder.getService();
serviceBound = true;
timerService.setIsAppInBackground(false);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
serviceBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercise);
Intent stopTimer = new Intent(this, TimerService.class);
stopTimer.setAction(ACTION_STOP_TIMER);
startService(stopTimer);
bindService(stopTimer, serviceConnection, Context.BIND_AUTO_CREATE);
// stopTimer.setAction(ACTION_STOP_TIMER);
// startService(stopTimer);
mHandler = new Handler();
@ -327,6 +355,10 @@ public class ExerciseActivity extends AppCompatActivity implements LoaderManager
super.onResume();
isActivityVisible = true;
if (timerService != null) {
timerService.setIsAppInBackground(false);
}
if (isBreakFinished) {
showEndDialog(this);
}
@ -341,6 +373,10 @@ public class ExerciseActivity extends AppCompatActivity implements LoaderManager
super.onPause();
isActivityVisible = false;
if (timerService != null) {
timerService.setIsAppInBackground(true);
}
if(isBreakFinished) {
// TODO: Either start a short Timer to see if the user comes back - or start the next work time rand finish this activity
// TODO: for now we just finish
@ -350,6 +386,28 @@ public class ExerciseActivity extends AppCompatActivity implements LoaderManager
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
/**
* Stop the notification when activity is destroyed
*/
@Override
public void onDestroy() {
if (timerService != null) {
timerService.workoutClosed();
}
super.onDestroy();
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (serviceBound) {
unbindService(serviceConnection);
serviceBound = false;
}
}
@Override
public void onLoadFinished(Loader<ExerciseSet> loader, ExerciseSet set) {
if (set != null) {

View file

@ -15,6 +15,7 @@ import android.preference.PreferenceManager;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.AsyncTaskLoader;
import androidx.loader.content.Loader;
@ -231,7 +232,7 @@ public class TimerActivity extends BaseActivity implements LoaderManager.LoaderC
isActivityVisible = true;
registerReceiver(timerReceiver, new IntentFilter(TimerService.TIMER_BROADCAST));
ContextCompat.registerReceiver(this, timerReceiver, new IntentFilter(TimerService.TIMER_BROADCAST), ContextCompat.RECEIVER_NOT_EXPORTED);
if(mTimerService != null && !mTimerService.isRunning()) {
updateProgress(mTimerService.getInitialDuration());

View file

@ -11,6 +11,7 @@ import android.os.Build;
import android.os.IBinder;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.core.app.AlarmManagerCompat;
import androidx.legacy.content.WakefulBroadcastReceiver;
import org.secuso.aktivpause.service.TimerService;
@ -79,7 +80,7 @@ public class TimerSchedulerReceiver extends WakefulBroadcastReceiver {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent automaticTimerIntent = new Intent(context, TimerSchedulerReceiver.class);
PendingIntent automaticTimerPending = PendingIntent.getBroadcast(context, 0, automaticTimerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent automaticTimerPending = PendingIntent.getBroadcast(context, 0, automaticTimerIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
@ -143,12 +144,8 @@ public class TimerSchedulerReceiver extends WakefulBroadcastReceiver {
}
}
if(done || !scheduleExerciseDaysEnabled) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), automaticTimerPending);
} else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), automaticTimerPending);
}
if((done || !scheduleExerciseDaysEnabled) && (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) || alarmManager.canScheduleExactAlarms()) {
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), automaticTimerPending);
}
}

View file

@ -12,6 +12,7 @@ import android.content.SharedPreferences;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.Settings;
@ -56,6 +57,9 @@ public class TimerService extends Service {
private static final int UPDATE_INTERVAL = 125;
public static final int NOTIFICATION_ID = 31337;
private NotificationCompat.Builder notiBuilder = null;
private NotificationManager notiManager = null;
private boolean isAppInBackground = false;
private TimerServiceBinder mBinder = new TimerServiceBinder();
private CountDownTimer mTimer;
@ -143,7 +147,7 @@ public class TimerService extends Service {
super.onCreate();
registerReceiver(timerReceiver, new IntentFilter(TIMER_BROADCAST));
ContextCompat.registerReceiver(this, timerReceiver, new IntentFilter(TIMER_BROADCAST), ContextCompat.RECEIVER_NOT_EXPORTED);
ContextCompat.registerReceiver(this, notificationDeletedReceiver, new IntentFilter(ACTION_NOTIFICATION_DELETED), ContextCompat.RECEIVER_NOT_EXPORTED);
ContextCompat.registerReceiver(this, notificationPreferenceChangedReceiver, new IntentFilter(ACTION_NOTIFICATION_CANCELED), ContextCompat.RECEIVER_NOT_EXPORTED);
}
@ -366,13 +370,50 @@ public class TimerService extends Service {
}
private void updateNotification() {
if(isRunning() || isPaused()) {
ServiceCompat.startForeground(this, NOTIFICATION_ID, buildNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
} else {
stopForeground(true);
if(isAppInBackground) {
Notification notification = buildNotification();
notiManager.notify(NOTIFICATION_ID, notification);
}
else if(notiManager != null) {
notiManager.cancel(NOTIFICATION_ID);
}
}
/**
* Check if the app is in the background.
* If so, start a notification showing the current timer.
*
* @param isInBackground Sets global flag to determine whether the app is in the background
*/
public void setIsAppInBackground(boolean isInBackground){
this.isAppInBackground = isInBackground;
//Execute after short delay to prevent short notification popup if workoutActivity is closed
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
updateNotification();
}
}, 700);
}
/**
* Cancel the notification when workout activity is destroyed
*/
public void workoutClosed(){
this.isAppInBackground = false;
notiManager.cancel(NOTIFICATION_ID);
}
// private void updateNotification() {
// if(isRunning() || isPaused()) {
// ServiceCompat.startForeground(this, NOTIFICATION_ID, buildNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
// } else {
// stopForeground(true);
// }
// }
@Override
public IBinder onBind(Intent intent) {
return mBinder;

View file

@ -1,5 +1,7 @@
Die Aktivpause-App ermöglicht es Ihnen, selbstständig Bewegungspausen durchzuführen und so ganz individuell eine gezielte Auszeit in Ihren Arbeitsalltag zu integrieren. Wann, wo und wie lange Sie aktive Pausen machen, können Sie somit für sich persönlich entscheiden. Das breite Übungsspektrum stammt aus dem etablierten Aktivpause-Programm am KIT und wurde von Wissenschaftler*innen am Institut für Sport und Sportwissenschaft des KIT zusammengestellt.
Folgende Features bietet die Aktivpause-App:
1. Auswahl und Erstellung von Übungssets: Aus den vorhandenen Übungen lassen sich individuelle Übungssets zusammenstellen, die für die Pausen ausgewählt werden können. Es stehen auch vordefinierte Übungssets zur Verfügung, die Ihnen den Start erleichtern.
2. Das Übungsspektrum reicht von Übungen zur Aktivierung des Herz-Kreislauf-Systems über Dehnungs- und Kräftigungs- bis hin zu Entspannungsübungen.
3. Mit der Filterfunktion können Sie gezielt Übungen nach Körperregion auswählen und etwaige Beschwerden vorbeugen.
@ -8,6 +10,7 @@ Folgende Features bietet die Aktivpause-App:
Kontaktieren Sie uns gerne über:
Bluesky - @secusoresearch.bsky.social https://bsky.app/profile/secusoresearch.bsky.social
Mastodon - @SECUSO_Research@bawü.social https://xn--baw-joa.social/@SECUSO_Research/
Offene Stellen - https://secuso.aifb.kit.edu/83.php
* Bluesky - @secusoresearch.bsky.social https://bsky.app/profile/secusoresearch.bsky.social
* Mastodon - @SECUSO_Research@bawü.social https://xn--baw-joa.social/@SECUSO_Research/
* Offene Stellen - https://secuso.aifb.kit.edu/83.php

View file

@ -1,6 +1,7 @@
The Aktivpause to Go App allows you to integrate planned breaks into your daily work. You can decide when, where and for how long you want to take breaks and this app will help shape your break in a healthy way. It offers a wide variety of exercises from the well-established Aktivpause program at KIT and was developed by Scientists at the Institute of Sports and Sports Science (IfSS) of KIT. Exercises are currently only provided in german.
The following features are provided by the app:
1. Creation and Choice of exercise sets: Individual exercise sets can be created. This makes it easier to complete your favorite exercises faster. The exercise sets can then be chosen to perform during breaks. There are also predefined exercise sets to ease the start into the app.
2. There are a wide variety of exercises: Exercises to activate the cardiovascular system, stretching, strength, and relaxation exercises.
3. The filter feature lets you easily choose exercises for specific body regions that may help you prevent potential complaints.
@ -8,6 +9,7 @@ The following features are provided by the app:
5. Integrate the Aktivpause break into your daily routine. You can schedule breaks to start at specific times and days, so you dont have to think about starting the timer manually to be reminded to take breaks.
Feel free to contact us via:
Bluesky - @secusoresearch.bsky.social https://bsky.app/profile/secusoresearch.bsky.social
Mastodon - @SECUSO_Research@bawü.social https://xn--baw-joa.social/@SECUSO_Research/
Job opening - https://secuso.aifb.kit.edu/english/Job_Offers.php
* Bluesky - @secusoresearch.bsky.social https://bsky.app/profile/secusoresearch.bsky.social
* Mastodon - @SECUSO_Research@bawü.social https://xn--baw-joa.social/@SECUSO_Research/
* Job opening - https://secuso.aifb.kit.edu/english/Job_Offers.php