Android judges that the app is placed in the background to monitor the home button

background:

The user presses the Home button to run the program in the background or the application starts other activities, such as the system browser, SMS, etc., and needs to send a notification to the system. After the user finishes other operations, click the notification bar to return to the application.

Question 1
When will the notification be sent?
The event that the user presses Home cannot be captured in the application layer, so it can only be started from the activity life cycle method.

Method 1:
All activities of the system inherit a BaseActivity, and maintain an array of currently visible activities in BaseActivity:
protected static ArrayList  sVisibleActivities = new ArrayList();

In onResume, save the current activity and clear all notifications at the same time:
protected void onResume()
{
if (!sVisibleActivities.contains(this))
{
sVisibleActivities.add(this);
}

// Clear the system message
mNotificationManager.cancel(R.id.notify);
}

In onStop, clear the saved current activity:
protected void onStop ()
{
if (sVisibleActivities.contains(this))
{
sVisibleActivities.remove(this);
}

// If there is currently no visible activity, send a system notification
if (sVisibleActivities.isEmpty())
{
sendBackgroundNotify();
}

super.onStop();
}

This way works in most cases It works well and can meet the requirements, but when the problem occurs, the onStop() method may not be called when the foreground activity is placed in the background, so the notification may not be sent!

Method 2:
After many twists and turns, it is found that activity has a life cycle method to achieve the purpose:

protected void onUserLeaveHint ()

Added in  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.

public void onUserInteraction ()

Added in  API level 3

Called whenever a key, touch, or trackball event is dispatched to the activity. Implement this method if you wish to know that the user has interacted with the device in some way while your activity is running. This callback and onUserLeaveHint() are intended to help activities manage status bar notifications intelligently; specifically, for helping activities determine the proper time to cancel a notfication.

All calls to your activity's onUserLeaveHint() callback will be accompanied by calls to onUserInteraction(). This ensures that your activity will be told of relevant user activity such as pulling down the notification pane and touching an item there.

Note that this callback will be invoked for the touch down action that begins a touch gesture, but may not be invoked for the touch-moved and touch-up actions that follow.


从文档来看,这个方法似乎就是为了按下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...

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325565751&siteId=291194637