- Оптимизация батареи
- Грубое и точное определение местоположения
- Уведомления о публикациях
- Чтение состояния телефона
- Фоновое местоположение
- Приостанавливать активность приложения, когда оно не используется.
- Устройства Wi-Fi поблизости.
Приемники могут работать в действии или в службе.
Код изchatgpt, который не сработал на 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) }
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... on-runtime
Мобильная версия