From 8e09050424b908fae4715f7dceb20b0401ee2d78 Mon Sep 17 00:00:00 2001 From: Javad Mnjd Date: Fri, 12 Jul 2024 16:49:56 +0330 Subject: [PATCH] fix: ensure app is correctly working again at startup --- .../java/io/github/jd1378/otphelper/App.kt | 24 +-------- .../github/jd1378/otphelper/BootReceiver.kt | 17 +++++-- .../jd1378/otphelper/NotificationListener.kt | 50 ++++++++++++------- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/io/github/jd1378/otphelper/App.kt b/app/src/main/java/io/github/jd1378/otphelper/App.kt index 0df63838..707d79f7 100644 --- a/app/src/main/java/io/github/jd1378/otphelper/App.kt +++ b/app/src/main/java/io/github/jd1378/otphelper/App.kt @@ -1,12 +1,10 @@ package io.github.jd1378.otphelper import android.app.Application -import android.content.ComponentName -import android.content.pm.PackageManager import androidx.hilt.work.HiltWorkerFactory import androidx.work.Configuration import dagger.hilt.android.HiltAndroidApp -import io.github.jd1378.otphelper.NotificationListener.Companion.isNotificationServiceEnabled +import io.github.jd1378.otphelper.NotificationListener.Companion.tryReEnableNotificationListener import javax.inject.Inject @HiltAndroidApp @@ -19,24 +17,6 @@ class App : Application(), Configuration.Provider { override fun onCreate() { super.onCreate() - if (isNotificationServiceEnabled(applicationContext)) { - // Rebind the service if it's already enabled - val componentName = - ComponentName( - this, - NotificationListener::class.java, - ) - val pm = packageManager - pm.setComponentEnabledSetting( - componentName, - PackageManager.COMPONENT_ENABLED_STATE_DISABLED, - PackageManager.DONT_KILL_APP, - ) - pm.setComponentEnabledSetting( - componentName, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED, - PackageManager.DONT_KILL_APP, - ) - } + tryReEnableNotificationListener(applicationContext) } } diff --git a/app/src/main/java/io/github/jd1378/otphelper/BootReceiver.kt b/app/src/main/java/io/github/jd1378/otphelper/BootReceiver.kt index 30f70f07..a44b53ef 100644 --- a/app/src/main/java/io/github/jd1378/otphelper/BootReceiver.kt +++ b/app/src/main/java/io/github/jd1378/otphelper/BootReceiver.kt @@ -4,15 +4,24 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.os.Build -import androidx.core.app.NotificationManagerCompat +import android.util.Log +import io.github.jd1378.otphelper.NotificationListener.Companion.isNotificationListenerServiceEnabled +import io.github.jd1378.otphelper.NotificationListener.Companion.tryReEnableNotificationListener import io.github.jd1378.otphelper.utils.NotificationHelper class BootReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent?) { if (intent?.action == Intent.ACTION_BOOT_COMPLETED) { - if (NotificationManagerCompat.getEnabledListenerPackages(context) - .contains(context.packageName)) { - context.startService(Intent(context, NotificationListener::class.java)) + if (isNotificationListenerServiceEnabled(context)) { + try { + context.startService(Intent(context, NotificationListener::class.java)) + } catch (e: Throwable) { + Log.e( + "BootReceiver", + "Failed to start NotificationListener", + ) + } + tryReEnableNotificationListener(context) } when (Build.VERSION.SDK_INT) { Build.VERSION_CODES.Q, diff --git a/app/src/main/java/io/github/jd1378/otphelper/NotificationListener.kt b/app/src/main/java/io/github/jd1378/otphelper/NotificationListener.kt index 0c160c9d..d63c12b5 100644 --- a/app/src/main/java/io/github/jd1378/otphelper/NotificationListener.kt +++ b/app/src/main/java/io/github/jd1378/otphelper/NotificationListener.kt @@ -3,11 +3,13 @@ package io.github.jd1378.otphelper import android.app.Notification import android.content.ComponentName import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager import android.os.Build -import android.provider.Settings import android.service.notification.NotificationListenerService import android.service.notification.StatusBarNotification import android.util.Log +import androidx.core.app.NotificationManagerCompat import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import androidx.work.workDataOf @@ -35,25 +37,39 @@ class NotificationListener : NotificationListenerService() { ) val notification_text_arrays_keys = listOf(Notification.EXTRA_TEXT_LINES) - fun isNotificationServiceEnabled(context: Context): Boolean { - val pkgName = context.packageName - val flat = - Settings.Secure.getString(context.contentResolver, "enabled_notification_listeners") - if (!flat.isNullOrEmpty()) { - val names = flat.split(":").toTypedArray() - for (name in names) { - val componentName = ComponentName.unflattenFromString(name) - if (componentName != null) { - if (pkgName == componentName.packageName) { - return true - } - } - } + fun isNotificationListenerServiceEnabled(context: Context): Boolean { + return NotificationManagerCompat.getEnabledListenerPackages(context) + .contains(context.packageName) + } + + fun tryReEnableNotificationListener(context: Context) { + if (isNotificationListenerServiceEnabled(context)) { + // Rebind the service if it's already enabled + val componentName = + ComponentName( + context, + NotificationListener::class.java, + ) + val pm = context.packageManager + pm.setComponentEnabledSetting( + componentName, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP, + ) + pm.setComponentEnabledSetting( + componentName, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP, + ) } - return false } } + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + super.onStartCommand(intent, flags, startId) + return START_STICKY + } + override fun onNotificationPosted(sbn: StatusBarNotification?) { super.onNotificationPosted(sbn) autoUpdatingListenerUtils.awaitCodeExtractor() @@ -142,7 +158,7 @@ class NotificationListener : NotificationListenerService() { // Handle the listener disconnected event Log.i(TAG, "Notification listener disconnected.") - if (isNotificationServiceEnabled(applicationContext)) { + if (isNotificationListenerServiceEnabled(applicationContext)) { Log.d(TAG, "Rebinding to the service") val componentName = ComponentName(