diff --git a/android/app/src/main/java/org/musicpd/Loader.java b/android/app/src/main/java/org/musicpd/Loader.java
deleted file mode 100644
index 21501e67b..000000000
--- a/android/app/src/main/java/org/musicpd/Loader.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-// Copyright The Music Player Daemon Project
-
-package org.musicpd;
-
-import android.util.Log;
-
-public class Loader {
-	private static final String TAG = "MPD";
-
-	public static boolean loaded = false;
-	public static String error;
-
-	static {
-		try {
-			System.loadLibrary("mpd");
-			loaded = true;
-		} catch (UnsatisfiedLinkError e) {
-			Log.e(TAG, e.getMessage());
-			error = e.getMessage();
-		}
-	}
-}
diff --git a/android/app/src/main/java/org/musicpd/Loader.kt b/android/app/src/main/java/org/musicpd/Loader.kt
new file mode 100644
index 000000000..2d89d435c
--- /dev/null
+++ b/android/app/src/main/java/org/musicpd/Loader.kt
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright The Music Player Daemon Project
+package org.musicpd
+
+import android.content.Context
+import android.os.Build
+import android.util.Log
+
+object Loader {
+    private const val TAG = "Loader"
+
+    private var loaded: Boolean = false
+    private var error: String? = null
+    private val failReason: String get() = error ?: ""
+
+    val isLoaded: Boolean get() = loaded
+
+    init {
+        load()
+    }
+
+    private fun load() {
+        if (loaded) return
+        loaded = try {
+            error = null
+            System.loadLibrary("mpd")
+            Log.i(TAG, "mpd lib loaded")
+            true
+        } catch (e: Throwable) {
+            error = e.message ?: e.javaClass.simpleName
+            Log.e(TAG, "failed to load mpd lib: $failReason")
+            false
+        }
+    }
+
+    fun loadFailureMessage(context: Context): String {
+        return context.getString(
+            R.string.mpd_load_failure_message,
+            Build.SUPPORTED_ABIS.joinToString(),
+            Build.PRODUCT,
+            Build.FINGERPRINT,
+            failReason
+        )
+    }
+}
diff --git a/android/app/src/main/java/org/musicpd/Main.kt b/android/app/src/main/java/org/musicpd/Main.kt
index e2fcac4f5..b7037feb9 100644
--- a/android/app/src/main/java/org/musicpd/Main.kt
+++ b/android/app/src/main/java/org/musicpd/Main.kt
@@ -59,6 +59,9 @@ class Main : Service(), Runnable {
         }
     }
 
+    private lateinit var mpdApp: MPDApplication
+    private lateinit var mpdLoader: Loader
+
     private var mThread: Thread? = null
     private var mStatus = MAIN_STATUS_STOPPED
     private var mAbort = false
@@ -104,6 +107,11 @@ class Main : Service(), Runnable {
         }
     }
 
