Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on Android "ForegroundServiceDidNotStartInTimeException" #230

Open
pbouttier opened this issue Aug 21, 2024 · 19 comments
Open

Crash on Android "ForegroundServiceDidNotStartInTimeException" #230

pbouttier opened this issue Aug 21, 2024 · 19 comments
Assignees
Labels
bug Something isn't working hacktoberfest

Comments

@pbouttier
Copy link

pbouttier commented Aug 21, 2024

Alarm plugin version
3.1.5

Describe the bug
Play Store and Sentry report the same bug, a crash

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{b388286 u0 com.pbouttier.sptraining/com.gdelataillade.alarm.alarm.AlarmService}
    at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException(ActivityThread.java:2261)
    at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:2232)
    at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2526)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:222)
    at android.os.Looper.loop(Looper.java:314)
    at android.app.ActivityThread.main(ActivityThread.java:8602)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:565)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)

To Reproduce
Steps to reproduce the behavior:
I didn't reproduce it myself, I only have the data from the play store, from sentry

Expected behavior
No crash :)

Screenshots
I didn't reproduce it myself

Device info
Provide device info (Manufacturer, OS version, ...)
Happen mostly on Android 14, but also and 13, 12, 10. And on multiple devices : samsung, xiaomi, redmi ...

Additional context
I have the "await" on most of my functions.

void main() async {
  // [...] others plugins
  await Alarm.init();

How i have set the alarm

  Future<void> setAlarm(DateTime dateTime) async {
    UserSettingsModel userSettings = await ref.read(userSettingsProvider.future);

    final alarmSettings = AlarmSettings(
      id: alarmId,
      dateTime: dateTime,
      assetAudioPath: 'assets/audio/alarm.mp3',
      loopAudio: false,
      vibrate: userSettings.noticeEndCountdown == NoticeEndCountdown.vibrate,
      // Le son est indépendant du son configuré à l'instant T sur Android, ça le remet brieffement à cette valeur
      volume: userSettings.noticeEndCountdown == NoticeEndCountdown.sound ? userSettings.countdownVolume : 0.0, 
      notificationTitle: tr('workout.ongoing.notification_countdown.title'),
      notificationBody: tr('workout.ongoing.notification_countdown.body'),
      enableNotificationOnKill: false,
      androidFullScreenIntent: false,
    );
    await Alarm.set(alarmSettings: alarmSettings);
  }

I didn't have await on the stop, I'll add it in the next version of my app, just in case.
Edit : not solve with the await on stop.

Thanks for your time, this bug apart from the package is great :)

@pbouttier pbouttier added the bug Something isn't working label Aug 21, 2024
@gdelataillade
Copy link
Owner

Hi @pbouttier

Thank you for your interest in the plugin!

I’ve just released version 4.0.0-dev.1, which includes some updates to the Android native code. This isn’t the final 4.0.0 release, as further testing is needed, but I hope it resolves the issue you’re experiencing.

@pbouttier
Copy link
Author

pbouttier commented Aug 27, 2024

I've tried the 4.0.0-dev.1, on dev (so I couldn't see if my users had the initial crash) :

I need to add -keep class com.gdelataillade.alarm.models.** { *; } to proguard-rules.pro. Otherwise in --release i got this error

See https://github.com/google/gson/blob/main/Troubleshooting.md#r8-abstract-class, null, java.lang.RuntimeException: AlarmSettings Error parsing JSON to AlarmSettings: Abstract classes can't be instantiated! Adjust the R8 configuration or register an InstanceCreator or a TypeAdapter for this type. Class name: h0.b

in models/AlarmSettings.kt

val gson = Gson()
val jsonString = gson.toJson(modifiedJson)
val result = gson.fromJson(jsonString, AlarmSettings::class.java)

And I've seen other minor things. I don't know if it's directly related to 4.0.0, or to the scope you wanted to integrate, but I'll put them here anyway just in case:

  • When the alarm sounds, the icon of my app is shown in the taskbar at the top, but in the notification itself only a white square is present. I suspect that it convert the icon into a grey square if not transparency + white is present. Add a different icon could be a nice improvement, if we don't want to reuse the app icon (which is not a minimalistic white + transparency in most of the case)

  • When I set an alarm 5s later, and kill the app, it's not triggered. If I don't kill the app, it shows up fine. If I set an alarm 10s later, and kill the app, it will be triggered. If the time is too short, it doesn't seem to set, perhaps a problem with the exact time?

@gdelataillade
Copy link
Owner

Hi @pbouttier

Thanks for your feedback !

  1. About the error parsing JSON to AlarmSettings, I added the proguard-rules.pro to the plugin and released version 4.0.0-dev.2.

  2. About the notification icon, I should indeed do something so developers can customize it. I'll add it to my to do list.

  3. This behavior occurs because, for alarms set to trigger within 5 seconds or less, I bypass the AlarmManager and directly start the AlarmService. The reason for this is that triggering the AlarmManager is a resource-intensive operation that can take a few seconds to execute, which is impractical for such short intervals. However, I can optimize this by reducing the threshold from 5 seconds to 3 seconds.

@pbouttier
Copy link
Author

Nice !

For 3, I don't think it's necessary to do anything specific. I was testing it in brute force mode, but it's unlikely to have a real case where it needs to alarm less than 5s later.

