Dev-hwang / flutter_foreground_task

This plugin is used to implement a foreground service on the Android platform.
https://pub.dev/packages/flutter_foreground_task
MIT License
140 stars 105 forks source link

Crash on Android 14 #220

Closed mohamadkenway closed 1 month ago

mohamadkenway commented 4 months ago

app crash on android 14 with these outputs :

E/AndroidRuntime( 6927): java.lang.RuntimeException: Unable to create service com.pravera.flutter_foreground_task.service.ForegroundService: android.app.InvalidForegroundServiceTypeException: Starting FGS with type none callerApp=ProcessRecord{dda2c92 6927:com.bargram.mobileapp.bargram_mobile/u0a190} targetSDK=34 has been prohibited E/AndroidRuntime( 6927): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4664) E/AndroidRuntime( 6927): at android.app.ActivityThread.-$$Nest$mhandleCreateService(Unknown Source:0) E/AndroidRuntime( 6927): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2264) E/AndroidRuntime( 6927): at android.os.Handler.dispatchMessage(Handler.java:106) E/AndroidRuntime( 6927): at android.os.Looper.loopOnce(Looper.java:205) E/AndroidRuntime( 6927): at android.os.Looper.loop(Looper.java:294) E/AndroidRuntime( 6927): at android.app.ActivityThread.main(ActivityThread.java:8177) E/AndroidRuntime( 6927): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime( 6927): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) E/AndroidRuntime( 6927): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) E/AndroidRuntime( 6927): Caused by: android.app.InvalidForegroundServiceTypeException: Starting FGS with type none callerApp=ProcessRecord{dda2c92 6927:com.bargram.mobileapp.bargram_mobile/u0a190} targetSDK=34 has been prohibited E/AndroidRuntime( 6927): at android.app.InvalidForegroundServiceTypeException$1.createFromParcel(InvalidForegroundServiceTypeException.java:53) E/AndroidRuntime( 6927): at android.app.InvalidForegroundServiceTypeException$1.createFromParcel(InvalidForegroundServiceTypeException.java:49) E/AndroidRuntime( 6927): at android.os.Parcel.readParcelableInternal(Parcel.java:4870) E/AndroidRuntime( 6927): at android.os.Parcel.readParcelable(Parcel.java:4852) E/AndroidRuntime( 6927): at android.os.Parcel.createExceptionOrNull(Parcel.java:3052) E/AndroidRuntime( 6927): at android.os.Parcel.createException(Parcel.java:3041) E/AndroidRuntime( 6927): at android.os.Parcel.readException(Parcel.java:3024) E/AndroidRuntime( 6927): at android.os.Parcel.readException(Parcel.java:2966) E/AndroidRuntime( 6927): at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:6761) E/AndroidRuntime( 6927): at android.app.Service.startForeground(Service.java:862) E/AndroidRuntime( 6927): at androidx.core.app.ServiceCompat$Api34Impl.startForeground(ServiceCompat.java:239) E/AndroidRuntime( 6927): at androidx.core.app.ServiceCompat.startForeground(ServiceCompat.java:172) E/AndroidRuntime( 6927): at com.pravera.flutter_foreground_task.service.ForegroundService.startForegroundService(ForegroundService.kt:246) E/AndroidRuntime( 6927): at com.pravera.flutter_foreground_task.service.ForegroundService.onCreate(ForegroundService.kt:85) E/AndroidRuntime( 6927): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4651) E/AndroidRuntime( 6927): ... 9 more I/Process ( 6927): Sending signal. PID: 6927 SIG: 9

mustansirgodhrawala commented 3 months ago

Were you able to fix this?

justjew commented 3 months ago

I have the same problem

UnluckyY1 commented 3 months ago

even after adding didn't solve the crash

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

and

<service android:name="com.pravera.flutter_foreground_task.service.ForegroundService" android:foregroundServiceType="dataSync" android:exported="false" />

UnluckyY1 commented 3 months ago

