2016-06-30 23 views
0

Ich arbeite derzeit an Android HCE-Anwendung. My HCE service nimmt APDUs vom Lesegerät. Reader Gerät sendet sie kontinuierlich. Also processCommandApdu() in meinem HCE service wird oft aufgerufen. Die meiste Zeit READER_STATE_APDU kommt. Dies ist ein proprietäres apdu und wird nur vom Lesegerät und meinem Android HCE service erkannt. Es enthält einige Informationen über Leser und spezielle MESSAGE Byte. Die meiste Zeit MESSAGE Byte ist 0x00 was bedeutet, keine Nachrichten. Aber manchmal deutet es auf ein Ereignis hin. Es kann ein Fehler oder etwas anderes sein. Mein HCE service muss MESSAGE Byte in Antwort APDU bestätigen. Und Lesergerät löscht MESSAGE Byte, wenn empfangene Antwort APDU von meinem HCE service.Android HCE-Anwendungsarchitektur

Jetzt ist meine Idee, READER_STATE_APDU in processCommandApdu() Methode zu analysieren und entsprechende Activity Benutzer anzuzeigen.

Zum Beispiel, wenn MESSAGE Byte 0x00 ist, möchte ich ReaderActivity starten, um dem Benutzer Leserinfo anzuzeigen. Und wenn MESSAGE Byte SOME_ERROR ist, möchte ich ErrorActivity starten, um dem Benutzer einen Fehler anzuzeigen.

Also mein processCommandApdu() kann so (Pseudo-Code):

public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) 
{ 
    ... 

    if commandApdu is READER_STATE_APDU 
    { 
     if messageByte is NO_MESSAGE 
     { 
      create intent for ReaderActivity and start it 
     } 
     else if messageByte is SOME_ERROR 
     { 
      create intent for ErrorActivity and start it 
     } 
     ... 
    } 

    ... 
} 

Natürlich sollten diese Aktivitäten haben einen Modus oder Fahnen in Absichten entspricht.

Aber wie ich bereits sagte, ist MESSAGE Byte SOME_ERROR nur für eine Transaktion, und ich möchte für eine gewisse Zeit ErrorActivity an Benutzer zeigen und zu verhindern, ReaderActivity gestartet wird.

So kann ich folgenden Code in meinem HCE service (Pseudo-Code) vorstellen:

boolean mStartReaderActivity; 

... 

public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) 
{ 
    ... 

    if commandApdu is READER_STATE_APDU 
    { 
     if messageByte is NO_MESSAGE 
     { 
      if (mStartReaderActivity) 
      { 
       create intent for ReaderActivity and start it 
      } 
     } 
     else if messageByte is SOME_ERROR 
     { 
      if (mStartReaderActivity) 
      { 
       mStartReaderActivity = false; 
      } 

      create intent for ErrorActivity and start it 
     } 
     ... 
    } 

    ... 
} 

... 

public int onStartCommand(Intent intent, int flags, int startId) 
{ 
    if intent is INTENT_ERROR_CONFIRMED 
    { 
     mStartReaderActivity = true; 
    } 
} 

und in meinem ErrorActivity (Pseudo-Code):

public void onConfirmErrorButtonClick() 
{ 
    create INTENT_ERROR_CONFIRMED and start service 
} 

Aber diese Lösung scheint unzuverlässig zu sein . Ich könnte zum Beispiel verwende SharedPreferencesmStartReaderActivity über meine HCE service Erholung zu behalten (Pseudo-Code):

boolean mStartReaderActivity; 

... 

public void onCreate() 
{ 
    ... 
    loadStartActivityFromPreferences(); 
    ... 
} 

public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) 
{ 
    ... 

    if commandApdu is READER_STATE_APDU 
    { 
     if messageByte is NO_MESSAGE 
     { 
      if (mStartReaderActivity) 
      { 
       create intent for ReaderActivity and start it 
      } 
     } 
     else if messageByte is SOME_ERROR 
     { 
      if (mStartReaderActivity) 
      { 
       mStartReaderActivity = false; 
       saveStartActivityToPreferences(); 
      } 

      create intent for ErrorActivity and start it 
     } 
     ... 
    } 

    ... 
} 

... 

public int onStartCommand(Intent intent, int flags, int startId) 
{ 
    if intent is INTENT_ERROR_CONFIRMED 
    { 
     mStartReaderActivity = true; 
     saveStartActivityToPreferences(); 
    } 
} 

Aber es gibt keine Garantie, dass INTENT_ERROR_CONFIRMED erstellt und gesendet und geliefert werden. Beispielsweise kann Android den Prozess beenden, bevor der Benutzer die Schaltfläche gedrückt hat. So kann HCE service mit mStartReaderActivity==false stecken bleiben.

Gibt es eine Möglichkeit, damit umzugehen?

Oder sollte ich vielleicht Architektur ändern? Zum Beispiel, sollte ich einen Activity mit Fragments verwenden und mStartReaderActivity (well, mShowReaderFragment in new terms) in Activity über savedINstanceState behalten?

Oder vielleicht eine andere Lösung?

Antwort

0

Ich bin mir nicht sicher, was Sie genau wollen, aber wenn Sie ErrorActivity zeigen möchten, bis Benutzer auf die Schaltfläche klicken.

HCE Server (es ist Pseudo-Code):

public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) 
{ 
    if commandApdu is READER_STATE_APDU { 
     if messageByte is NO_MESSAGE { 
      if(SharedPrefs 'inError != true'){ 
       create intent for ReaderActivity and start it 
      } 
     } else if messageByte is SOME_ERROR { 
      save 'inError = true + errorMessage=myerror' in SharedPref 
      create intent for ErrorActivity and start it 
     } 
    } 
} 

@Override 
public void onDestroy() { 
    // set error to false 
    SharedPrefs 'inError = false' 
} 

In ErrorActivity (es ist Pseudo-Code)

//click on button acknowledge 
public void clickAcknowledgeError(View v){ 
    save 'inError = false' 
} 
+0

Thanks a lot für Antwort. Aber ich denke, dass Ihre Lösung ähnlich wie meine ist (siehe 'saveStartActivityToPreferences()' und 'loadStartActivityFromPreferences()' in meiner Frage), und wenn ja, es funktioniert nicht. Zum Beispiel hat 'HCE service'' 'ERROR' 'gesetzt und gesetzt (und in Prefs gespeichert). Dann wird 'ErrorActivity' gestartet und dem Benutzer angezeigt. Dann tötet Android den Prozess und der Benutzer drückt die Schaltfläche nicht, und wenn dies der Fall ist, wird das Flag nicht gelöscht. Dann wird der 'HCE-Dienst' neu gestartet und das Flag aus den Einstellungen gelesen. Jetzt zeigt Flag immer an, dass 'ReaderActivity' nicht gestartet werden sollte – fighter0ik

+0

Sie könnten onDestroy überschreiben, ich habe meine Antwort aktualisiert – LaurentY

+0

@ fighter0ik wenn es nützlich ist, bitte akzeptieren Sie die Antwort – LaurentY