title: Continuously listen for fingerprints on android device in background
body: <p>I am developing a fingerprint gesture application which should work in the background and continuously listen for fingerprint input from user to perform desired actions. So far, I have tried to use IntentService to make fingerprint scanner work in the background but as soon as I close the activity or minimize it, fingerprint scanner stops working. Is there any way where I can use fingerprint scanner in the background even after my activity is closed?
  Here is my code</p>
  
  <p>MainActivity.java</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity {
  
      private static final String KEY_NAME = "secretkey";
      private Cipher cipher;
      private KeyStore keyStore;
      private KeyGenerator keyGenerator;
      private FingerprintManager.CryptoObject cryptoObject;
  
      private TextView textView;
      private Button auth_button,stop_button;
      private FingerprintManager fingerprintManager;
      private KeyguardManager keyguardManager;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M) {
              keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
              fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
              textView=(TextView)findViewById(R.id.authStatus);
              auth_button=(Button)findViewById(R.id.auth_button);
              stop_button=(Button)findViewById(R.id.stop_button);
  
              if (!fingerprintManager.isHardwareDetected()) {
                  textView.setText("Your device doesn't support fingerprint authentication");
              }
  
              if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
                  textView.setText("Please enable the fingerprint permission");
              }
  
              if (!fingerprintManager.hasEnrolledFingerprints()) {
                  textView.setText("No fingerprint configured. Please register at least one fingerprint in your device's Settings");
              }
  
              if (!keyguardManager.isKeyguardSecure()) {
                  textView.setText("Please enable lockscreen security in your device's Settings");
              }
  
              else {
                  auth_button.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          Toast.makeText(MainActivity.this, "Starting service", Toast.LENGTH_SHORT).show();
                          try
                          {
                              generateKey();
                          }
                          catch(Exception e)
                          {
                              e.printStackTrace();
                          }
                          if(initCipher())
                          {
                              Provider provider=new Provider(fingerprintManager,cryptoObject,MainActivity.this);
                              Intent intent=new Intent(MainActivity.this,AsyncService.class);
                              startService(intent);
                          }
                      }
                  });
  
                  stop_button.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          stopService(new Intent(MainActivity.this,AsyncService.class));
                          Toast.makeText(MainActivity.this, "Service stopped", Toast.LENGTH_SHORT).show();
                      }
                  });
              }
          }
      }
  
      private void generateKey() {
          try
          {
              keyStore = KeyStore.getInstance("AndroidKeyStore");
              keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
              keyStore.load(null);
              keyGenerator.init(new
  
                      KeyGenParameterSpec.Builder(KEY_NAME,
                      KeyProperties.PURPOSE_ENCRYPT |
                              KeyProperties.PURPOSE_DECRYPT)
                      .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                      .setUserAuthenticationRequired(true)
                      .setEncryptionPaddings(
                              KeyProperties.ENCRYPTION_PADDING_PKCS7)
                      .build());
  
              keyGenerator.generateKey();
          }
          catch (Exception e)
          {
              e.printStackTrace();
          }
      }
  
      public boolean initCipher() {
          try
          {
              cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7);
          }
          catch (Exception e)
          {
              throw new RuntimeException("Failed to get Cipher", e);
          }
  
          try
          {
              keyStore.load(null);
              SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME, null);
              cipher.init(Cipher.ENCRYPT_MODE, key);
              return true;
          }
          catch (KeyPermanentlyInvalidatedException e)
          {
              return false;
          }
          catch (Exception e)
          {
              throw new RuntimeException("Failed to init Cipher", e);
          }
      }
  }
  </code></pre>
  
  <p>AsyncService.java</p>
  
  <pre><code>public class AsyncService extends IntentService {
  
      private int ONGOING_NOTIFICATION_ID=2346712;
  
      public AsyncService() {
          super(AsyncService.class.getName());
      }
  
      @Override
      protected void onHandleIntent(Intent intent) {
          showNotification();
          new FingerprintHandler().startAuth(Provider.fpManager,Provider.cryptoObj);
      }
  
      public void showNotification() {
  
          Intent notificationIntent = new Intent(this, MainActivity.class);
          PendingIntent pendingIntent =
                  PendingIntent.getActivity(this, 0, notificationIntent, 0);
  
          Notification notification =
                  new Notification.Builder(this)
                          .setContentTitle(getText(R.string.notification_title))
                          .setContentText(getText(R.string.notification_message))
                          .setSmallIcon(R.drawable.launcher)
                          .setContentIntent(pendingIntent)
                          .build();
  
          startForeground(ONGOING_NOTIFICATION_ID, notification);
      }
  
      public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
  
          private CancellationSignal cancellationSignal;
          public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject)
          {
              cancellationSignal = new CancellationSignal();
              if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
              {
                  return;
              }
              manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
          }
  
          @Override
          public void onAuthenticationError(int errMsgId, CharSequence errString)
          {
  
          }
  
          @Override
          public void onAuthenticationFailed()
          {
             //some action to perform
          }
  
          @Override
          public void onAuthenticationHelp(int helpMsgId, CharSequence helpString)
          {
  
          }
  
          @Override
          public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result)
          {
              //some action to perform
          }
      }
  }
  </code></pre>
  
  <p>Provider.java</p>
  
  <pre><code>public class Provider {
  
      public static FingerprintManager fpManager;
      public static FingerprintManager.CryptoObject cryptoObj;
      public static Context mContext;
  
      public Provider(FingerprintManager fingerprintManager, FingerprintManager.CryptoObject cryptoObject, Context context) {
          fpManager=fingerprintManager;
          cryptoObj=cryptoObject;
          mContext=context;
      }
  }
  </code></pre>