I believe I've identified the main cause of the crash:

Inside the ForegroundTask Widget, within the AndroidNotificationOptions, you need to specify the foregroundServiceType.

WillStartForegroundTask(
            onWillStart: () async {
              // Return whether to start the foreground service.
              return canStartForegroundTask;
            },
            notificationTitle: appName,
            notificationText: 'notificationText',
            androidNotificationOptions: AndroidNotificationOptions(
              **foregroundServiceType: AndroidForegroundServiceType.DATA_SYNC,**
              channelId: 'channelId',
              channelName: 'Sync Progress',
              channelDescription: 'This notification appears when the Sync service is running.',
              channelImportance: NotificationChannelImportance.LOW,
              priority: NotificationPriority.LOW,
              iconData: const NotificationIconData(
                resType: ResourceType.drawable,
                resPrefix: ResourcePrefix.ic,
                name: 'notification',
                backgroundColor: ThemeColor.primary,
              ),
            ),
            iosNotificationOptions: const IOSNotificationOptions(),
            foregroundTaskOptions: const ForegroundTaskOptions(allowWifiLock: true),
            callback: _startEmptyForegroundTaskHandler,
            child: child,
          )

I believe this option needs to be required by the AndroidNotificationOptions API or mentioned inside the readme file for clarity.

frederikstonge commented 3 months ago

I believe I've identified the main cause of the crash:

Inside the ForegroundTask Widget, within the AndroidNotificationOptions, you need to specify the foregroundServiceType.

WillStartForegroundTask(
            onWillStart: () async {
              // Return whether to start the foreground service.
              return canStartForegroundTask;
            },
            notificationTitle: appName,
            notificationText: 'notificationText',
            androidNotificationOptions: AndroidNotificationOptions(
              **foregroundServiceType: AndroidForegroundServiceType.DATA_SYNC,**
              channelId: 'channelId',
              channelName: 'Sync Progress',
              channelDescription: 'This notification appears when the Sync service is running.',
              channelImportance: NotificationChannelImportance.LOW,
              priority: NotificationPriority.LOW,
              iconData: const NotificationIconData(
                resType: ResourceType.drawable,
                resPrefix: ResourcePrefix.ic,
                name: 'notification',
                backgroundColor: ThemeColor.primary,
              ),
            ),
            iosNotificationOptions: const IOSNotificationOptions(),
            foregroundTaskOptions: const ForegroundTaskOptions(allowWifiLock: true),
            callback: _startEmptyForegroundTaskHandler,
            child: child,
          )

I believe this option needs to be required by the AndroidNotificationOptions API or mentioned inside the readme file for clarity.

Still crashes for me. I'm passing the foregroundServiceType to AndroidNotificationOptions, I also have the right permissions and definitions in my manifest. I'm using "specialUse", which also requires me to specify a subtype in the manifest, I don't know if this could be related, or it's because it's value is too big (static const int SPECIAL_USE = 1073741824;)

After some investigation, the line where we pass the foregroundServiceType is here : https://github.com/Dev-hwang/flutter_foreground_task/blob/master/android/src/main/kotlin/com/pravera/flutter_foreground_task/service/ForegroundService.kt#L246

ServiceCompat.startForeground(
        this,
        notificationOptions.id,
        builder.build(),
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            notificationOptions.foregroundServiceType
        } else {
            0
        }
    )

First of all, we set 0 when we are above android version O (in the first if above), but this parameter is only available starting at Q : https://developer.android.com/reference/androidx/core/app/ServiceCompat#summary

Also, I don't understand why None (0) is passed in my case. I'm using latest flutter version 3.22, with min sdk set to 23. target and compile sdk is 34 (Android 14).

