Refactor code structure for improved readability and maintainability
This commit is contained in:
2
cinny
2
cinny
Submodule cinny updated: 3efc68e893...d226b1810a
@@ -8,6 +8,8 @@
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
|
||||
|
||||
<!-- AndroidTV support -->
|
||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package wtf.ruv.paarrot
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
|
||||
@@ -7,5 +9,17 @@ class MainActivity : TauriActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// Start the foreground sync service to keep the app alive for notifications
|
||||
startSyncService()
|
||||
}
|
||||
|
||||
private fun startSyncService() {
|
||||
val serviceIntent = Intent(this, SyncService::class.java)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(serviceIntent)
|
||||
} else {
|
||||
startService(serviceIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package wtf.ruv.paarrot
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
@@ -7,8 +8,11 @@ import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.os.Looper
|
||||
import android.os.PowerManager
|
||||
import android.os.SystemClock
|
||||
import androidx.core.app.NotificationCompat
|
||||
|
||||
/**
|
||||
@@ -21,9 +25,19 @@ class SyncService : Service() {
|
||||
private const val CHANNEL_ID = "paarrot_sync_channel"
|
||||
private const val CHANNEL_NAME = "Background Sync"
|
||||
private const val WAKE_LOCK_TAG = "Paarrot:SyncWakeLock"
|
||||
private const val ALARM_REQUEST_CODE = 1001
|
||||
private const val KEEP_ALIVE_INTERVAL_MS = 5 * 60 * 1000L // 5 minutes
|
||||
}
|
||||
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val keepAliveRunnable = object : Runnable {
|
||||
override fun run() {
|
||||
// Re-acquire wake lock periodically to prevent it from being released
|
||||
ensureWakeLock()
|
||||
handler.postDelayed(this, KEEP_ALIVE_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? = null
|
||||
|
||||
@@ -31,18 +45,35 @@ class SyncService : Service() {
|
||||
super.onCreate()
|
||||
createNotificationChannel()
|
||||
acquireWakeLock()
|
||||
scheduleKeepAlive()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
startForeground(NOTIFICATION_ID, createNotification())
|
||||
ensureWakeLock()
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
handler.removeCallbacks(keepAliveRunnable)
|
||||
cancelAlarm()
|
||||
releaseWakeLock()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||
// Restart service if app is swiped away
|
||||
val restartServiceIntent = Intent(applicationContext, SyncService::class.java)
|
||||
restartServiceIntent.setPackage(packageName)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(restartServiceIntent)
|
||||
} else {
|
||||
startService(restartServiceIntent)
|
||||
}
|
||||
super.onTaskRemoved(rootIntent)
|
||||
}
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel(
|
||||
@@ -69,7 +100,7 @@ class SyncService : Service() {
|
||||
|
||||
return NotificationCompat.Builder(this, CHANNEL_ID)
|
||||
.setContentTitle("Paarrot")
|
||||
.setContentText("Syncing messages...")
|
||||
.setContentText("Connected to Matrix")
|
||||
.setSmallIcon(android.R.drawable.ic_dialog_info)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
@@ -77,16 +108,64 @@ class SyncService : Service() {
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun scheduleKeepAlive() {
|
||||
// Use handler for periodic wake lock refresh
|
||||
handler.postDelayed(keepAliveRunnable, KEEP_ALIVE_INTERVAL_MS)
|
||||
|
||||
// Also set up alarm as backup
|
||||
scheduleAlarm()
|
||||
}
|
||||
|
||||
private fun scheduleAlarm() {
|
||||
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val intent = Intent(this, SyncService::class.java)
|
||||
val pendingIntent = PendingIntent.getService(
|
||||
this,
|
||||
ALARM_REQUEST_CODE,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
// Schedule inexact repeating alarm to restart service periodically
|
||||
alarmManager.setInexactRepeating(
|
||||
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
SystemClock.elapsedRealtime() + KEEP_ALIVE_INTERVAL_MS,
|
||||
KEEP_ALIVE_INTERVAL_MS,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
|
||||
private fun cancelAlarm() {
|
||||
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val intent = Intent(this, SyncService::class.java)
|
||||
val pendingIntent = PendingIntent.getService(
|
||||
this,
|
||||
ALARM_REQUEST_CODE,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
alarmManager.cancel(pendingIntent)
|
||||
}
|
||||
|
||||
private fun acquireWakeLock() {
|
||||
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
wakeLock = powerManager.newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK,
|
||||
WAKE_LOCK_TAG
|
||||
).apply {
|
||||
acquire(10 * 60 * 1000L) // 10 minutes timeout
|
||||
// Acquire indefinitely - the service manages its own lifecycle
|
||||
acquire()
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureWakeLock() {
|
||||
wakeLock?.let {
|
||||
if (!it.isHeld) {
|
||||
it.acquire()
|
||||
}
|
||||
} ?: acquireWakeLock()
|
||||
}
|
||||
|
||||
private fun releaseWakeLock() {
|
||||
wakeLock?.let {
|
||||
if (it.isHeld) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user