How can I add foregroundServiceType to a library manifest while maintaining backwards compatibility?

black picture black · Jun 13, 2019 · Viewed 10.6k times · Source

My library project has a location service, and per Android Q requirements it sets the android:foregroundServiceType="location" attribute in the manifest. When an app module uses my library and compiles against API level 28, it fails with the following error:

AndroidManifest.xml:57: AAPT: error: attribute android:foregroundServiceType not found.

How can my library maintain compatibility with older versions, while making sure the functionality works on Android Q?

Answer

black picture black · Jun 17, 2019

My goal is to avoid breaking anyone's build when the library version is updated, and at the same time avoid forcing the developer to compile against API 29. It seems I have two choices:

  • Provide a separate library so that developers compiling against API 28 and lower don't get impacted;
  • warn developers targeting the new version to replace the service definition in the manifest using tools:node="replace".

The problem with the first approach is that I will need to maintain two libraries for some time. The problem with the second is that developers must remember to revert the change once they update the SDK version.

In my case, I will go with the second approach. By passing an explicit foreground service type to the startForeground method when targeting Android Q, I can cause a crash if the type is not set in the manifest. The developer can therefore catch this when targeting Android Q and revert the manifest change to fix it.