利用onUserLeaveHint發送後臺運行通知

背景:
用戶按下Home鍵將程序置於後臺運行或者應用啓動其餘activity,好比系統瀏覽器,短信等,須要向系統發送通知,用戶作完別的操做後,點擊通知欄,回到應用。

問題
在什麼時機發送通知?
用戶按下Home的事件在應用層時捕捉不到的,所以只能從activity生命週期方法着手。

方法一:
系統全部activity繼承一個BaseActivity,在BaseActivity中維護一個當前可見的activity數組:
protected static ArrayListsVisibleActivities = new ArrayList();

在onResume中,將當前activity保存,同時清除全部通知:
protected void onResume()
{
    if (!sVisibleActivities.contains(this))
   {
        sVisibleActivities.add(this);

   }
// 清除系統消息
mNotificationManager.cancel(R.id.notify);
}

在onStop中,清除保存的當前activity:
protected void onStop()
{
    if (sVisibleActivities.contains(this))
   {
        sVisibleActivities.remove(this);
   }
// 若是當前沒有可見的activity,則發送系統通知
if (sVisibleActivities.isEmpty())
   {
        sendBackgroundNotify();
    }
super.onStop();
}

這種方式在大多數狀況下工做良好,能夠達到需求,可是問題時,當前臺的activity被至於後臺時,onStop()方法不必定會被調用,所以通知有可能不會被髮出!

方法二:
幾經周折,發現activity有一個生命週期方法能夠達到目的:

protected void onUserLeaveHint ()

Since: API Level 3
Called as part of the activity lifecycle when an activity is about to go into the background as the result of user choice.
For example, when the user presses the Home key, onUserLeaveHint() will be called, but when an incoming phone call causes the in-call Activity to be automatically brought to the foreground,
onUserLeaveHint() will not be called on the activity being interrupted. In cases when it is invoked, this method is called right before the activity's onPause() callback.
This callback and onUserInteraction() are intended to help activities manage status bar notifications intelligently; specifically, for helping activities determine the proper time to cancel a notfication.


從文檔來看,這個方法彷佛就是爲了按下Home鍵時這樣的場景設計的。
這樣,在onUserLeaveHint裏發出系統通知便可。
可是問題又來了,若是啓動應用,從一個activity依次調用startActivity,finish關閉本身,啓動一個新的activity時,onUserLeaveHint也會被調用....

再次翻閱文檔,發現Intent中的一個Flag:

public static final int FLAG_ACTIVITY_NO_USER_ACTION

Since: API Level 3
If set, this flag will prevent the normal onUserLeaveHint() callback from occurring on the current frontmost activity before it is paused as the newly-started activity is brought to the front.

Typically, an activity can rely on that callback to indicate that an explicit user action has caused their activity to be moved out of the foreground.
The callback marks an appropriate point in the activity's lifecycle for it to dismiss any notifications that it intends to display "until the user has seen them," such as a blinking LED.
If an activity is ever started via any non-user-driven events such as phone-call receipt or an alarm handler, this flag should be passed to Context.startActivity, ensuring that the pausing activity does not think the user has acknowledged its notification.
這正是我想要的,這樣,在啓動activity時,往intent中加上這個flag,onUserLeaveHint就不會再被調用了,hoory...
相關文章
相關標籤/搜索