Skip to content

Commit 3b8bc5a

Browse files
committed
Fatal Exception: java.lang.RuntimeException: Unable to create service com.ismartcoding.plain.services.HttpServerService: android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false: service com.ismartcoding.plain/.services.HttpServerServic
1 parent 9f1cfc1 commit 3b8bc5a

File tree

6 files changed

+60
-23
lines changed

6 files changed

+60
-23
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
5353
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
5454
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" />-->
55+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
5556

5657
<uses-feature
5758
android:name="android.hardware.microphone"
@@ -152,7 +153,7 @@
152153
<service
153154
android:name=".services.HttpServerService"
154155
android:exported="false"
155-
android:foregroundServiceType="specialUse"
156+
android:foregroundServiceType="specialUse|dataSync"
156157
android:stopWithTask="true">
157158
<property
158159
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"

app/src/main/java/com/ismartcoding/plain/events/AppEvents.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import com.ismartcoding.plain.web.websocket.WebSocketHelper
3030
import io.ktor.server.websocket.DefaultWebSocketServerSession
3131
import kotlinx.coroutines.delay
3232
import kotlinx.coroutines.launch
33+
import androidx.core.content.ContextCompat
3334

3435
// The events raised by the app
3536
class StartHttpServerEvent : ChannelEvent()
@@ -173,7 +174,10 @@ object AppEvents {
173174
while (retry > 0) {
174175
try {
175176
val context = MainApp.instance
176-
context.startService(Intent(context, HttpServerService::class.java))
177+
androidx.core.content.ContextCompat.startForegroundService(
178+
context,
179+
Intent(context, HttpServerService::class.java)
180+
)
177181
break
178182
} catch (ex: Exception) {
179183
LogCat.e(ex.toString())

app/src/main/java/com/ismartcoding/plain/services/HttpServerService.kt

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.ismartcoding.plain.services
22

33
import android.annotation.SuppressLint
4+
import android.content.Intent
45
import android.content.pm.ServiceInfo
56
import androidx.core.app.ServiceCompat
67
import androidx.lifecycle.Lifecycle
@@ -31,18 +32,7 @@ class HttpServerService : LifecycleService() {
3132
override fun onCreate() {
3233
super.onCreate()
3334
NotificationHelper.ensureDefaultChannel()
34-
val notification =
35-
NotificationHelper.createServiceNotification(
36-
this,
37-
"${BuildConfig.APPLICATION_ID}.action.stop_http_server",
38-
getString(R.string.api_service_is_running),
39-
HttpServerManager.getNotificationContent()
40-
)
41-
ServiceCompat.startForeground(
42-
this, HttpServerManager.notificationId,
43-
notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
44-
)
45-
35+
4636
lifecycle.addObserver(object : LifecycleEventObserver {
4737
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
4838
when (event) {
@@ -61,6 +51,51 @@ class HttpServerService : LifecycleService() {
6151
}
6252
})
6353
}
54+
55+
@SuppressLint("InlinedApi")
56+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
57+
super.onStartCommand(intent, flags, startId)
58+
59+
try {
60+
NotificationHelper.ensureDefaultChannel()
61+
62+
val notification = NotificationHelper.createServiceNotification(
63+
this,
64+
"${BuildConfig.APPLICATION_ID}.action.stop_http_server",
65+
getString(R.string.api_service_is_running),
66+
HttpServerManager.getNotificationContent()
67+
)
68+
69+
try {
70+
ServiceCompat.startForeground(
71+
this,
72+
HttpServerManager.notificationId,
73+
notification,
74+
ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
75+
)
76+
} catch (e: Exception) {
77+
LogCat.e("Error starting foreground service with specialUse: ${e.message}")
78+
try {
79+
ServiceCompat.startForeground(
80+
this,
81+
HttpServerManager.notificationId,
82+
notification,
83+
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
84+
)
85+
} catch (e2: Exception) {
86+
LogCat.e("Error starting foreground service with dataSync: ${e2.message}")
87+
startForeground(HttpServerManager.notificationId, notification)
88+
}
89+
}
90+
} catch (e: Exception) {
91+
LogCat.e("Failed to start foreground service: ${e.message}")
92+
e.printStackTrace()
93+
stopSelf()
94+
return START_NOT_STICKY
95+
}
96+
97+
return START_STICKY
98+
}
6499

65100
private suspend fun startHttpServerAsync() {
66101
LogCat.d("startHttpServer")

app/src/main/java/com/ismartcoding/plain/ui/nav/NavHostController.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ fun NavHostController.navigatePdf(uri: Uri) {
3737
}
3838
}
3939

40-
4140
fun NavHostController.navigateOtherFile(path: String) {
42-
currentBackStackEntry?.savedStateHandle?.set("path", path)
43-
navigate(Routing.OtherFile) {
41+
navigate(Routing.OtherFile(path)) {
4442
launchSingleTop = true
4543
}
4644
}

app/src/main/java/com/ismartcoding/plain/ui/nav/Routing.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Routing {
6464
object Apps
6565

6666
@Serializable
67-
object OtherFile
67+
data class OtherFile(val path: String)
6868

6969
@Serializable
7070
object Docs

app/src/main/java/com/ismartcoding/plain/ui/page/Main.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ fun Main(
132132
LaunchedEffect(Unit) {
133133
onLaunched()
134134
}
135-
136135
LaunchedEffect(sharedFlow) {
137136
sharedFlow.collect { event ->
138137
when (event) {
@@ -286,13 +285,13 @@ fun Main(
286285
ChatEditTextPage(navController, r.id, content, chatVM)
287286
}
288287

289-
composable<Routing.OtherFile> {
290-
val path = navController.previousBackStackEntry?.savedStateHandle?.get("path") ?: ""
291-
OtherFilePage(navController, path)
288+
composable<Routing.OtherFile> { backStackEntry ->
289+
val r = backStackEntry.toRoute<Routing.OtherFile>()
290+
OtherFilePage(navController, r.path)
292291
}
293292

294293
composable<Routing.PdfViewer> {
295-
val uri = navController.previousBackStackEntry?.savedStateHandle?.get("uri") as? Uri
294+
val uri = navController.previousBackStackEntry?.savedStateHandle?.get<Uri>("uri")
296295
if (uri != null) {
297296
PdfPage(navController, uri)
298297
}

0 commit comments

Comments
 (0)