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.
Have your notification launch an Activity that runs the fingerprint sensor, then starts your Service.