mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 22:45:20 +00:00
Fix foreground service start eligibility (#714)
* Fix foreground service start eligibility * Defer foreground service start when backgrounded * fix crash --------- Co-authored-by: CC <cc@ggg.local>
This commit is contained in:
@@ -59,6 +59,7 @@ class MainActivity : OrientationAwareActivity() {
|
||||
private lateinit var meshService: BluetoothMeshService
|
||||
private lateinit var unifiedMeshService: MeshService
|
||||
private val mainViewModel: MainViewModel by viewModels()
|
||||
private var pendingMeshForegroundServiceStart = false
|
||||
private val chatViewModel: ChatViewModel by viewModels {
|
||||
object : ViewModelProvider.Factory {
|
||||
override fun <T : androidx.lifecycle.ViewModel> create(modelClass: Class<T>): T {
|
||||
@@ -114,8 +115,8 @@ class MainActivity : OrientationAwareActivity() {
|
||||
|
||||
// Initialize permission management
|
||||
permissionManager = PermissionManager(this)
|
||||
// Ensure foreground service is running and get mesh instance from holder
|
||||
try { com.bitchat.android.service.MeshForegroundService.start(applicationContext) } catch (_: Exception) { }
|
||||
// Start the foreground service when allowed, then get mesh instances from the holder.
|
||||
startMeshForegroundServiceBestEffort()
|
||||
meshService = com.bitchat.android.service.MeshServiceHolder.getOrCreate(applicationContext)
|
||||
unifiedMeshService = com.bitchat.android.service.MeshServiceHolder.getUnifiedOrCreate(applicationContext)
|
||||
// Expose BLE mesh to Wi‑Fi Aware controller for cross-transport relays - DEPRECATED
|
||||
@@ -614,6 +615,22 @@ class MainActivity : OrientationAwareActivity() {
|
||||
mainViewModel.updateErrorMessage(message)
|
||||
mainViewModel.updateOnboardingState(OnboardingState.ERROR)
|
||||
}
|
||||
|
||||
private fun startMeshForegroundServiceBestEffort() {
|
||||
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
|
||||
pendingMeshForegroundServiceStart = true
|
||||
Log.i("MainActivity", "Deferring foreground mesh service start until activity is started")
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
com.bitchat.android.service.MeshForegroundService.start(applicationContext)
|
||||
pendingMeshForegroundServiceStart = false
|
||||
} catch (e: Exception) {
|
||||
pendingMeshForegroundServiceStart = true
|
||||
Log.w("MainActivity", "Unable to start foreground mesh service; will retry when activity is started", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Battery Optimization status and proceed with onboarding flow
|
||||
@@ -715,6 +732,7 @@ class MainActivity : OrientationAwareActivity() {
|
||||
// Set up unified mesh delegate and start enabled transports
|
||||
unifiedMeshService.delegate = chatViewModel
|
||||
unifiedMeshService.startServices()
|
||||
startMeshForegroundServiceBestEffort()
|
||||
|
||||
Log.d("MainActivity", "Mesh service started successfully")
|
||||
|
||||
@@ -752,6 +770,13 @@ class MainActivity : OrientationAwareActivity() {
|
||||
handleVerificationIntent(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
if (pendingMeshForegroundServiceStart) {
|
||||
startMeshForegroundServiceBestEffort()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
@@ -38,24 +38,20 @@ class MeshForegroundService : Service() {
|
||||
fun start(context: Context) {
|
||||
val intent = Intent(context, MeshForegroundService::class.java).apply { action = ACTION_START }
|
||||
|
||||
// On API >= 26, avoid background-service start restrictions by using startForegroundService
|
||||
// only when we can actually post a notification (Android 13+ requires runtime notif permission)
|
||||
val bgEnabled = MeshServicePreferences.isBackgroundEnabled(true)
|
||||
val hasNotifPerm = hasNotificationPermissionStatic(context)
|
||||
// Only launch as an FGS when onStartCommand can promote immediately.
|
||||
val shouldStartForeground = shouldStartAsForeground(context)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (bgEnabled && hasNotifPerm) {
|
||||
if (shouldStartForeground) {
|
||||
context.startForegroundService(intent)
|
||||
} else {
|
||||
// Do not attempt to start a background service from headless context without notif permission
|
||||
// or when background is disabled, to avoid BackgroundServiceStartNotAllowedException.
|
||||
android.util.Log.i(
|
||||
"MeshForegroundService",
|
||||
"Not starting service on API>=26 (bgEnabled=$bgEnabled, hasNotifPerm=$hasNotifPerm)"
|
||||
"Not starting service on API>=26 (shouldStartForeground=$shouldStartForeground)"
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (bgEnabled) {
|
||||
if (MeshServicePreferences.isBackgroundEnabled(true)) {
|
||||
context.startService(intent)
|
||||
} else {
|
||||
android.util.Log.i("MeshForegroundService", "Background disabled; not starting service (pre-O)")
|
||||
@@ -69,12 +65,10 @@ class MeshForegroundService : Service() {
|
||||
*/
|
||||
fun onNotificationPermissionGranted(context: Context) {
|
||||
// If background is enabled and permission now granted, start/promo service
|
||||
val hasNotifPerm = hasNotificationPermissionStatic(context)
|
||||
if (!MeshServicePreferences.isBackgroundEnabled(true) || !hasNotifPerm) return
|
||||
if (!shouldStartAsForeground(context)) return
|
||||
|
||||
val intent = Intent(context, MeshForegroundService::class.java).apply { action = ACTION_UPDATE_NOTIFICATION }
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Safe now that we can show a notification
|
||||
context.startForegroundService(intent)
|
||||
} else {
|
||||
context.startService(intent)
|
||||
|
||||
Reference in New Issue
Block a user