[英]Problems with activity lifecycle (How to detect if activity is in foreground)
[英]How to detect application runs foreground or background using Single Activity or Java class
我想将报告发送到服务器,这意味着用户在一天内要使用该应用程序多长时间。
@Override
protected void onResume() {
super.onResume();
//commonclassMethod.getInstance(UserForground);
}
@Override
protected void onStop() {
super.onStop();
//commonclassMethod.getInstance(UserBackground);
}
发生什么情况,我需要在每个活动中调用此方法。
我需要的是,是否有可能在单个Java类或活动中找到用户forground
background
方法。
提前致谢。
您可以通过在扩展Application类的类中添加isAppIsInBackground(Context context)方法来实现此目的。
在该类中定义该方法:
public static boolean isAppIsInBackground(Context context) {
boolean isInBackground = true;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
for (String activeProcess : processInfo.pkgList) {
if (activeProcess.equals(context.getPackageName())) {
isInBackground = false;
}
}
}
}
} else {
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (componentInfo.getPackageName().equals(context.getPackageName())) {
isInBackground = false;
}
}
return isInBackground;
}
如果应用程序在后台,则为true
或者另一种更好的方法是在BaseActivity的重写方法中,通过BaseActivity扩展每个Activity
protected void onResume() {
super.onResume();
//commonclassMethod.getInstance(UserForground);
}
protected void onStop() {
super.onStop();
//commonclassMethod.getInstance(UserBackground);
}
您可以实现回调方法来解决您的情况。
例如:
首先创建一个接口,然后定义一个方法,该方法将用作回调。 在此示例中,我们将有两个类,一个类A和另一个类B
接口:
public interface OnCustomEventListener{
public void onEvent(); //method, which can have parameters
}
classB中的侦听器本身(我们仅在classB中设置侦听器)
私人OnCustomEventListener mListener; //侦听器字段
//setting the listener
public void setCustomEventListener(OnCustomEventListener eventListener) {
this.mListener=eventListener;
}
在classA中,我们如何开始侦听classB必须告诉的一切
classB.setCustomEventListener(new OnCustomEventListener(){
public void onEvent(){
//do whatever you want to do when the event is performed.
}
});
我们如何从classB触发事件(例如,按下按钮时)
if(this.mListener!=null){
this.mListener.onEvent();
}
创建一个扩展类的应用程序,并使用registerActivityLifecycleCallbacks()获取活动生命周期
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
if(activity.getClass().getSimpleName().equalsIgnoreCase(MainActivity.class.getSimpleName())){
//Do the required thing here
}
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
}
也不要忘记在清单中注册活动
<application
android:name=".MyApp"
您有两个选择。
1)做一个抽象的BaseActivity并使所有Activity对其进行扩展。 这样,您仅在一个BaseActivity中编写代码,并且所有子活动都使用它。
2)使用自定义计数器类来监视应用程序到前台。 如果您要复制它,这是我的实现。
/**
* Created by App Studio 35 on 6/23/17.
*/
public class AppLifeCycleTracker implements Application.ActivityLifecycleCallbacks {;
/*///////////////////////////////////////////////////////////////
// METHODS
*////////////////////////////////////////////////////////////////
private static final String TAG = Globals.SEARCH_STRING + AppLifeCycleTracker.class.getSimpleName();
private static AppLifeCycleTracker INSTANCE;
private static int numActivitiesInMemory = 0;
private ArrayList<IAppToForegroundListener> mAppToForegroundListeners;
private boolean isRefreshing;
private Object lockAccess = new Object();
private AlertDialog mAlertDialog = null;
/*///////////////////////////////////////////////////////////////
// PROPERTIES
*////////////////////////////////////////////////////////////////
private ArrayList<IAppToForegroundListener> getAppToForegroundListeners(){
return mAppToForegroundListeners == null ? mAppToForegroundListeners = new ArrayList<IAppToForegroundListener>() : mAppToForegroundListeners;
}
public boolean getIsRefreshing(){
return isRefreshing;
}
public boolean getAppIsInBackground(){
return numActivitiesInMemory < 1;
}
/*///////////////////////////////////////////////////////////////
// CONSTRUCTOR
*////////////////////////////////////////////////////////////////
private AppLifeCycleTracker(){
}
public synchronized static AppLifeCycleTracker getInstance(){
if(INSTANCE == null){
INSTANCE = new AppLifeCycleTracker();
}
return INSTANCE;
}
/*///////////////////////////////////////////////////////////////
// LIFE CYCLE OVERRIDES
*////////////////////////////////////////////////////////////////
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(final Activity activity) {
//App went into background, so set a flag to avoid loading while we refresh
if(numActivitiesInMemory == 0 && !(activity instanceof SplashScreenActivity) && !(activity instanceof CreateAccountActivity)){
A35Log.v(TAG, "App Returned to Foreground, refreshing Token");
//first load on splash it goes from 0 to 1 so hold off on splash
synchronized (lockAccess) {
isRefreshing = true;
}
if (DeviceInfo.getInstance(activity).getIsConnectedToInternet()) {
CognitoManager.refreshToken(activity, new GenericHandler() {
@Override
public void onSuccess() {
A35Log.v(TAG, "Token Refresh Complete, notifying listeners");
//we are good, keep going
for(IAppToForegroundListener listener : getAppToForegroundListeners()){
listener.onRefreshTokenComplete();
}
synchronized (lockAccess) {
isRefreshing = false;
}
}
@Override
public void onFailure(Exception exception) {
//boot them to login screen
if(activity instanceof LoginActivity || activity instanceof SplashScreenActivity){
return;
}
startLoginActivity(activity);
synchronized (lockAccess) {
isRefreshing = false;
}
}
});
} else {
showInternetRequiredDialog(activity);
}
}
numActivitiesInMemory++;
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
numActivitiesInMemory--;
//if numActivities == 0 then you are in the background
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
/*///////////////////////////////////////////////////////////////
// METHODS
*////////////////////////////////////////////////////////////////
public void addAppToForegroundListener(IAppToForegroundListener listener){
getAppToForegroundListeners().add(listener);
}
public void removeAppToForegroundListener(IAppToForegroundListener listener){
getAppToForegroundListeners().remove(listener);
}
private void startLoginActivity(final Activity activity){
((AMApplication) activity.getApplication()).logoutCurrentUser(activity, false, false, null, true, null);
}
/*///////////////////////////////////////////////////////////////
// INTERFACES
*////////////////////////////////////////////////////////////////
public interface IAppToForegroundListener {
/*///////////////////////////////////////////////////////////////
// METHODS
*////////////////////////////////////////////////////////////////
void onRefreshTokenComplete();
}
private void showInternetRequiredDialog(Activity activity){
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("Error").setMessage("Internet is required to use this app").setNegativeButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(mAlertDialog != null && mAlertDialog.isShowing()) {
mAlertDialog.dismiss();
}
}
});
mAlertDialog = builder.create();
mAlertDialog.show();
}
}
当然,这样做的作用比您要查找的要多,因为我的管理使用cognito刷新了令牌,并在从后台返回时强制刷新,以及诸如此类的事情,因此,无需理会。 但是其余的还是一样。 希望能有所帮助。
我假设您不需要BaseActivity的示例,因此我不会通过粘贴它来光顾您。
在应用程序类中启动
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(AppLifeCycleTracker.getInstance());
}
然后,仅当应用程序处于活动或片段级别处于前台或后台时,才需要从BaseActivity或BaseFragment访问即可。 对于您的情况,情况并非如此。
但是,如果您想使用它,只需执行以下操作:
@Override
public void onAttach(Context context) {
super.onAttach(context);
AppLifeCycleTracker.getInstance().addAppToForegroundListener(this);
}
@Override
public void onDetach() {
super.onDetach();
AppLifeCycleTracker.getInstance().removeAppToForegroundListener(this);
}
但是,我必须再次强调,仅当您希望让您的活动或片段知道应用何时返回前台以强制刷新或其他行为时,此部分才是。 如果使用Activity,则将onDetach替换为onDestroy,但是对于您的方案,您可以跳过整个代码的最后一部分,不需要它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.