package eu.jopek.dingdongmail import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.app.Service import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.pm.ApplicationInfo import android.content.pm.ServiceInfo import android.graphics.BitmapFactory import android.graphics.Color import android.os.Build import android.os.IBinder import android.os.PowerManager import android.util.Log import android.widget.Toast import eu.jopek.dingdongmail.ui.theme.DingDongMailTheme fun log(str: String) { Log.d("Ding-Dong Mail", str) } enum class Actions { START, STOP } class MainWorkerService : Service() { private var wakeLock: PowerManager.WakeLock? = null private var isServiceStarted = false override fun onBind(intent: Intent): IBinder? { log("Some component want to bind with the service") // We don't provide binding, so return null return null } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { if (intent != null) { val action = intent.action log("using an intent with action $action") when (action) { Actions.START.name -> startService() Actions.STOP.name -> stopService() else -> log("This should never happen. No action in the received intent") } } else { log("with a null intent. It has been probably restarted by the system.") } // by returning this we make sure the service is restarted if the system kills the service return START_STICKY } override fun onCreate() { super.onCreate() log("The service has been created") val notification = createNotification() startForeground(ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE, notification) } override fun onDestroy() { super.onDestroy() log("The service has been destroyed") Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show() } private fun startService() { if (isServiceStarted) return log("Starting the foreground service task") Toast.makeText(this, "Service starting its task", Toast.LENGTH_SHORT).show() isServiceStarted = true // we need this lock so our service gets not affected by Doze Mode // wakeLock = // (getSystemService(Context.POWER_SERVICE) as PowerManager).run { // newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DingDongMail::lock").apply { // acquire() // } // } val i = Intent("eu.faircode.email.DISABLE").apply { setPackage("eu.faircode.email") } startService(i) val intentFilter = IntentFilter("io.heckel.ntfy.MESSAGE_RECEIVED") registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED) } private val receiver: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val msg = intent.getStringExtra("message") ?: return val (email, _mailbox) = msg.split(":", ignoreCase = false, limit = 2) // log("email: $email") val i = Intent("eu.faircode.email.POLL").apply { setPackage("eu.faircode.email") putExtra("account", email) } startService(i) } } private fun stopService() { log("Stopping the foreground service") Toast.makeText(this, "Service stopping", Toast.LENGTH_SHORT).show() val i = Intent("eu.faircode.email.ENABLE").apply { setPackage("eu.faircode.email") } startService(i) // wakeLock?.let { // if (it.isHeld) { // it.release() // } // } stopSelf() unregisterReceiver(receiver) isServiceStarted = false } private fun createNotification(): Notification { val notificationChannelId = "DING-DONG MAIL - FOREGROUND SERVICE" val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val channel = NotificationChannel( notificationChannelId, "Foreground service", NotificationManager.IMPORTANCE_MIN ).let { it.description = "Foreground service" it.enableLights(true) it.lightColor = Color.RED it.enableVibration(true) it.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400) it } notificationManager.createNotificationChannel(channel) val pendingIntent: PendingIntent = Intent(this, MainActivity::class.java).let { notificationIntent -> PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE) } val builder: Notification.Builder = Notification.Builder( this, notificationChannelId ) return builder .setContentTitle("Ding-Dong Mail - Foreground Service") .setContentText("This makes Ding-Dong Mail works so good") .setContentIntent(pendingIntent) .setSmallIcon(R.drawable.notification) .setColor(resources.getColor(R.color.notification_bg, theme)) .setLargeIcon( BitmapFactory.decodeResource( applicationContext.resources, R.mipmap.logo ) ) .build() } }