2011-04-08 28 views
26

我有一个Android应用程序,它将一些数据发送到web服务。我需要在应用程序关闭或发送到后台后立即发送此数据。但是,我该如何完成此操作?当Android应用程序关闭/发送到后台时运行代码

我目前的解决方案是在我的家庭活动的OnPause()上运行它,但我需要这个来运行,无论用户在关闭应用程序时使用哪个活动。这是可能的还是必须添加所有活动的OnPause方法?

+0

我觉得服务进行长期操作,当用户退出应用程序启用。 – Utopia 2016-12-14 09:44:05

回答

21

编辑

这个答案只会为了一个目的,那就是,在运行一个onPause()代码的所有活动。它不会让您在应用程序发送到后台时运行代码。

原来的答案

制作名为YourBasicActivity的活动并覆盖其onPause()方法和YourBasicActivity

+1

嗯。这是一个很好的建议:)但我有我的应用程序许多不同的活动..如ListActivity ..我怎么做呢? – Herter 2011-04-08 10:24:45

+1

在这种情况下,您必须编写YourListActivity,因为它是'Activity'的特殊形式(如果您使用的是如此多的ListActivity)。 – 2011-04-08 10:29:30

+19

但是,当我们从一个活动切换到另一个时,onPause()也被调用就在应用程序关闭或发送到后台时。 – peceps 2011-06-15 11:03:27

0

覆盖扩展的每个活动的主页活动onStop()方法和运行代码出现。

0

我想你需要运行你自己的线程,它会检查所有正在运行的活动是否在后台或被销毁。

MyBasicActivity extends Activity 
{ 
    private static ArrayList<MyBasicActivity> activities=new ArrayList<MyBasicActivities); 
    private boolean started; 

    public void onCreate() 
    { 
     activities.add(this); 
    } 

    public void onDestroy() 
    { 
     activities.remove(this); 
    } 

    public void onStart() 
    { 
     this.started=true; 
    } 

    public void onPause() 
    { 
     this.started=false; 
    } 

    public boolean isStarted() 
    { 
     return started; 
    } 
} 

MyThread implements Runnable 
{ 
    private ArrayList<MyBasicActivity> activities; 

    public MyThread(ArrayList<MyBasicActivity> activities) 
    { 
     this.activities=activities; 
    } 

    void run() 
    { 
      while(!stopped) 
      { 
       boolean inBackground=true; 
       for(MyBasicActivity activity:activities) 
       { 
       if(activity.isStarted()) 
       { 
         inBackground=false; 
         break; 
       } 
       } 
       if(inBackground) 
        //run your code here; 
       sleep(10000); //10 secs 
      } 

    } 
} 
27

检查该解决方案首次您决定使用下面的代码之前https://stackoverflow.com/a/5862048/1037294


要检查,如果你的应用程序发送到后台,你可以在你的应用程序调用上onPause()onStop()此代码对每一个活动:

/** 
    * Checks if the application is being sent in the background (i.e behind 
    * another application's Activity). 
    * 
    * @param context the context 
    * @return <code>true</code> if another application will be above this one. 
    */ 
    public static boolean isApplicationSentToBackground(final Context context) { 
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    List<RunningTaskInfo> tasks = am.getRunningTasks(1); 
    if (!tasks.isEmpty()) { 
     ComponentName topActivity = tasks.get(0).topActivity; 
     if (!topActivity.getPackageName().equals(context.getPackageName())) { 
     return true; 
     } 
    } 

    return false; 
    } 

对于这个工作你应该包括这个你AndroidManifest.xml

<uses-permission android:name="android.permission.GET_TASKS" /> 
+0

是不是有一个事件允许接收器做到这一点? – StErMi 2012-03-27 07:29:21

+0

这里有一个问题。这并不能保证该应用程序在后台。该应用程序仍可能正在运行,因此am.getRunningTasks()可能会将您的应用程序作为正在运行的应用程序返回。在这种情况下,此方法将返回false。 从他们的文档: 请注意,“运行”并不意味着任何任务的代码当前已加载或活动 - 该任务可能已被系统冻结,以便在下一次带入时可以重启以前的状态到前台。 更多信息:http://developer.android.com/reference/android/app/ActivityManager.html#getRecentTasks(int,int) – RPM 2012-12-21 22:27:48

+0

我通过调用onStop() – RPM 2012-12-22 00:24:05

2

也许这可以是有益的,告诉我,如果它为你工作。 只有当您从后台返回时,活动的值将为0(零) 其余时间将是执行onRestart() 时高于0(零)的数字。

