0

В настоящее время я работаю над приложением Android HCE. My HCE service берет APDU с устройства чтения. Устройство чтения отправляет их непрерывно. Так что processCommandApdu() в моем HCE service вызывается довольно часто. Заходит большинство времени READER_STATE_APDU. Это проприетарный апд, и он распознается только устройством чтения и моим андроидом HCE service. Он содержит некоторую информацию о читателе и специальный байт MESSAGE. В большинстве случаев MESSAGE байт 0x00, что означает отсутствие сообщений. Но иногда это указывает на какое-то событие. Это может быть ошибка или что-то еще. Мой HCE service должен подтвердить MESSAGE байт в ответ APDU. И устройство считывателя очищает MESSAGE байт, когда получил ответ APDU от моего HCE service.Архитектура приложения Android HCE

Теперь моя идея - разобрать READER_STATE_APDU в processCommandApdu() и показать соответствующие Activity пользователю.

Например, когда MESSAGE байт 0x00 Я хочу начать ReaderActivity, чтобы показать информацию читателю пользователю. И когда MESSAGE байт SOME_ERROR Я хочу начать ErrorActivity, чтобы показать пользователю ошибку.

Так что мой processCommandApdu() может быть, как это (псевдокод):

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

    ... 
} 

Конечно эти мероприятия должны иметь соответствующие режимы запуска или флаги в намерениях.

Но, как я уже говорил ранее, MESSAGE байт SOME_ERROR только для одной транзакции, и я хочу, чтобы показать ErrorActivity к пользователю в течение некоторого времени и предотвратить ReaderActivity от запуска.

Так что я могу представить себе следующий код в моем HCE service (псевдокоде):

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

и в моем ErrorActivity (псевдокоде):

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

Но это решение кажется ненадежным , Я мог бы, например, использовать SharedPreferences сохранить mStartReaderActivity по моему HCE service отдыха (псевдокод):

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

Но нет никакой гарантии, что INTENT_ERROR_CONFIRMED будут созданы и отправлены и доставлены. Например, Android может убить процесс до того, как пользователь нажал кнопку. Таким образом, HCE service может зависеть от mStartReaderActivity==false.

Есть ли способ справиться с этим?

Или, может быть, я должен изменить архитектуру? Например, следует ли использовать один Activity с Fragments и сохранить mStartReaderActivity (well, mShowReaderFragment in new terms) в Activity через savedINstanceState?

Возможно, какое-либо другое решение?

ответ

0

Я не уверен, что вы хотите точно, но если вы хотите показать ErrorActivity, пока пользователь не нажмет на кнопку.

HCE сервера (это псевдо-код):

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

В ErrorActivity (это псевдо-код)

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

Большое спасибо за ответ. Но я думаю, что ваше решение похоже на мое (см. 'SaveStartActivityToPreferences()' и 'loadStartActivityFromPreferences()' в моем вопросе), и если да, то он не работает. Например, служба «HCE» получила «ERROR» и установила флаг (и сохранила в prefs). Затем «ErrorActivity» запускается и отображается пользователю. Затем Android убивает процесс, и пользователь не нажимает кнопку, и если да, флаг не очищается. Затем 'HCE service' перезапускается и читает флаг из настроек. Теперь флаг всегда указывает, что 'ReaderActivity' не должен быть запущен – fighter0ik

+0

Вы можете переопределить onDestroy, я обновил свой ответ – LaurentY

+0

@ fighter0ik, если это полезно, пожалуйста, примите ответ – LaurentY

 Смежные вопросы

  • Нет связанных вопросов^_^