Reputation: 311
I have implemented Foreground Service using WorkManager, it works fine upto API Level 33. Since it is mandatory in API Level 34 to specify foregroundServiceType, I specified it in Worker and in the Manifest but getting this error.
AndroidManifest.xml
Required Permissions:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<service
android:name=".services.DownloadService"
android:exported="false"
android:enabled="true"
tools:node="merge"
android:foregroundServiceType="dataSync"/>
Inside Worker:
setForegroundAsync(
ForegroundInfo(
NOTIFICATION_ID,
getNotification(),
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
)
)
Getting this error
java.lang.IllegalArgumentException: foregroundServiceType 0x00000001 is not a subset of foregroundServiceType attribute 0x00000000 in service element of manifest file at android.os.Parcel.createExceptionOrNull(Parcel.java:3015)
at android.os.Parcel.createException(Parcel.java:2995)
at android.os.Parcel.readException(Parcel.java:2978)
at android.os.Parcel.readException(Parcel.java:2920)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:6079) at android.app.Service.startForeground(Service.java:797) ...
I tried making some changes here and there but nothing works.
Upvotes: 31
Views: 13629
Reputation: 718
If you get the same error, but using C#/MAUI.NET with Android SDK 34. Set the "Name" in the Service Attribute of class which must be the same (android:name) in AndroidManifest.xml
namespace myproject;
[Service(Name = "com.example.myproject.MessageService")]
public partial class MessageService : Service
{
private void RegisterNotification()
{
//...
var notification = new Notification.Bulder(...).Build();
// supported on android 29.0 and later
StartForeground(NOTIFICATION_ID, notification,
Android.Content.PM.Foregroundservice.TypeDataSync);
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true">
<service android:name="com.example.myproject.MessageService"
android:foregroundServiceType="dataSync"
android:exported="false"/>
</application>
</manifest>
Upvotes: 6
Reputation: 21
I finally came up with a solution that worked for me.
[SupportedOSPlatform("android31.0")]
[Service(Exported = false, Enabled = true, Name = ".GPSService", ForegroundServiceType = ForegroundService.TypeLocation)]
public class GPSService : Service
{
I had to put the "ForegroundService.TypeLocation in the attribute so that this function would work:
if (Build.VERSION.SdkInt >= BuildVersionCodes.R)
{
StartForeground(NotificationId, new Notification.Builder(this, ChannelId)
.SetContentTitle("GPS Service")
.SetContentText("GPS Service is running")
.SetSmallIcon(Resource.Drawable.notification_action_background)
.Build(),
ForegroundService.TypeLocation);
}
Everything else I tried prior to adding the attribute would throw an error.
Happy coding!
Upvotes: 2
Reputation: 945
Thanks to @sebastian I got the right answer for this exception, when no services are used in application, but WorkManager is used.
The full answer would be to add into AndroidManifest.xml
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />
Also add proper permission in the same file, based on foregroundServiceType
that is defined for that service. In this case, add permission:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
And to call startForegroundAsync
, create ForegroundInfo on the following way:
ForegroundInfo foregroundInfo;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
foregroundInfo = new ForegroundInfo(notificationId, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
} else {
foregroundInfo = new ForegroundInfo(notificationId, notification);
}
setForegroundAsync(foregroundInfo);
Upvotes: 46
Reputation: 2890
Try adding
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />
to the Manifest.
Source: Documenation
Upvotes: 19
Reputation: 5368
Error message says that foregroundServiceType you have used to invoke your service isn't declared in Manifest. It seems like you have declared your service type as "mediaPlayback" in manifest and is trying to launch it as "dataSync". You can also define multiple foregroundServiceTypes for your service and use one of them while launching service depending upon use case you are starting service. To provide multiple types in declaration, you may separate all your types by a pipe(|) symbol. Try changing your code as below or remove mediaPlayback if its not required.
<service
android:name=".services.DownloadService"
android:exported="false"
android:enabled="true"
tools:node="merge"
android:foregroundServiceType="dataSync|mediaPlayback"/>
Reference: https://developer.android.com/about/versions/14/changes/fgs-types-required
Upvotes: 2