2017-09-25 32 views
0

我正在開發一個應該在後臺工作的指紋手勢應用程序,並不斷偵聽用戶輸入的指紋以執行所需的操作。到目前爲止,我已嘗試使用IntentService使指紋掃描儀在後臺工作,但只要關閉活動或將其最小化,指紋掃描儀就會停止工作。即使在我的活動結束之後,有什麼方法可以在後臺使用指紋掃描儀? 這裏是我的代碼在後臺連續收聽Android設備上的指紋

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; 
    } 
} 

回答

0

你可以試試這個下面的代碼。首先你需要在清單文件中添加服務的性質

<service 
     android:name=".service.Service" 
     android:enabled="true" 
     android:icon="@drawable/ic_launcher" 
     android:isolatedProcess="true"> 

    </service> 

而且也是你的服務添加START_STICKY的。

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