diff --git a/pretixprint/app/src/main/AndroidManifest.xml b/pretixprint/app/src/main/AndroidManifest.xml
index f0975ac1..cf2b2708 100644
--- a/pretixprint/app/src/main/AndroidManifest.xml
+++ b/pretixprint/app/src/main/AndroidManifest.xml
@@ -124,6 +124,12 @@
+
+
diff --git a/pretixprint/app/src/main/java/eu/pretix/pretixprint/print/KeepaliveService.kt b/pretixprint/app/src/main/java/eu/pretix/pretixprint/print/KeepaliveService.kt
new file mode 100644
index 00000000..313b2253
--- /dev/null
+++ b/pretixprint/app/src/main/java/eu/pretix/pretixprint/print/KeepaliveService.kt
@@ -0,0 +1,83 @@
+package eu.pretix.pretixprint.print
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.os.Build
+import android.os.IBinder
+import androidx.core.app.NotificationCompat
+import eu.pretix.pretixprint.R
+import eu.pretix.pretixprint.ui.SettingsActivity
+
+class KeepaliveService : Service() {
+
+ companion object {
+ val CHANNEL_ID = "pretixprint_keepalive_channel"
+ val ONGOING_NOTIFICATION_ID = 43
+
+ fun start(context: Context) {
+ val intent = Intent(context, KeepaliveService::class.java)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ context.startForegroundService(intent)
+ } else {
+ context.startService(intent)
+ }
+ }
+ }
+
+ private fun _startForeground() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val channel = NotificationChannel(
+ CHANNEL_ID,
+ getString(R.string.notification_channel_keepalive),
+ NotificationManager.IMPORTANCE_LOW
+ )
+ channel.description = getString(R.string.notification_channel_keepalive_description)
+ channel.setSound(null, null)
+ channel.enableVibration(false)
+ getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
+ }
+
+ val startBaseActivity = Intent(this, SettingsActivity::class.java)
+ startBaseActivity.action = Intent.ACTION_MAIN
+ startBaseActivity.addCategory(Intent.CATEGORY_LAUNCHER)
+ startBaseActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+
+ val keepAliveNotification: Notification =
+ NotificationCompat.Builder(this, CHANNEL_ID)
+ .setContentTitle(getString(R.string.keepalive_notification))
+ .setSmallIcon(R.drawable.ic_stat_print)
+ .setContentIntent(
+ PendingIntent.getActivity(
+ this,
+ 0,
+ startBaseActivity,
+ if (Build.VERSION.SDK_INT >= 23) {
+ PendingIntent.FLAG_IMMUTABLE
+ } else {
+ 0
+ }
+ )
+ )
+ .build()
+ this.startForeground(ONGOING_NOTIFICATION_ID, keepAliveNotification)
+ }
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ _startForeground()
+ return START_NOT_STICKY
+ }
+
+ override fun onBind(p0: Intent?): IBinder? {
+ TODO("Not yet implemented")
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ _startForeground()
+ }
+}
\ No newline at end of file
diff --git a/pretixprint/app/src/main/java/eu/pretix/pretixprint/print/PrintService.kt b/pretixprint/app/src/main/java/eu/pretix/pretixprint/print/PrintService.kt
index 86c96aa7..c8d1231f 100644
--- a/pretixprint/app/src/main/java/eu/pretix/pretixprint/print/PrintService.kt
+++ b/pretixprint/app/src/main/java/eu/pretix/pretixprint/print/PrintService.kt
@@ -10,6 +10,7 @@ import android.os.Build.VERSION.SDK_INT
import android.os.Bundle
import android.os.ResultReceiver
import android.util.Log
+import androidx.annotation.Keep
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.preference.PreferenceManager
@@ -38,6 +39,7 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
}
private fun createNotificationChannel() {
+ Log.i("PrintService", "createNotificationChannel()")
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -52,6 +54,7 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
}
private fun startForegroundNotification() {
+ Log.i("PrintService", "startForegroundNotification()")
createNotificationChannel()
val notificationIntent = Intent(this, SettingsActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
@@ -61,10 +64,12 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_stat_print)
.build()
+ Log.i("PrintService", "startForeground()")
startForeground(ONGOING_NOTIFICATION_ID, notification)
}
private fun logException(e: Throwable) {
+ Log.i("PrintService", "logException()")
try {
val log = File.createTempFile("error_", ".log", this.cacheDir)
val fw = FileWriter(log)
@@ -79,6 +84,7 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
}
private fun print(intent: Intent, rr: ResultReceiver?) {
+ Log.i("PrintService", "print()")
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
val type = getType(intent.action!!)
@@ -296,7 +302,12 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
}
}
+ override fun onCreate() {
+ super.onCreate()
+ }
+
override fun onHandleIntent(intent: Intent?) {
+ Log.i("PrintService", "onHandleIntent()")
var rr: ResultReceiver? = null
if (intent!!.hasExtra("resultreceiver")) {
rr = intent.getParcelableExtra("resultreceiver")!! as ResultReceiver
@@ -305,6 +316,7 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
startForegroundNotification()
if (intent.action == ACTION_STOP_SERVICE) {
+ Log.i("PrintService", "stopForeground()")
stopForeground(true)
stopSelf()
return
@@ -336,6 +348,11 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
val type = getType(intent.action!!)
val connection = prefs.getString("hardware_${type}printer_connection", "network_printer")
+
+ if (prefs.getBoolean("keepalive_service", false)) {
+ KeepaliveService.start(this)
+ }
+
if (connection == "system") {
// stop the foreground service, but keep the notification
if (SDK_INT >= Build.VERSION_CODES.N) {
@@ -344,6 +361,7 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
stopForeground(false)
}
} else {
+ Log.i("PrintService", "stopForeground()")
stopForeground(true)
}
}
diff --git a/pretixprint/app/src/main/java/eu/pretix/pretixprint/ui/Settings.kt b/pretixprint/app/src/main/java/eu/pretix/pretixprint/ui/Settings.kt
index fe664eae..2fcebc81 100644
--- a/pretixprint/app/src/main/java/eu/pretix/pretixprint/ui/Settings.kt
+++ b/pretixprint/app/src/main/java/eu/pretix/pretixprint/ui/Settings.kt
@@ -35,6 +35,7 @@ import eu.pretix.pretixprint.R
import eu.pretix.pretixprint.connections.IMinInternalConnection
import eu.pretix.pretixprint.connections.SunmiInternalConnection
import eu.pretix.pretixprint.connections.SystemConnection
+import eu.pretix.pretixprint.print.KeepaliveService
import eu.pretix.pretixprint.print.testPrint
import io.sentry.Sentry
import kotlinx.coroutines.CoroutineScope
@@ -371,6 +372,14 @@ class SettingsActivity : AppCompatActivity() {
.beginTransaction()
.replace(R.id.content, SettingsFragment())
.commit()
+
+ if (prefs.getBoolean("keepalive_service", false)) {
+ try {
+ KeepaliveService.start(this)
+ } catch (e: IllegalStateException) {
+ e.printStackTrace()
+ }
+ }
}
override fun onRequestPermissionsResult(
diff --git a/pretixprint/app/src/main/res/values/strings.xml b/pretixprint/app/src/main/res/values/strings.xml
index 9731d2ea..2fd2d9b2 100644
--- a/pretixprint/app/src/main/res/values/strings.xml
+++ b/pretixprint/app/src/main/res/values/strings.xml
@@ -19,6 +19,11 @@
Driver
Security
Close
+ Service is running
+ Shows a notification when the service is running
+ pretixPRINT is running
+ Run keepalive service
+ Workaround to avoid the app being killed on low-powered devices.
Print jobs
Shows a notification during a print job
Print prepared. Touch to open print dialog
diff --git a/pretixprint/app/src/main/res/xml/preferences.xml b/pretixprint/app/src/main/res/xml/preferences.xml
index 27a89482..c1b31059 100644
--- a/pretixprint/app/src/main/res/xml/preferences.xml
+++ b/pretixprint/app/src/main/res/xml/preferences.xml
@@ -52,6 +52,11 @@
android:key="pref_pin"
android:title="@string/pin_protection_pin"
android:summary="@string/pin_protection_description" />
+