@pbouttier
Copy link
Author

Re,

The problem persist on lastest version

Exception android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
  at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException (ActivityThread.java:2262)
  at android.app.ActivityThread.throwRemoteServiceException (ActivityThread.java:2233)
  at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2527)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:222)
  at android.os.Looper.loop (Looper.java:314)
  at android.app.ActivityThread.main (ActivityThread.java:8610)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:565)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1081)

And a second one (few cases) :

Exception java.lang.RuntimeException:
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5071)
  at android.app.ActivityThread.-$$Nest$mhandleServiceArgs
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2435)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:224)
  at android.os.Looper.loop (Looper.java:318)
  at android.app.ActivityThread.main (ActivityThread.java:8762)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:561)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1013)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
  at org.json.JSONTokener.nextCleanInternal (JSONTokener.java:121)
  at org.json.JSONTokener.nextValue (JSONTokener.java:98)
  at org.json.JSONObject.<init> (JSONObject.java:168)
  at org.json.JSONObject.<init> (JSONObject.java:185)
  at com.gdelataillade.alarm.alarm.AlarmService.onStartCommand (AlarmService.kt:71)
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5053)

@gdelataillade
Copy link
Owner

Hi @pbouttier

I've been unable to reproduce your issue. Are you sure you followed the installation steps ?

@pbouttier
Copy link
Author

Re, sorry for my late reply.

I was missing the scheduleExactAlarm permission but I can't find a configuration where it would be disabled, nor can I reproduce the problem on an emulator.

My hope was that you had an idea of what might be blocking it, but if we're both lost, we'll be sailing blind.

Maybe something like this ? https://stackoverflow.com/questions/77415459/android-13-foregroundservicedidnotstartintimeexception, androidx/media#112 ?

@gdelataillade
Copy link
Owner

I'm aware of the 5 seconds rule, I run startForeground almost instantly when alarm is triggered. Maybe there's an error before it is called. Do you have more logs to share ?

@pbouttier
Copy link
Author

I have these json from sentry. Android 13 & 14, differents permissions.

schedule, post notif not granted us.sentry.io.json
playback not granted us.sentry.io.json

@gdelataillade
Copy link
Owner

Hi @pbouttier

Sorry for the late reply. Do you ask for the scheduleExactAlarm permission ? If we can't reproduce the issue maybe it's because this permission is not granted by default in some devices. Maybe you could try to add it (see doc step 5) and see if the issue still appears in your Sentry.

What do you think ?

@pbouttier
Copy link
Author

pbouttier commented Oct 1, 2024

In the second error log, the permissions were :

‘SCHEDULE_EXACT_ALARM": “granted”,
‘USE_EXACT_ALARM": “granted”,

So the problem must not be there

Sorry, I only saw afterwards that it was a raw file, with no indentation or line feeds. Here they are, in readable format :

schedule not granted.txt
play back not granted beautiful.json.txt

And thanks for the custom notification icon, it's great

@gdelataillade
Copy link
Owner

I saw something interesting in the second error log:

"FOREGROUND_SERVICE_MEDIA_PLAYBACK": "not_granted"

I believe this permission is necessary. The weird thing is that it should be granted by default when I added it in the plugin's manifest here:

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

Did you disable it manually ? Does you other logs have this permission not granted ?

If so, log 1 may crash because of SCHEDULE_EXACT_ALARM and log 2 because of FOREGROUND_SERVICE_MEDIA_PLAYBACK. What do you think ?

@gdelataillade
Copy link
Owner

Hi @pbouttier

Do you still have the issue ?

@pbouttier
Copy link
Author

Sorry for my late reply.

I haven't had time to test the request for the SCHEDULE_EXACT_ALARM permission. I'll include it in my next update but it's a big one, I've still got other points to finish.

I don't understand FOREGROUND_SERVICE_MEDIA_PLAYBACK either. The permission is in the .xml file, so it ‘should work’.

@gdelataillade
Copy link
Owner

No problem. Let me know how it goes in your next update !

@synstin
Copy link

synstin commented Oct 25, 2024

I often report the same crash.

POCO peridot (POCO F6) - Android 14(SDK 34)

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException
Exception android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
  at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException (ActivityThread.java:2250)
  at android.app.ActivityThread.throwRemoteServiceException (ActivityThread.java:2221)
  at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2515)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:224)
  at android.os.Looper.loop (Looper.java:318)
  at android.app.ActivityThread.main (ActivityThread.java:8790)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:561)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1013)

@gdelataillade
Copy link
Owner

Hi @synstin,

Do you have the Android permissions set up as outlined earlier in this conversation?

@synstin
Copy link

synstin commented Oct 30, 2024

I've set all permissions. This is my current list of permissions. Thank you.

<!-- PERMISSION -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
    <!-- /PERMISSION -->

    <!-- ALARM -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
    <!-- /ALARM -->

    <!-- AWESOME NOTIFICATION PERMISSION -->
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
    <!-- /AWESOME NOTIFICATION PERMISSION -->

@riqtech90
Copy link

Screenshot 2024-11-10 at 8 16 35 PM

My app also received daily crash report from firebase crashlytic. Haven't experience the crash personally, but from what i see, the crash report most of it is android 8 to android 11 devices

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working hacktoberfest
Projects
None yet
Development

No branches or pull requests

4 participants