I am developing an Android app and I want to detect when the user exits my app either by clicking the Back button or the Home button.
我正在开发一个Android应用程序,我想通过单击“返回”按钮或“主页”按钮来检测用户何时退出我的应用程序。
Also, an event like onInit()
would be useful in my scenario, as I just want to have the MyInıt
action start at first.
此外,像onInit()这样的事件在我的场景中会很有用,因为我只想先启动MyInıt动作。
onDestroy()
is not called until other apps need more memory.
在其他应用程序需要更多内存之前,不会调用onDestroy()。
5 个解决方案
#1
18
If your activity is the last in the stack then detecting a back button with onKeyDown would solve 1/2 of this
如果您的活动是堆栈中的最后一个,那么使用onKeyDown检测后退按钮将解决其中的1/2
The home key is a little trickier, there is no absolute method but you could do something like this which works for my simple needs.
主键有点棘手,没有绝对的方法,但你可以做这样的事情,适合我的简单需求。
The onUserLeaveHint is called according to the documentation when the user clicks the home button OR when something interrupts your application (like an incoming phone call) so to guess which it is you use the onUserInteraction method to stamp the last user interaction time.
当用户单击主页按钮或某些内容中断您的应用程序时(例如来电),根据文档调用onUserLeaveHint,以便猜测您使用onUserInteraction方法标记最后一个用户交互时间。
Now if that precedes the onUserLeaveHint closely enough you can assume (not guaranteed but has worked for me so far) that the home button was the reason your application is being pushed into the background (exiting)
现在,如果它在onUserLeaveHint之前足够紧密,你可以假设(不保证但到目前为止对我有用)主页按钮是你的应用程序被推入后台的原因(退出)
Not sure what your intent is in catching the home button, anyway here is a simplistic way to do that, I use a 100ms fence around the two events which I have found has always worked for me. NOTE: I have only tested on a handful of phones, like all things in Android your mileage will vary dependent on OS / Hardware (heck even the stuff that's documented and supposed to work sometimes doesn't)
不知道你在捕捉主页按钮的意图是什么,无论如何这里是一个简单的方法,我使用100ms围栏围绕这两个事件我发现一直为我工作。注意:我只测试过一些手机,就像Android中的所有东西一样,你的里程数会因操作系统/硬件的不同而有所不同(即使是有记录的,有时也不应该工作的东西)
long userInteractionTime = 0;
@Override
public void onUserInteraction() {
userInteractionTime = System.currentTimeMillis();
super.onUserInteraction();
Log.i("appname","Interaction");
}
@Override
public void onUserLeaveHint() {
long uiDelta = (System.currentTimeMillis() - userInteractionTime);
super.onUserLeaveHint();
Log.i("bThere","Last User Interaction = "+uiLag);
if (uiDelta < 100)
Log.i("appname","Home Key Pressed");
else
Log.i("appname","We are leaving, but will probably be back shortly!");
}
#2
24
Note: This only works if your target is >= API14
You can also use Application.registerActivityLifecycleCallbacks() and when any activity pauses post a delayed Runnable
(that will invoke when user lefts app) to Handler
. When activities are created/started/resumed you remove that Runnable
from Handler
. So when you navigate inside your app you always cancel that Runnable
, but if another activity not from your app is activated - the Runnable
will be invoked.
您还可以使用Application.registerActivityLifecycleCallbacks(),并在任何活动暂停时将延迟的Runnable(将在用户左侧应用程序时调用)发布到Handler。创建/启动/恢复活动时,从Handler中删除该Runnable。因此,当您在应用程序内导航时,您始终取消Runnable,但如果未激活来自您应用程序的其他活动,则将调用Runnable。
I used this to logout user when he lefts my app, here's code for callbacks:
当我把我的应用程序留给用户时,我用这个来注销用户,这里是回调代码:
public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {
private Handler handler;
private Runnable runLogout = new Runnable() {
@Override
public void run() {
//logoutUser()
}
};
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
handler = new Handler(getMainLooper());
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
handler.removeCallbacks(runLogout);
}
@Override
public void onActivityStarted(Activity activity) {
handler.removeCallbacks(runLogout);
}
@Override
public void onActivityResumed(Activity activity) {
handler.removeCallbacks(runLogout);
}
@Override
public void onActivityPaused(Activity activity) {
handler.postDelayed(runLogout, 1000);
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
However, Runnable
will run not in the context of activity lifecycle, so to use this in activity you would need to set and check some application-wide flag or broadcast an intent.
但是,Runnable不会在活动生命周期的上下文中运行,因此要在活动中使用它,您需要设置并检查某些应用程序范围的标记或广播意图。
#3
9
The onUserLeaveHint is called according to the documentation when the user clicks the home button OR when something interrupts your application (like an incoming phone call) so to guess which it is you use the onUserInteraction method to stamp the last user interaction time.
当用户单击主页按钮或某些内容中断您的应用程序时(例如来电),根据文档调用onUserLeaveHint,以便猜测您使用onUserInteraction方法标记最后一个用户交互时间。
Just a small correction to the answer Idistic gave - OnUserLeaveHint() is not called when your activity is interrupted by an incoming call. Here is the snippet from Android documentation -
只是对Idistic给出的答案进行了一个小的修正 - 当您的活动被来电中断时,不会调用OnUserLeaveHint()。以下是Android文档的片段 -
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.
当活动即将作为用户选择的结果进入后台时,被称为活动生命周期的一部分。例如,当用户按下Home键时,将调用onUserLeaveHint(),但是当传入的电话呼叫导致调用中的Activity自动被带到前台时,onUserLeaveHint()将不会被调用的活动被调用。
#4
0
Yes, check the lifecycle of the app - when a user minimizes or leaves a couple of methods get called onPause() onStop() and onDestroy()
是的,检查应用程序的生命周期 - 当用户最小化或离开几个方法时,调用onPause()onStop()和onDestroy()
http://developer.android.com/reference/android/app/Activity.html
#5
-1
another option that you might consider is to check for the back button or home key press. This is done by overriding the onKeyDown() , listen for the back key/home key and override the default behaviour.
您可能考虑的另一个选项是检查后退按钮或主页按键。这是通过重写onKeyDown(),侦听后退键/ home键并覆盖默认行为来完成的。
I've found a similar question that might help you out.
我发现了一个类似的问题可能对你有所帮助。
Android: Prompt user to save changes when Back button is pressed
Android:按下后退按钮时提示用户保存更改
Cheers
#1
18
If your activity is the last in the stack then detecting a back button with onKeyDown would solve 1/2 of this
如果您的活动是堆栈中的最后一个,那么使用onKeyDown检测后退按钮将解决其中的1/2
The home key is a little trickier, there is no absolute method but you could do something like this which works for my simple needs.
主键有点棘手,没有绝对的方法,但你可以做这样的事情,适合我的简单需求。
The onUserLeaveHint is called according to the documentation when the user clicks the home button OR when something interrupts your application (like an incoming phone call) so to guess which it is you use the onUserInteraction method to stamp the last user interaction time.
当用户单击主页按钮或某些内容中断您的应用程序时(例如来电),根据文档调用onUserLeaveHint,以便猜测您使用onUserInteraction方法标记最后一个用户交互时间。
Now if that precedes the onUserLeaveHint closely enough you can assume (not guaranteed but has worked for me so far) that the home button was the reason your application is being pushed into the background (exiting)
现在,如果它在onUserLeaveHint之前足够紧密,你可以假设(不保证但到目前为止对我有用)主页按钮是你的应用程序被推入后台的原因(退出)
Not sure what your intent is in catching the home button, anyway here is a simplistic way to do that, I use a 100ms fence around the two events which I have found has always worked for me. NOTE: I have only tested on a handful of phones, like all things in Android your mileage will vary dependent on OS / Hardware (heck even the stuff that's documented and supposed to work sometimes doesn't)
不知道你在捕捉主页按钮的意图是什么,无论如何这里是一个简单的方法,我使用100ms围栏围绕这两个事件我发现一直为我工作。注意:我只测试过一些手机,就像Android中的所有东西一样,你的里程数会因操作系统/硬件的不同而有所不同(即使是有记录的,有时也不应该工作的东西)
long userInteractionTime = 0;
@Override
public void onUserInteraction() {
userInteractionTime = System.currentTimeMillis();
super.onUserInteraction();
Log.i("appname","Interaction");
}
@Override
public void onUserLeaveHint() {
long uiDelta = (System.currentTimeMillis() - userInteractionTime);
super.onUserLeaveHint();
Log.i("bThere","Last User Interaction = "+uiLag);
if (uiDelta < 100)
Log.i("appname","Home Key Pressed");
else
Log.i("appname","We are leaving, but will probably be back shortly!");
}
#2
24
Note: This only works if your target is >= API14
You can also use Application.registerActivityLifecycleCallbacks() and when any activity pauses post a delayed Runnable
(that will invoke when user lefts app) to Handler
. When activities are created/started/resumed you remove that Runnable
from Handler
. So when you navigate inside your app you always cancel that Runnable
, but if another activity not from your app is activated - the Runnable
will be invoked.
您还可以使用Application.registerActivityLifecycleCallbacks(),并在任何活动暂停时将延迟的Runnable(将在用户左侧应用程序时调用)发布到Handler。创建/启动/恢复活动时,从Handler中删除该Runnable。因此,当您在应用程序内导航时,您始终取消Runnable,但如果未激活来自您应用程序的其他活动,则将调用Runnable。
I used this to logout user when he lefts my app, here's code for callbacks:
当我把我的应用程序留给用户时,我用这个来注销用户,这里是回调代码:
public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {
private Handler handler;
private Runnable runLogout = new Runnable() {
@Override
public void run() {
//logoutUser()
}
};
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
handler = new Handler(getMainLooper());
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
handler.removeCallbacks(runLogout);
}
@Override
public void onActivityStarted(Activity activity) {
handler.removeCallbacks(runLogout);
}
@Override
public void onActivityResumed(Activity activity) {
handler.removeCallbacks(runLogout);
}
@Override
public void onActivityPaused(Activity activity) {
handler.postDelayed(runLogout, 1000);
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
However, Runnable
will run not in the context of activity lifecycle, so to use this in activity you would need to set and check some application-wide flag or broadcast an intent.
但是,Runnable不会在活动生命周期的上下文中运行,因此要在活动中使用它,您需要设置并检查某些应用程序范围的标记或广播意图。
#3
9
The onUserLeaveHint is called according to the documentation when the user clicks the home button OR when something interrupts your application (like an incoming phone call) so to guess which it is you use the onUserInteraction method to stamp the last user interaction time.
当用户单击主页按钮或某些内容中断您的应用程序时(例如来电),根据文档调用onUserLeaveHint,以便猜测您使用onUserInteraction方法标记最后一个用户交互时间。
Just a small correction to the answer Idistic gave - OnUserLeaveHint() is not called when your activity is interrupted by an incoming call. Here is the snippet from Android documentation -
只是对Idistic给出的答案进行了一个小的修正 - 当您的活动被来电中断时,不会调用OnUserLeaveHint()。以下是Android文档的片段 -
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.
当活动即将作为用户选择的结果进入后台时,被称为活动生命周期的一部分。例如,当用户按下Home键时,将调用onUserLeaveHint(),但是当传入的电话呼叫导致调用中的Activity自动被带到前台时,onUserLeaveHint()将不会被调用的活动被调用。
#4
0
Yes, check the lifecycle of the app - when a user minimizes or leaves a couple of methods get called onPause() onStop() and onDestroy()
是的,检查应用程序的生命周期 - 当用户最小化或离开几个方法时,调用onPause()onStop()和onDestroy()
http://developer.android.com/reference/android/app/Activity.html
#5
-1
another option that you might consider is to check for the back button or home key press. This is done by overriding the onKeyDown() , listen for the back key/home key and override the default behaviour.
您可能考虑的另一个选项是检查后退按钮或主页按键。这是通过重写onKeyDown(),侦听后退键/ home键并覆盖默认行为来完成的。
I've found a similar question that might help you out.
我发现了一个类似的问题可能对你有所帮助。
Android: Prompt user to save changes when Back button is pressed
Android:按下后退按钮时提示用户保存更改
Cheers