I am searching for broadcast receivers which will be fired when one of those permissions has changed:
- Battery optimization
- Coarse & Fine Location
- Post Notifications
- Read Phone State
- Background Location
- Pause app activity when unused
- Nearby wifi devices
I just ask for the code of what to register and what to unregister.
The receivers may run in an activity or in a service.
Code from chatgpt that didn't work 100%:
@file:Suppress("DEPRECATION")
package com.mobeetest.worker.utilities.permissions
import android.app.AppOpsManager
import android.content.*
import android.location.LocationManager
import android.util.Log
class RuntimePermissionWatcher(
private val context: Context,
// ΝΕΟ: predicate που μας λέει αν ΠΡΕΠΕΙ να “ακούμε” ένα permission τώρα
private val shouldWatch: (String) -> Boolean,
private val onMaybeChanged: (String) -> Unit
) {
private val tag = "RuntimePermissionWatcher"
private val appOps = context.getSystemService(AppOpsManager::class.java)
// helper για map από AppOp -> permission name που χρησιμοποιείς στα steps
private fun opToPermissionName(op: String?): String? = when (op) {
AppOpsManager.OPSTR_FINE_LOCATION,
AppOpsManager.OPSTR_COARSE_LOCATION -> "Location"
AppOpsManager.OPSTR_READ_PHONE_STATE -> "Phone"
// Αν θες να ακούς και notifications μέσω AppOps (όπου υποστηρίζεται):
// AppOpsManager.OPSTR_POST_NOTIFICATION -> "Notifications"
else -> null
}
private val opChangedListener = AppOpsManager.OnOpChangedListener { op, pkg ->
// φιλτράρουμε by pkg και by permission status
if (pkg != context.packageName) return@OnOpChangedListener
val name = opToPermissionName(op) ?: return@OnOpChangedListener
if (!shouldWatch(name)) return@OnOpChangedListener
onMaybeChanged(name)
}
private val locationReceiver = object : BroadcastReceiver() {
override fun onReceive(ctx: Context?, intent: Intent?) {
// Events: MODE_CHANGED / PROVIDERS_CHANGED -> αφορούν Location
if (!shouldWatch("Location")) return
onMaybeChanged("Location")
}
}
private val powerReceiver = object : BroadcastReceiver() {
override fun onReceive(ctx: Context?, intent: Intent?) {
// Δεν σου λέει whitelist per-app, αλλά είναι καλό hint για recheck.
if (!shouldWatch("Battery")) return
onMaybeChanged("Battery")
}
}
private val powerFilter = IntentFilter().apply {
addAction(android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
addAction(android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)
}
private val locationFilter = IntentFilter().apply {
addAction(LocationManager.MODE_CHANGED_ACTION)
addAction(LocationManager.PROVIDERS_CHANGED_ACTION)
}
fun start() {
try {
context.registerReceiver(powerReceiver, powerFilter)
appOps.startWatchingMode(
AppOpsManager.OPSTR_FINE_LOCATION, context.packageName, opChangedListener
)
appOps.startWatchingMode(
AppOpsManager.OPSTR_COARSE_LOCATION, context.packageName, opChangedListener
)
appOps.startWatchingMode(
AppOpsManager.OPSTR_READ_PHONE_STATE, context.packageName, opChangedListener
)
// Προαιρετικά, αν θέλεις και Notifications όπου υποστηρίζεται από OEM/SDK:
// appOps.startWatchingMode(
// AppOpsManager.OPSTR_POST_NOTIFICATION, context.packageName, opChangedListener
// )
} catch (t: Throwable) {
Log.w(tag, "startWatchingMode failed: ${t.message}")
}
context.registerReceiver(locationReceiver, locationFilter)
}
fun stop() {
runCatching { appOps.stopWatchingMode(opChangedListener) }
runCatching { context.unregisterReceiver(locationReceiver) }
runCatching { context.unregisterReceiver(powerReceiver) }
}
}