Fixing "MissingForegroundServiceTypeException: Starting FGS without a type" on Android 14
Problem Statement
When running foreground services on Android 14 (API level 34) with targetSdkVersion=34
, you may encounter the error:
android.app.MissingForegroundServiceTypeException: Starting FGS without a type
This error causes app crashes specifically on Android 14 devices while the same code works correctly on Android 13 and earlier versions. The issue occurs when:
- Your app's target is set to Android 14 (API 34)
- You start a foreground service without specifying a foreground service type
- You haven't declared the required service type in your manifest
Solution
Android 14 introduces stricter requirements for foreground services. You must:
- Declare the appropriate foreground service type in your manifest
- Specify the service type at runtime when starting the service
- Add necessary permissions if using special foreground service types
Step 1: Update AndroidManifest.xml
Add the following to your AndroidManifest.xml
, replacing [SERVICE_NAME]
and [SERVICE_TYPE]
with your actual service name and type:
<service
android:name=".[SERVICE_NAME]"
android:foregroundServiceType="[SERVICE_TYPE]"
android:exported="false"> <!-- Add other attributes as needed -->
</service>
For special use cases (when your service doesn't fit predefined categories), declare the special use permission:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
Step 2: Modify Service Startup Code
Update your Kotlin/Java code to specify the service type when starting foreground services on Android 14+:
private fun startForegroundService() {
// ... [notification setup code remains unchanged] ...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
// Android 14 (API 34)+ requires service type
startForeground(125, notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
)
} else {
// Legacy method for older versions
startForeground(125, notification)
}
}
Step 3: Choose Appropriate Service Type
Replace FOREGROUND_SERVICE_TYPE_SPECIAL_USE
with the type matching your service's purpose:
Service Type Constant | Manifest Value | Use Case |
---|---|---|
FOREGROUND_SERVICE_TYPE_SPECIAL_USE | specialUse | Generic services not covered by other types |
FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK | mediaPlayback | Audio/video playback |
FOREGROUND_SERVICE_TYPE_LOCATION | location | Location tracking |
FOREGROUND_SERVICE_TYPE_HEALTH | health | Health/fitness tracking |
Complete Implementation Example
private fun startForegroundService() {
// Notification setup remains unchanged from original code
val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// ... [channel setup] ...
} else {
NotificationCompat.Builder(this)
}
// ... [intent and notification configuration] ...
val notification = builder.build()
// Android 14+ compatibility
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startForeground(
125,
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE // Use appropriate type
)
} else {
startForeground(125, notification)
}
}
Key Considerations
- Target SDK Requirement: This fix only applies when targeting Android 14 (API 34) or higher
- Permission Rules:
FOREGROUND_SERVICE_SPECIAL_USE
requires no special user permission- Other types (like location) may require additional runtime permissions
- Backward Compatibility: Always maintain separate code paths for pre-Android 14 devices
- Type Selection: Choose the most specific type that matches your service's functionality
- Manifest Declaration: The
android:foregroundServiceType
in manifest must match the type used at runtime
Important Note
All foreground services must still meet the standard requirements regardless of type:
- Display a persistent notification
- Call
startForeground()
within the service'sonStartCommand()
- Use a notification channel (Android 8.0+)
For official guidance, refer to Android's foreground service documentation.
By implementing these changes, your foreground service will comply with Android 14's requirements while maintaining backward compatibility with older versions.