2011-04-08 29 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! 
     } 
    } 
} 
相關問題