ref #6: Add broadcast receiver that hides powerbar

This commit is contained in:
Tim Kluge 2024-12-10 21:29:41 +01:00
parent 2cf5ce70d6
commit f2c7c59bb7
5 changed files with 58 additions and 8 deletions

View File

@ -36,7 +36,13 @@ extensions like this. Until it is available, you can sideload the app.
## Credits ## Credits
- Icons by [boxicons.com](https://boxicons.com) (MIT-licensed). - Icons by [boxicons.com](https://boxicons.com) (MIT-licensed).
- Based on [karoo-ext](https://github.com/hammerheadnav/karoo-ext) (Apache 2.0-licensed).
## Links ## Hide powerbar from other apps
[karoo-ext source](https://github.com/hammerheadnav/karoo-ext) If you want to temporarily hide the powerbar from other apps when you show something on the screen
that would be hidden by the bar overlay, you can send a `de.timklge.HIDE_POWERBAR` broadcast intent to the app.
Optionally, include the following extras:
- `duration` (long, ms): Duration for which the powerbar should be hidden. If not set, the powerbar will be hidden for 15 seconds.
- `location` (string, `"top"` or `"bottom"`): Location of the powerbar to hide. If not set, the powerbar at the top will be hidden.

View File

@ -13,8 +13,8 @@ android {
applicationId = "de.timklge.karoopowerbar" applicationId = "de.timklge.karoopowerbar"
minSdk = 26 minSdk = 26
targetSdk = 33 targetSdk = 33
versionCode = 5 versionCode = 6
versionName = "1.2.0" versionName = "1.2.1"
} }
buildTypes { buildTypes {

View File

@ -3,8 +3,8 @@
"packageName": "de.timklge.karoopowerbar", "packageName": "de.timklge.karoopowerbar",
"iconUrl": "https://github.com/timklge/karoo-powerbar/releases/latest/download/karoo-powerbar.png", "iconUrl": "https://github.com/timklge/karoo-powerbar/releases/latest/download/karoo-powerbar.png",
"latestApkUrl": "https://github.com/timklge/karoo-powerbar/releases/latest/download/app-release.apk", "latestApkUrl": "https://github.com/timklge/karoo-powerbar/releases/latest/download/app-release.apk",
"latestVersion": "1.2.0", "latestVersion": "1.2.1",
"latestVersionCode": 5, "latestVersionCode": 6,
"developer": "timklge", "developer": "timklge",
"description": "Adds a colored power bar to the bottom of the screen", "description": "Adds a colored power bar to the bottom of the screen",
"releaseNotes": "Add options to add secondary power bar and to hide bar when not riding. Fix manually set up power/hr zones." "releaseNotes": "Add options to add secondary power bar and to hide bar when not riding. Fix manually set up power/hr zones."

View File

@ -10,7 +10,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class KarooPowerbarExtension : KarooExtension("karoo-powerbar", "1.2.0") { class KarooPowerbarExtension : KarooExtension("karoo-powerbar", "1.2.1") {
companion object { companion object {
const val TAG = "karoo-powerbar" const val TAG = "karoo-powerbar"

View File

@ -1,7 +1,11 @@
package de.timklge.karoopowerbar package de.timklge.karoopowerbar
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Context.WINDOW_SERVICE import android.content.Context.WINDOW_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.graphics.PixelFormat import android.graphics.PixelFormat
import android.os.Build import android.os.Build
import android.util.DisplayMetrics import android.util.DisplayMetrics
@ -21,10 +25,10 @@ import io.hammerhead.karooext.models.UserProfile
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -98,8 +102,16 @@ class Window(
private var serviceJob: Job? = null private var serviceJob: Job? = null
@SuppressLint("UnspecifiedRegisterReceiverFlag")
suspend fun open() { suspend fun open() {
serviceJob = CoroutineScope(Dispatchers.Default).launch { serviceJob = CoroutineScope(Dispatchers.Default).launch {
val filter = IntentFilter("de.timklge.HIDE_POWERBAR")
if (Build.VERSION.SDK_INT >= 33) {
context.registerReceiver(hideReceiver, filter, Context.RECEIVER_EXPORTED)
} else {
context.registerReceiver(hideReceiver, filter)
}
karooSystem.connect { connected -> karooSystem.connect { connected ->
Log.i(TAG, "Karoo system service connected: $connected") Log.i(TAG, "Karoo system service connected: $connected")
} }
@ -216,8 +228,15 @@ class Window(
} }
} }
private var currentHideJob: Job? = null
fun close() { fun close() {
try { try {
context.unregisterReceiver(hideReceiver)
if (currentHideJob != null){
currentHideJob?.cancel()
currentHideJob = null
}
serviceJob?.cancel() serviceJob?.cancel()
(context.getSystemService(WINDOW_SERVICE) as WindowManager).removeView(rootView) (context.getSystemService(WINDOW_SERVICE) as WindowManager).removeView(rootView)
rootView.invalidate() rootView.invalidate()
@ -226,4 +245,29 @@ class Window(
Log.d(TAG, e.toString()) Log.d(TAG, e.toString())
} }
} }
private val hideReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (action == "de.timklge.HIDE_POWERBAR") {
val location = when (intent.getStringExtra("location")) {
"top" -> PowerbarLocation.TOP
"bottom" -> PowerbarLocation.BOTTOM
else -> PowerbarLocation.TOP
}
val duration = intent.getLongExtra("duration", 15_000)
Log.d(TAG, "Received broadcast to hide $location powerbar for $duration ms")
currentHideJob?.cancel()
currentHideJob = CoroutineScope(Dispatchers.Main).launch {
rootView.visibility = View.INVISIBLE
withContext(Dispatchers.Default){
delay(duration)
}
rootView.visibility = View.VISIBLE
currentHideJob = null
}
}
}
}
} }