The value seems to be correctly passed down to android, with val foregroundServiceType = prefs.getInt(PrefsKey.FOREGROUND_SERVICE_TYPE, 0) (however it defaults to 0 if it doesn't work).

Decoder07 commented 3 months ago

How was it working earlier without foregroundServiceType on android 14 ?

lloydk26 commented 3 months ago

@Decoder07 I think on older versions of the SDK, it's not required. Same thing happened to my project after updating the SDK, it started crashing without it. Unfortunately for me, even after adding the foregroundServiceType, I can still see some crashes being recorded on our side.


    FlutterForegroundTask.init(
      androidNotificationOptions: AndroidNotificationOptions(
        foregroundServiceType: AndroidForegroundServiceType.REMOTE_MESSAGING,
        channelId: NotificationChannels.processBookingId,
        channelName: NotificationChannels.processBookingName,
        channelImportance: NotificationChannelImportance.HIGH,
        priority: NotificationPriority.HIGH,
        iconData: const NotificationIconData(
          resType: ResourceType.mipmap,
          resPrefix: ResourcePrefix.ic,
          name: 'launcher',
        ),
        buttons: [],
      ),
      iosNotificationOptions: const IOSNotificationOptions(),
      foregroundTaskOptions: const ForegroundTaskOptions(
        autoRunOnBoot: true,
        allowWifiLock: true,
      ),
    );
  }
}```

has anyone managed to fix this? 
mohamadkenway commented 3 months ago

I fixed this issue by adding these properties : isSticky: false, foregroundServiceType: AndroidForegroundServiceType.MANIFEST,

lloydk26 commented 3 months ago

hi @mohamadkenway , in your app, did you guys recently updated your Flutter version and that's when you encountered the issue? If yes, I would like to ask how did you manage to replicate the issue as in our case, we consistently encounter it after updating our Flutter SDK, and after adding foregroundServiceType: AndroidForegroundServiceType.REMOTE_MESSAGING,

We didn't encounter it anymore. Unfortunately, we see a lot of our users in Crashlytics still encounter it even if our latest build has explicitly set a foregroundServiceType.

I'm hoping you experienced the same issue as us. Thanks in advance for the help

hasanalaniIT commented 3 months ago

Hello Guys I was having the same issues but after reading some of your comments I managed to make it work for me I'm working on a voice assistant application that uses a microphone for input and a speaker for output and I need the foreground service to make it listen to the user while it's in the background of the application. So what I did here is I updated the "flutter_foreground_task" package to the latest version "6.2.0" and I adjusted the androidNotificationOptions and added the : foregroundServiceType: AndroidForegroundServiceType.MANIFEST

and then in the AndroidManifest.xml I added these lines based on my app usage : <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

I hope this helps Good Luck

tatuan19 commented 3 months ago

@hasanalaniIT Can you tell me your Flutter version?

hasanalaniIT commented 3 months ago

@tatuan19 My current flutter and dart versions are Flutter 3.19.4 Dart 3.3.2

pamafe1976 commented 1 month ago

Hi. I had set targetSdkVersion to 33 to avoid this error, which apparently only appeared when compiling with 34. We are getting close to Googles 31/August deadline to switch to 34, so Its important to fix this issue asap.

My app is setting foregroundServiceType: AndroidForegroundServiceType.LOCATION

Also in the manifest, I have

        <service android:name="com.pravera.flutter_foreground_task.service.ForegroundService" 
                 android:stopWithTask="true" 
                 android:foregroundServiceType='location' 
                 android:exported="false"/>        

Im using Flutter 3.22.2 and a fork to flutter_foreground_task 6.2.0 (since I need the PR #195 that has not been merged)

What would be the difference if using foregroundServiceType: AndroidForegroundServiceType.MANIFEST?

Does it make any sense to make the change?

Regards

Dev-hwang commented 1 month ago

This is not any problem or error.

Starting with Android 14 or SdkVersion 34 , you must set foregroundServiceType to start foreground service.

Please see readme for more details.

@pamafe1976

image

Just update the plugin to the latest version and set foregroundServiceType in Manifest.

No longer need to set the foregroundServiceType of AndroidNotificationOptions.