Use FingerprintService from a custom service

869 views Asked by At

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:

  • The main point of the app is to run in background as a service.
  • The user must to be able to unlock the app from anywhere in the system (not just from the activity).
  • The user must to touch a notification to start the service, and therefore start the fingerprint authentication.

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.

1

There are 1 answers

2
Gabe Sechan On BEST ANSWER

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