public class FatherClass extends Activity { 

private static int activities = 0; 

public void onCreate(Bundle savedInstanceState, String clase) { 
    super.onCreate(savedInstanceState); 
} 

protected void onRestart() 
{ 
    super.onRestart(); 
    if(activities == 0){ 
     Log.i("APP","BACK FROM BACKGROUND"); 
    } 
} 

protected void onStop(){ 
    super.onStop(); 
    activities = activities - 1; 
} 

protected void onStart(){ 
    super.onStart(); 
    activities = activities + 1; 
} 

} 

所有的类都必须从这个类中延伸才能工作。

说明:本在onStart执行一个活动是“看得见”和的onStop当活动是“不可见”。所以当你的APP(它表示APP不活动)进入后台时,所有的活动都是“不可见的”,因此他们执行onStop方法,所以这个想法背后是ADD ONE每次活动开始时,SUBTRACT ONE每次活动都隐藏起来,所以如果变量“activities”的值为零,这意味着在某个点开始的所有活动现在都不可见,所以当您从后台返回并执行onRestart方法在“front”中的活动中,您可以检查是否来自后台或正在重新启动活动。

19

这是我使用的方法,它似乎工作得很好:

我有一个顶层应用程序类我自己的扩展应用这样

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks { 

您还需要注册此应用程序对象在您的清单文件中:

<application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:name=".MyApplication"> 

请注意我是如何实现ActivityLifeCycleCallbacks接口的。这个接口有以下方法:

public static interface ActivityLifecycleCallbacks { 
    void onActivityCreated(android.app.Activity activity, android.os.Bundle bundle); 

    void onActivityStarted(android.app.Activity activity); 

    void onActivityResumed(android.app.Activity activity); 

    void onActivityPaused(android.app.Activity activity); 

    void onActivityStopped(android.app.Activity activity); 

    void onActivitySaveInstanceState(android.app.Activity activity, android.os.Bundle bundle); 

    void onActivityDestroyed(android.app.Activity activity); 
} 

您需要实现这些方法,然后注册为您的应用程序,这些活动的onCreate()如下

@Override 
public void onCreate() { 
    super.onCreate(); 
    registerActivityLifecycleCallbacks(this); 
} 

然后,这将调用回调函数(在所有MyApplication对象)每当一个活动的生命周期方法发生如的onCreate(),在onPause等 在你onActivityPaused(),那么你可以检查,如果应用程序通过调用@peceps方法后台或不:isApplicationSentToBackground(...)

这是我的代码看起来像那么......

/** 
* Application.ActivityLifecycleCallbacks methods 
*/ 
@Override 
public void onActivityCreated(Activity activity, Bundle bundle) { 

} 

@Override 
public void onActivityStarted(Activity activity) { 
} 

@Override 
public void onActivityResumed(Activity activity) { 
} 

@Override 
public void onActivityStopped(Activity activity) { 
    try { 
     boolean foreground = new ForegroundCheckTask().execute(getApplicationContext()).get(); 
     if(!foreground) { 
      //App is in Background - do what you want 
     } 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
public void onActivityPaused(Activity activity) { 
} 

@Override 
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { 
} 

@Override 
public void onActivityDestroyed(Activity activity) { 
} 

创建一个新类去检查前景(这是一个异步。任务)。有关更多信息,请参阅check android application is in foreground or not?

class ForegroundCheckTask extends AsyncTask<Context, Void, Boolean> { 
    @Override 
    protected Boolean doInBackground(Context... params) { 
     final Context context = params[0]; 
     return isAppOnForeground(context); 
    } 

    private boolean isAppOnForeground(Context context) { 
     ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
     List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); 
     if (appProcesses == null) { 
      return false; 
     } 
     final String packageName = context.getPackageName(); 
     for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { 
      if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 
+0

你仍然需要在API 14提供的清单 – RPM 2012-12-21 19:32:16

+1

中使用 - 很好的解决方案 – 2012-12-24 21:19:58

+1

伟大的解决方案!当应用程序转到后台时(onPause),我需要获取Activity,并且这个工作就像一个魅力一样。谢谢 – Pablo 2017-06-21 21:19:36

0

您可以使用应用程序时是打开的,当你的应用进来前景/背景closed.this方法只叫其称之为onAppForegroundStateChange()方法。 onAppForegroundStateChange()方法比使用onPause()方法更好,因为每次当您转到其他活动时,也会调用onPause方法。

您可以使用此方法类似

public class MyApplication extends Application { 
    @Override 
    public void onCreate() { 
     super.onCreate(); 
     AppForegroundStateManager.getInstance().addListener(this); 
    } 

    @Override 
    public void onAppForegroundStateChange(AppForegroundStateManager.AppForegroundState newState) { 
     if (AppForegroundStateManager.AppForegroundState.IN_FOREGROUND == newState) { 
      // App just entered the foreground. Do something here! 
     } else { 
      // App just entered the background. Do something here! 
     } 
    } 
} 
相关问题