Je développe une application gestuelle d'empreintes digitales qui devrait fonctionner en arrière-plan et écouter en continu les entrées d'empreintes digitales de l'utilisateur pour effectuer les actions souhaitées. Jusqu'à présent, j'ai essayé d'utiliser IntentService pour faire fonctionner le scanner d'empreintes digitales en arrière-plan, mais dès que je ferme l'activité ou la minimise, le scanner d'empreintes digitales cesse de fonctionner. Est-il possible d'utiliser le scanner d'empreintes digitales en arrière-plan même après la fermeture de mon activité? Voici mon codeEn écoute continue pour les empreintes digitales sur l'appareil Android en arrière-plan
MainActivity.java
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 >= 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);
}
}
}
AsyncService.java
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
}
}
}
Provider.java
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;
}
}