Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foreground service type for timer

My exercise app uses a foreground service to keep an accurate timer going when a user turns off the screen whilst exercising. There's both a countdown and indefinite count-up timer option. This works great on devices up until Android 14. Android 14 requires me to name a service type. Without this I get a android.app.MissingForegroundServiceTypeException, but when I look at the various service types I don't see any that fit the use case. It's not sensors that would fit health, it's not and exact timer which would fit systemExempted as the count-up is indefinite, and the restrictions around specialUse makes me think there's no chance it'll be accepted.

Does anyone know which type I should use. The code for launching the service is as follows:

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle(exerciseNameStr + " Timer Running")
                .setSmallIcon(exerciseIcons.getResourceId(iconId, 0))
                .setContentIntent(pendingIntent)
                .setChronometerCountDown(!countUpwards)
                .setUsesChronometer(true)
                .setTimeoutAfter(counterMsec + 1000)
                .setWhen(time)
                .build();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
        {
            startForeground(100, notification, FOREGROUND_SERVICE_TYPE_???);
        }
        else
        {
            startForeground(100, notification);   // <-- this code raises an exception for Android 14
        }

Is there another way to implement this type of timer showing the tick on the notification?

like image 399
Simon Huckett Avatar asked Jun 26 '26 17:06

Simon Huckett


1 Answers

Without an answer I opted for specialUse as follows:

AndroidManifest.xml:

<manifest
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
...
  <application>
...
    <service
        android:name=".CountService"
        android:foregroundServiceType="specialUse"
        android:exported="false">
        <property
            android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
            android:value="Foreground service needed to [fill in details for use case here]..."/>
    </service>
  </application>
</manifest

In addition to this I had to add a link in Google play console with a video showing the App in action justifying the use-case. After an extended review, all is well.

like image 86
Simon Huckett Avatar answered Jun 28 '26 16:06

Simon Huckett