Использование onNewIntent и жизненного цикла активности для проверки наличия сообщения

У меня есть сервер push-уведомлений для доставки сообщений в мое приложение Android, и я хотел бы знать, как лучше всего уведомить сервер, когда сообщение было просмотрено.

В настоящее время я пытаюсь отправить сообщение подтверждения на сервер, как только основное действие моего приложения вызывает его обратный вызов onResume, но поскольку я использую основное действие SingleTop и обрабатываю некоторые намерения с помощью метода onNewIntent, я не могу быть уверен если onResume вызвано намерением или приложением, выходящим на передний план. Я сопоставил поток обратного вызова в трех ситуациях, в которых может быть моя деятельность, когда она получает намерение запустить ее, а именно:

  • Действие выполняется на переднем плане (вверху стека) (1)

    Запуск -> onPause () -> onNewIntent (намерение) -> onResume ()

  • Действие приостанавливается на переднем плане (например, экран) (2)

    Приостановлено -> onRestart () -> onStart () -> onResume () -> onPause () -> onNewIntent (намерение)

  • Действие приостанавливается в фоновом режиме (например, я участвую в другом действии) (3)

    Приостановлено в фоновом режиме -> onNewIntent (намерение) -> onRestart () -> onStart () -> onResume ()

В случае, если я перейду к своей деятельности, не получив намерения:

  • Действие приостанавливается, и пользователь переходит к нему (4)

    Приостановлено -> onRestart () -> onStart () -> onResume ()

В случаях 1, 3 и 4 пользователь заканчивается экраном, на котором он / она действительно может видеть сообщение, поэтому я хочу отправить сообщение с подтверждением.

Если бы был обратный вызов, который вызывается только в том случае, если действие действительно становится видимым на экране, это было бы идеально, но мне трудно его найти.

Кто-нибудь знает, как я могу это решить?


person Felipe Jun    schedule 16.12.2014    source источник


Ответы (1)


У меня есть решение, может быть, не самое лучшее, но пока оно работает.

Я планирую сообщение подтверждения для каждого onResume целевого действия и отменяю его, если onPause вызывается быстро (что в большинстве случаев указывает на то, что это произошло из-за внешнего намерения, а не из-за активности).

onResume ()

@Override
protected void onResume() {

    Log.d("MainActivity", "onResume");
    super.onResume();

    final SharedPreferences prefs = getSharedPreferences("lastMessageId", Context.MODE_PRIVATE);
    final Long messageId = prefs.getLong("lastMessageId", -1L);

    Runnable task = new Runnable() {

        @Override
        public void run() {
            if(messageId!=-1L){
                Request req = getAgent().notifyMessageSeen(messageId, ((ApplicationILocate)getApplication()).getUser(MainActivity.this), MainActivity.this);
                ((ApplicationILocate)getApplication()).addRequestToQueue(req);
                prefs.edit().putLong("lastMessageId", -1).commit();
            }
        }
    };
    future = scheduler.schedule(task, 1, TimeUnit.SECONDS);
    resumedTime = new Time();
    resumedTime.setToNow();
}

onPause ()

protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    Log.d("MainActivity", "onPause");

    pausedTime = new Time();
    pausedTime.setToNow();
    Log.d("MainActivity", "elapsed between resume and pause: "+(pausedTime.toMillis(false)-resumedTime.toMillis(false)));
    if(pausedTime.toMillis(false)-resumedTime.toMillis(false) < 100){
        future.cancel(true);
    }
}

Таким образом, сообщение получает подтверждение каждый раз, когда оно выходит на экран, и экран не заблокирован. Любое лучшее решение приветствуется.

person Felipe Jun    schedule 18.12.2014