Stop notification listener when all logging is disabled
This commit is contained in:
@@ -5,7 +5,8 @@ import androidx.core.content.edit
|
||||
|
||||
/** Persists rule choices only; notification contents never enter SharedPreferences. */
|
||||
class LoggingRuleStore(context: Context) {
|
||||
private val preferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
|
||||
private val appContext = context.applicationContext
|
||||
private val preferences = appContext.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
|
||||
|
||||
fun ruleFor(type: LoggingType): LoggingRule = LoggingRule(
|
||||
enabled = preferences.getBoolean(key(type, "enabled"), true),
|
||||
@@ -24,6 +25,7 @@ class LoggingRuleStore(context: Context) {
|
||||
preferences.edit {
|
||||
write(type, rule)
|
||||
}
|
||||
updateListenerComponent()
|
||||
}
|
||||
|
||||
fun copy(from: LoggingType, targets: Set<LoggingType>) {
|
||||
@@ -33,6 +35,7 @@ class LoggingRuleStore(context: Context) {
|
||||
write(target, source.copy(selectedPackages = source.selectedPackages.toSet()))
|
||||
}
|
||||
}
|
||||
updateListenerComponent()
|
||||
}
|
||||
|
||||
private fun android.content.SharedPreferences.Editor.write(type: LoggingType, rule: LoggingRule) {
|
||||
@@ -46,6 +49,10 @@ class LoggingRuleStore(context: Context) {
|
||||
|
||||
private fun key(type: LoggingType, suffix: String) = "${type.name.lowercase()}.$suffix"
|
||||
|
||||
private fun updateListenerComponent() {
|
||||
NotificationListenerComponentController.update(appContext, LoggingType.entries.map(::ruleFor))
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val FILE_NAME = "logging-rules"
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package se.ajpanton.notificationlog.settings
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.service.notification.NotificationListenerService
|
||||
import android.util.Log
|
||||
import se.ajpanton.notificationlog.capture.NotificationCaptureService
|
||||
|
||||
/**
|
||||
* Notification listeners are re-bound by Android after boot when their component
|
||||
* is enabled and the user granted notification access. Disabling the component
|
||||
* is therefore both the no-work battery mode and the no-start-on-boot mode.
|
||||
*/
|
||||
internal object NotificationListenerComponentController {
|
||||
fun update(context: Context, rules: Collection<LoggingRule>) {
|
||||
val applicationContext = context.applicationContext
|
||||
val component = ComponentName(applicationContext, NotificationCaptureService::class.java)
|
||||
val packageManager = applicationContext.packageManager
|
||||
val desired = if (NotificationListenerPolicy.shouldRun(rules)) {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
} else {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
||||
}
|
||||
if (packageManager.getComponentEnabledSetting(component) == desired) return
|
||||
packageManager.setComponentEnabledSetting(component, desired, PackageManager.DONT_KILL_APP)
|
||||
if (desired == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
|
||||
try {
|
||||
NotificationListenerService.requestRebind(component)
|
||||
} catch (error: SecurityException) {
|
||||
Log.w(TAG, "Notification access is not granted yet; Android will bind after the user grants it", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val TAG = "NotificationListenerControl"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package se.ajpanton.notificationlog.settings
|
||||
|
||||
/** The listener is useful only when at least one event type is enabled. */
|
||||
object NotificationListenerPolicy {
|
||||
fun shouldRun(rules: Collection<LoggingRule>): Boolean = rules.any { it.enabled }
|
||||
}
|
||||
Reference in New Issue
Block a user