Fix android system bars overlapping UI #1564 #1574

This commit is contained in:
advplyr 2025-05-21 17:26:31 -05:00
parent 1357a0628f
commit 1cf36e5549
8 changed files with 71 additions and 20 deletions

View file

@ -5,6 +5,10 @@
"plugins": { "plugins": {
"CapacitorHttp": { "CapacitorHttp": {
"enabled": false "enabled": false
},
"StatusBar": {
"backgroundColor": "#232323",
"style": "DARK"
} }
}, },
"server": { "server": {

View file

@ -6,10 +6,15 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.ViewGroup
import android.view.WindowInsets
import android.webkit.WebView
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.view.updateLayoutParams
import com.anggrayudi.storage.SimpleStorage import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.SimpleStorageHelper import com.anggrayudi.storage.SimpleStorageHelper
import com.audiobookshelf.app.managers.DbManager import com.audiobookshelf.app.managers.DbManager
@ -40,18 +45,6 @@ class MainActivity : BridgeActivity() {
) )
public override fun onCreate(savedInstanceState: Bundle?) { public override fun onCreate(savedInstanceState: Bundle?) {
// TODO: Optimize using strict mode logs
// StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
// .detectDiskReads()
// .detectDiskWrites().detectAll()
// .detectNetwork() // or .detectAll() for all detectable problems
// .penaltyLog()
// .build())
// StrictMode.setVmPolicy(VmPolicy.Builder()
// .detectLeakedSqlLiteObjects()
// .detectLeakedClosableObjects()
// .penaltyLog()
// .build())
DbManager.initialize(applicationContext) DbManager.initialize(applicationContext)
registerPlugin(AbsAudioPlayer::class.java) registerPlugin(AbsAudioPlayer::class.java)
@ -63,7 +56,47 @@ class MainActivity : BridgeActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Log.d(tag, "onCreate") Log.d(tag, "onCreate")
// Update the margins to handle edge-to-edge enforced in SDK 35
// See: https://developer.android.com/develop/ui/views/layout/edge-to-edge
val webView: WebView = findViewById(R.id.webview)
webView.setOnApplyWindowInsetsListener { v, insets ->
val (left, top, right, bottom) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val sysInsets = insets.getInsets(WindowInsets.Type.systemBars())
Log.d(tag, "safe sysInsets: $sysInsets")
arrayOf(sysInsets.left, sysInsets.top, sysInsets.right, sysInsets.bottom)
} else {
arrayOf(
insets.systemWindowInsetLeft,
insets.systemWindowInsetTop,
insets.systemWindowInsetRight,
insets.systemWindowInsetBottom
)
}
// Inject as CSS variables
// NOTE: Possibly able to use in the future to support edge-to-edge better.
val js = """
document.documentElement.style.setProperty('--safe-area-inset-top', '${top}px');
document.documentElement.style.setProperty('--safe-area-inset-bottom', '${bottom}px');
document.documentElement.style.setProperty('--safe-area-inset-left', '${left}px');
document.documentElement.style.setProperty('--safe-area-inset-right', '${right}px');
""".trimIndent()
webView.evaluateJavascript(js, null)
// Set margins
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = left
bottomMargin = bottom
rightMargin = right
topMargin = top
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowInsets.CONSUMED
} else {
insets
}
}
val permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) val permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
if (permission != PackageManager.PERMISSION_GRANTED) { if (permission != PackageManager.PERMISSION_GRANTED) {

View file

@ -7,6 +7,7 @@
tools:context=".MainActivity"> tools:context=".MainActivity">
<WebView <WebView
android:id="@+id/webview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:background">@color/background_dark</item>
<item name="android:statusBarColor">@color/background_dark</item>
<item name="android:navigationBarColor">@color/background_dark</item>
</style>
</resources>

View file

@ -3,5 +3,5 @@
<color name="light_blue_200">#FF81D4FA</color> <color name="light_blue_200">#FF81D4FA</color>
<color name="light_blue_600">#FF039BE5</color> <color name="light_blue_600">#FF039BE5</color>
<color name="light_blue_900">#FF01579B</color> <color name="light_blue_900">#FF01579B</color>
<color name="background_dark">#262626</color> <color name="background_dark">#232323</color>
</resources> </resources>

View file

@ -5,6 +5,10 @@
"plugins": { "plugins": {
"CapacitorHttp": { "CapacitorHttp": {
"enabled": false "enabled": false
},
"StatusBar": {
"backgroundColor": "#232323",
"style": "DARK"
} }
}, },
"server": { "server": {

View file

@ -5,6 +5,10 @@
"plugins": { "plugins": {
"CapacitorHttp": { "CapacitorHttp": {
"enabled": false "enabled": false
},
"StatusBar": {
"backgroundColor": "#232323",
"style": "DARK"
} }
}, },
"server": { "server": {

View file

@ -16,12 +16,6 @@ if (Capacitor.getPlatform() != 'web') {
await StatusBar.setStyle({ style: Style.Dark }) await StatusBar.setStyle({ style: Style.Dark })
} }
setStatusBarStyleDark() setStatusBarStyleDark()
const setStatusBarOverlays = async () => {
// Defaults to true in capacitor v7
await StatusBar.setOverlaysWebView({ overlay: false })
}
setStatusBarOverlays()
} }
Vue.prototype.$showHideStatusBar = async (show) => { Vue.prototype.$showHideStatusBar = async (show) => {