Search code examples
androidtimernotificationsforeground-service

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?


Solution

  • 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.