androidandroid-serviceandroid-fingerprint-api

Use FingerprintService from a custom service


Background

I have a small app where I want to add fingerprint authentication. This authentication is only used to unlock the app.

The important things are:

Problem

The FingerprintService must to be started from a foreground Activity. Even if I put the service in foreground with startForeground(), the FingerprintService emits a warning:

01-01 23:22:11.015 1576-1576/system_process W/FingerprintService: Rejecting com.package.myapp ; not in foreground
01-01 23:22:11.015 1576-1576/system_process V/FingerprintService: authenticate(): reject com.package.myapp

This only happens if I touch the notification when I'm outside the app, e.g., in the home screen. If I touch it when I am in the app, the authentication works and I'm able to unlock using my fingerprint (because the Acticity is focused, in foreground).

My current code (only the relevant part)

From the Activity, display the notification that starts the service:

// NofityManager is a factory class that returns a configured Builder
NotificationCompat.Builder builder = NotifyManager.getBuilder(this);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(SERVICE_NOTIFICATION_ID, builder.build());

When the service is started, put it into foreground and start the fingerprint authentication:

@Override
public void onCreate()
{
    NotificationCompat.Builder builder = NotifyManager.getBuilder(this)
        .setContentTitle(getString(R.string.notification_title2))
        .setContentText(getString(R.string.notification_text));

    startForeground(FOREGROUND_NOTIFICATION_ID, builder.build());

    // this is the class that I use to setup the FingerprintService
    // and call authenticate()
    fingerprintValidator = new FingerprintValidator(this);

    if(fingerprintValidator.check(false))
    {
        try
        {
            fingerprintValidator.startService(this);
        }
        catch(RuntimeException ex)
        {
            Log.d(TAG, ex.getLocalizedMessage() + "\n" + ex.getStackTrace().toString());
        }
    }
    else
    {
        // notify the user
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    return START_STICKY;
}

Question

How can I use the FingerprintService from a custom service running in foreground? I know it is possible because I saw another app doing this, so must to be a way.


Solution

  • Have your notification launch an Activity that runs the fingerprint sensor, then starts your Service.