+    override fun onCreate() {
+        super.onCreate()
+        mpdLoader = Loader
+    }
+
     @Synchronized
     private fun sendMessage(
         @Suppress("SameParameterValue") what: Int,
@@ -152,19 +160,6 @@ class Main : Service(), Runnable {
     }
 
     override fun run() {
-        if (!Loader.loaded) {
-            val error = """
-                Failed to load the native MPD library.
-                Report this problem to us, and include the following information:
-                SUPPORTED_ABIS=${java.lang.String.join(", ", *Build.SUPPORTED_ABIS)}
-                PRODUCT=${Build.PRODUCT}
-                FINGERPRINT=${Build.FINGERPRINT}
-                error=${Loader.error}
-                """.trimIndent()
-            setStatus(MAIN_STATUS_ERROR, error)
-            stopSelf()
-            return
-        }
         synchronized(this) {
             if (mAbort) return
             setStatus(MAIN_STATUS_STARTED, null)
@@ -245,7 +240,9 @@ class Main : Service(), Runnable {
                 .setContentIntent(contentIntent)
                 .build()
 
-        mThread = Thread(this).apply { start() }
+        if (mpdLoader.isLoaded) {
+            mThread = Thread(this).apply { start() }
+        }
 
         val player = MPDPlayer(Looper.getMainLooper())
         mMediaSession = MediaSession.Builder(this, player).build()
diff --git a/android/app/src/main/java/org/musicpd/ui/SettingsViewModel.kt b/android/app/src/main/java/org/musicpd/ui/SettingsViewModel.kt
index 62929ee4f..c6f06ef3d 100644
--- a/android/app/src/main/java/org/musicpd/ui/SettingsViewModel.kt
+++ b/android/app/src/main/java/org/musicpd/ui/SettingsViewModel.kt
@@ -6,6 +6,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import org.musicpd.Loader
 import org.musicpd.MainServiceClient
 import org.musicpd.Preferences
 import org.musicpd.data.LoggingRepository
@@ -17,6 +18,7 @@ class SettingsViewModel @Inject constructor(
     private var loggingRepository: LoggingRepository
 ) : ViewModel() {
     private var mClient: MainServiceClient? = null
+    val mpdLoader = Loader
 
     data class StatusUiState(
         val statusMessage: String = "",
diff --git a/android/app/src/main/java/org/musicpd/ui/StatusScreen.kt b/android/app/src/main/java/org/musicpd/ui/StatusScreen.kt
index b913c57b5..cbd56a4df 100644
--- a/android/app/src/main/java/org/musicpd/ui/StatusScreen.kt
+++ b/android/app/src/main/java/org/musicpd/ui/StatusScreen.kt
@@ -1,13 +1,18 @@
 package org.musicpd.ui
 
 import android.Manifest
+import android.content.Context
 import android.os.Build
+import android.util.TypedValue
+import androidx.annotation.AttrRes
+import androidx.annotation.ColorInt
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.selection.SelectionContainer
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Circle
 import androidx.compose.material3.Button
@@ -20,6 +25,7 @@ import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
@@ -53,13 +59,24 @@ fun StatusScreen(settingsViewModel: SettingsViewModel) {
         verticalArrangement = Arrangement.Center
     ) {
         NetworkAddress()
-        ServerStatus(settingsViewModel)
+        ServerStatus(settingsViewModel, storagePermissionState)
         AudioMediaPermission(storagePermissionState)
+        MPDLoaderStatus(settingsViewModel)
     }
 }
 
+@ColorInt
+fun getThemeColorAttribute(context: Context, @AttrRes attr: Int): Int {
+    val value = TypedValue()
+    if (context.theme.resolveAttribute(attr, value, true)) {
+        return value.data
+    }
+    return android.graphics.Color.BLACK
+}
+
+@OptIn(ExperimentalPermissionsApi::class)
 @Composable
-fun ServerStatus(settingsViewModel: SettingsViewModel) {
+fun ServerStatus(settingsViewModel: SettingsViewModel, storagePermissionState: PermissionState) {
     val context = LocalContext.current
 
     val statusUiState by settingsViewModel.statusUIState.collectAsState()
@@ -72,21 +89,35 @@ fun ServerStatus(settingsViewModel: SettingsViewModel) {
             verticalAlignment = Alignment.CenterVertically,
             horizontalArrangement = Arrangement.SpaceEvenly
         ) {
-            Row {
+            Row(verticalAlignment = Alignment.CenterVertically) {
                 Icon(
                     imageVector = Icons.Default.Circle,
                     contentDescription = "",
-                    tint = if (statusUiState.running) Color(0xFFB8F397) else Color(0xFFFFDAD6)
+                    tint = Color(
+                        getThemeColorAttribute(
+                            context,
+                            if (statusUiState.running) R.attr.appColorPositive else R.attr.appColorNegative
+                        )
+                    ),
+                    modifier = Modifier
+                        .padding(end = 8.dp)
+                        .alpha(0.6f)
                 )
-                Text(text = if (statusUiState.running) "Running" else "Stopped")
+                Text(text = stringResource(id = if (statusUiState.running) R.string.running else R.string.stopped))
             }
-            Button(onClick = {
-                if (statusUiState.running)
-                    settingsViewModel.stopMPD()
-                else
-                    settingsViewModel.startMPD(context)
-            }) {
-                Text(text = if (statusUiState.running) "Stop MPD" else "Start MPD")
+            Button(
+                onClick = {
+                    if (statusUiState.running)
+                        settingsViewModel.stopMPD()
+                    else
+                        settingsViewModel.startMPD(context)
+                },
+                enabled = settingsViewModel.mpdLoader.isLoaded
+                        && storagePermissionState.status.isGranted
+            ) {
+                Text(
+                    text = stringResource(id = if (statusUiState.running) R.string.stopMPD else R.string.startMPD)
+                )
             }
         }
         Row(
@@ -139,4 +170,19 @@ fun AudioMediaPermission(storagePermissionState: PermissionState) {
             }
         }
     }
+}
+
+@Composable
+fun MPDLoaderStatus(settingsViewModel: SettingsViewModel) {
+    val loader = settingsViewModel.mpdLoader
+    if (!loader.isLoaded) {
+        val context = LocalContext.current
+        SelectionContainer {
+            Text(
+                loader.loadFailureMessage(context),
+                Modifier.padding(16.dp),
+                color = MaterialTheme.colorScheme.error
+            )
+        }
+    }
 }
\ No newline at end of file
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 32877eb03..6c47fa042 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -1,14 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <resources>
-  <string name="app_name">MPD</string>
-  <string name="notification_title_mpd_running">Music Player Daemon is running</string>
-  <string name="notification_text_mpd_running">Touch for MPD options.</string>
-  <string name="toggle_button_run_on">MPD is running</string>
-  <string name="toggle_button_run_off">MPD is not running</string>
-  <string name="checkbox_run_on_boot">Run MPD automatically on boot</string>
-  <string name="checkbox_wakelock">Prevent suspend when MPD is running (Wakelock)</string>
-  <string name="checkbox_pause_on_headphones_disconnect">Pause MPD when headphones disconnect</string>
-  <string name="external_files_permission_request">MPD requires access to external files to play local music. Please grant the permission.</string>
-  <string name="title_open_app_info">Open app info</string>
+    <string name="app_name">MPD</string>
+    <string name="notification_title_mpd_running">Music Player Daemon is running</string>
+    <string name="notification_text_mpd_running">Touch for MPD options.</string>
+    <string name="toggle_button_run_on">MPD is running</string>
+    <string name="toggle_button_run_off">MPD is not running</string>
+    <string name="checkbox_run_on_boot">Run MPD automatically on boot</string>
+    <string name="checkbox_wakelock">Prevent suspend when MPD is running (Wakelock)</string>
+    <string name="checkbox_pause_on_headphones_disconnect">Pause MPD when headphones disconnect</string>
+    <string name="external_files_permission_request">MPD requires access to external files to play local music. Please grant the permission.</string>
+    <string name="title_open_app_info">Open app info</string>
+    <string name="mpd_load_failure_message">"Failed to load the native MPD library.
+Report this problem to us, and include the following information:
+SUPPORTED_ABIS=%1$s
+PRODUCT=%2$s
+FINGERPRINT=%3$s
+error=%4$s"
+  </string>
+    <string name="stopped">Stopped</string>
+    <string name="running">Running</string>
+    <string name="stopMPD">Stop MPD</string>
+    <string name="startMPD">Start MPD</string>
 </resources>
diff --git a/android/app/src/main/res/values/themes.xml b/android/app/src/main/res/values/themes.xml
index c9502c8f8..d53aa8c45 100644
--- a/android/app/src/main/res/values/themes.xml
+++ b/android/app/src/main/res/values/themes.xml
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <style name="Theme.MPD" parent="android:Theme.Material.Light.NoActionBar" />
+    <color name="red_500">#F44336</color>
+    <color name="red_900">#B71C1C</color>
+    <color name="green_300">#81C784</color>
+    <color name="green_700">#388E3C</color>
+
+    <color name="colorErrorOnLight">@color/red_900</color>
+    <color name="colorErrorOnDark">@color/red_500</color>
+
+    <color name="colorSuccessOnLight">@color/green_700</color>
+    <color name="colorSuccessOnDark">@color/green_300</color>
+
+    <attr name="appColorNegative" format="color|reference" />
+    <attr name="appColorPositive" format="color|reference" />
+
+    <style name="Theme.MPD" parent="android:Theme.Material.Light.NoActionBar">
+        <item name="appColorNegative">@color/colorErrorOnLight</item>
+        <item name="appColorPositive">@color/colorSuccessOnLight</item>
+    </style>
 </resources>
\ No newline at end of file