Android 14 Workmanger Foreground Service type

Rmvivek
2 min readJan 2, 2024

--

In Android 10, for all Foreground services, appeared the possibility to announce the type of service that specifies the purpose of its launch. In Android 14, it becomes mandatory to specify the type for all Services that can be launched as Foreground, and in modern Android, this is almost all cases. To cover all the options of using Foreground Service they added new types of services, and each of them has a special permission.

  1. Manifast file:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<application tools:targetApi="34">
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
/

Google Play will also check the Foreground Service during the build uploading phase. Any application with Android 14 support (targetSdk>= 34) must confirm that the Service with the announced task type is needed to run the application. Otherwise, you won’t be allowed to publish in the store.

2. creation workmanger object

private fun setOnTime()
{

val constrain = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val uploadReq = OneTimeWorkRequest.Builder(UploadWork::class.java)
.addTag(TAG)
.setConstraints(constrain)
.setInputData(data)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)//Expedited jobs only support network and storage constraints

.build()
val workMager = WorkManager.getInstance(this@WorkManagerMainActivity)
workMager.enqueue(uploadReq)
}

4. creating dowork class

class UploadWork(context: Context,params: WorkerParameters): CoroutineWorker(context,params) {//CoroutineWorker
companion object{

const val NOTIFICATION_NAME = "appid"
const val NOTIFICATION_CHANNEL = "channel_55"
}
override suspend fun doWork(): Result {

setForeground(createForegroundInfo())
//write your code network call or long runnung work
return Result.success(output)

}
private fun createForegroundInfo(): ForegroundInfo {
return if(SDK_INT>= Q) { ForegroundInfo(15, sendNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
}else{
ForegroundInfo(15, sendNotification())
}
}

private fun sendNotification():Notification {
val intent = Intent(applicationContext, MainActivity::class.java)
intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
val notificationManager = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val pendingIntent = getActivity(applicationContext, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
val notification = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("Android 14 service test")
.setContentText("SDK14")
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
if (SDK_INT >= O) {
notification.setChannelId(NOTIFICATION_CHANNEL)
val channel = NotificationChannel(NOTIFICATION_CHANNEL, NOTIFICATION_NAME, IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(101, notification.build())
return notification.build()
}

}

if not declare manifast file service type you getting below mention following error

Process: com.example.myapplication, PID: 15987
java.lang.IllegalArgumentException: foregroundServiceType 0x00000001 is not a subset of foregroundServiceType attribute 0x00000040 in service element of manifest file
at android.os.Parcel.createExceptionOrNull(Parcel.java:3015)

--

--