Specify service type in startForeground for Android 14

This commit is contained in:
Sylvain Berfini 2023-06-16 13:39:10 +02:00
parent 32c8a098c5
commit 72b92408a1
3 changed files with 69 additions and 15 deletions

View file

@ -20,12 +20,17 @@
package org.linphone.compatibility package org.linphone.compatibility
import android.annotation.TargetApi import android.annotation.TargetApi
import android.app.ForegroundServiceStartNotAllowedException
import android.app.Notification
import android.app.NotificationManager import android.app.NotificationManager
import android.app.Service
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.ServiceInfo
import android.net.Uri import android.net.Uri
import android.provider.Settings import android.provider.Settings
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import org.linphone.core.tools.Log
@TargetApi(34) @TargetApi(34)
class Api34Compatibility { class Api34Compatibility {
@ -44,5 +49,37 @@ class Api34Compatibility {
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
ContextCompat.startActivity(context, intent, null) ContextCompat.startActivity(context, intent, null)
} }
fun startCallForegroundService(service: Service, notifId: Int, notif: Notification) {
try {
service.startForeground(
notifId,
notif,
ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
)
} catch (fssnae: ForegroundServiceStartNotAllowedException) {
Log.e("[Api34 Compatibility] Can't start service as foreground! $fssnae")
} catch (se: SecurityException) {
Log.e("[Api34 Compatibility] Can't start service as foreground! $se")
} catch (e: Exception) {
Log.e("[Api34 Compatibility] Can't start service as foreground! $e")
}
}
fun startDataSyncForegroundService(service: Service, notifId: Int, notif: Notification) {
try {
service.startForeground(
notifId,
notif,
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
)
} catch (fssnae: ForegroundServiceStartNotAllowedException) {
Log.e("[Api34 Compatibility] Can't start service as foreground! $fssnae")
} catch (se: SecurityException) {
Log.e("[Api34 Compatibility] Can't start service as foreground! $se")
} catch (e: Exception) {
Log.e("[Api34 Compatibility] Can't start service as foreground! $e")
}
}
} }
} }

View file

@ -291,7 +291,7 @@ class Compatibility {
} }
} }
fun startForegroundService(service: Service, notifId: Int, notif: Notification?) { private fun startForegroundService(service: Service, notifId: Int, notif: Notification?) {
if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12)) { if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12)) {
Api31Compatibility.startForegroundService(service, notifId, notif) Api31Compatibility.startForegroundService(service, notifId, notif)
} else { } else {
@ -299,6 +299,22 @@ class Compatibility {
} }
} }
fun startCallForegroundService(service: Service, notifId: Int, notif: Notification) {
if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) {
Api34Compatibility.startCallForegroundService(service, notifId, notif)
} else {
startForegroundService(service, notifId, notif)
}
}
fun startDataSyncForegroundService(service: Service, notifId: Int, notif: Notification) {
if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) {
Api34Compatibility.startDataSyncForegroundService(service, notifId, notif)
} else {
startForegroundService(service, notifId, notif)
}
}
/* Call */ /* Call */
fun canDrawOverlay(context: Context): Boolean { fun canDrawOverlay(context: Context): Boolean {

View file

@ -407,24 +407,23 @@ class NotificationsManager(private val context: Context) {
fun startForeground(coreService: CoreService, useAutoStartDescription: Boolean = true) { fun startForeground(coreService: CoreService, useAutoStartDescription: Boolean = true) {
service = coreService service = coreService
if (serviceNotification == null) { val notification = serviceNotification ?: createServiceNotification(useAutoStartDescription)
createServiceNotification(useAutoStartDescription) if (notification == null) {
if (serviceNotification == null) { Log.e(
Log.e( "[Notifications Manager] Failed to create service notification, aborting foreground service!"
"[Notifications Manager] Failed to create service notification, aborting foreground service!" )
) return
return
}
} }
currentForegroundServiceNotificationId = SERVICE_NOTIF_ID currentForegroundServiceNotificationId = SERVICE_NOTIF_ID
Log.i( Log.i(
"[Notifications Manager] Starting service as foreground [$currentForegroundServiceNotificationId]" "[Notifications Manager] Starting service as foreground [$currentForegroundServiceNotificationId]"
) )
Compatibility.startForegroundService(
Compatibility.startDataSyncForegroundService(
coreService, coreService,
currentForegroundServiceNotificationId, currentForegroundServiceNotificationId,
serviceNotification notification
) )
} }
@ -438,7 +437,7 @@ class NotificationsManager(private val context: Context) {
val coreService = service val coreService = service
if (coreService != null) { if (coreService != null) {
Compatibility.startForegroundService( Compatibility.startCallForegroundService(
coreService, coreService,
currentForegroundServiceNotificationId, currentForegroundServiceNotificationId,
callNotification callNotification
@ -499,11 +498,11 @@ class NotificationsManager(private val context: Context) {
service = null service = null
} }
private fun createServiceNotification(useAutoStartDescription: Boolean = false) { private fun createServiceNotification(useAutoStartDescription: Boolean = false): Notification? {
val serviceChannel = context.getString(R.string.notification_channel_service_id) val serviceChannel = context.getString(R.string.notification_channel_service_id)
if (Compatibility.getChannelImportance(notificationManager, serviceChannel) == NotificationManagerCompat.IMPORTANCE_NONE) { if (Compatibility.getChannelImportance(notificationManager, serviceChannel) == NotificationManagerCompat.IMPORTANCE_NONE) {
Log.w("[Notifications Manager] Service channel is disabled!") Log.w("[Notifications Manager] Service channel is disabled!")
return return null
} }
val pendingIntent = NavDeepLinkBuilder(context) val pendingIntent = NavDeepLinkBuilder(context)
@ -535,7 +534,9 @@ class NotificationsManager(private val context: Context) {
builder.setContentIntent(pendingIntent) builder.setContentIntent(pendingIntent)
} }
serviceNotification = builder.build() val notif = builder.build()
serviceNotification = notif
return notif
} }
/* Call related */ /* Call related */