0

我有一个推送通知服务器来将消息传递到我的 Android 应用程序,我想知道在看到消息时通知服务器的最佳方式。

目前,我正在尝试在我的应用程序的主要活动调用其 onResume 回调后立即将确认消息发送到服务器,但是当我使用 SingleTop 主要活动时,我使用 onNewIntent 方法处理一些意图,我不能确定如果 onResume 是由于 Intent 或应用程序进入前台。当我的活动收到启动它的意图时,我已经在三种情况下映射了回调流,它们是:

  • 活动在前台运行(栈顶)(1)

    运行 -> onPause() -> onNewIntent(intent) -> onResume()

  • 活动在前台暂停(例如屏幕)(2)

    暂停 -> onRestart() -> onStart() -> onResume() -> onPause() -> onNewIntent(intent)

  • 活动在后台暂停(例如,我在另一个活动中)(3)

    在后台暂停 -> onNewIntent(intent) -> onRestart() -> onStart() -> onResume()

如果我在没有收到意图的情况下导航到我的活动:

  • 活动暂停,用户导航到它 (4)

    暂停 -> onRestart() -> onStart() -> onResume()

在情况 1、3 和 4 中,用户在他/她可以实际看到消息的屏幕中结束,所以我想发送 ack 消息。

如果在活动真的在屏幕上可见的情况下调用回调,那将是完美的,但我很难找到它。

有人知道我该如何解决这个问题?

4

1 回答 1

0

我有一个解决方案,也许它不是最好的,但现在正在工作。

我安排目标活动的每个 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();
}

暂停()

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

所以消息每次进入屏幕时都会收到确认并且屏幕没有锁定。欢迎任何更好的解决方案。

于 2014-12-18T12:27:14.273 回答