Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pretixprint/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@
<action android:name="eu.pretix.pretixpos.print.PRINT_RECEIPT" />
</intent-filter>
</service>
<service
android:name=".print.KeepaliveService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="connectedDevice">
</service>

<meta-data android:name="io.sentry.dsn" android:value="${SENTRY_DSN}" />
<meta-data android:name="io.sentry.auto-session-tracking.enable" android:value="false" />
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -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,
Expand All @@ -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)
Expand All @@ -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!!)

Expand Down Expand Up @@ -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>("resultreceiver")!! as ResultReceiver
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -344,6 +361,7 @@ abstract class AbstractPrintService(name: String) : IntentService(name) {
stopForeground(false)
}
} else {
Log.i("PrintService", "stopForeground()")
stopForeground(true)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
5 changes: 5 additions & 0 deletions pretixprint/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
<string name="settings_label_driver">Driver</string>
<string name="settings_label_security">Security</string>
<string name="dismiss">Close</string>
<string name="notification_channel_keepalive">Service is running</string>
<string name="notification_channel_keepalive_description">Shows a notification when the service is running</string>
<string name="keepalive_notification">pretixPRINT is running</string>
<string name="keepalive_service">Run keepalive service</string>
<string name="keepalive_service_description">Workaround to avoid the app being killed on low-powered devices.</string>
<string name="notification_channel_print">Print jobs</string>
<string name="notification_channel_print_description">Shows a notification during a print job</string>
<string name="print_now_notification">Print prepared. Touch to open print dialog</string>
Expand Down
5 changes: 5 additions & 0 deletions pretixprint/app/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@
android:key="pref_pin"
android:title="@string/pin_protection_pin"
android:summary="@string/pin_protection_description" />
<CheckBoxPreference
android:defaultValue="false"
android:key="keepalive_service"
android:title="@string/keepalive_service"
android:summary="@string/keepalive_service_description" />
</PreferenceCategory>

<PreferenceCategory android:title="@string/settings_label_about">
Expand Down