2012-12-26 83 views
3

檢測應用程序是否處於前景的原因有很多。例如,作爲GCM/C2DM推送通知的觸發器,很多應用程序在執行應用程序前臺和後臺的不同行爲時都會有很好的理由。 其他原因可能是 - 打擊耗費寶貴資源的服務,例如查詢後臺任務中的服務器。確定是否在前臺應用程序 - 是否皺眉?

只要是明確的:定義(在我看來)的後臺程序是
應用程序,它沒有它的活動被調用的方法onStart(),卻沒有援引onStop()方法。這是因爲活動僅在當時在其生命週期中對用戶可見。

從另一方面 -

  • 似乎是谷歌不希望應用到home鍵的反應(這不是API的一部分)

  • 反應到onBackPressed()上「根/主「活動作爲離開的指示器Activity當然不是好主意(因爲很多用戶使用主頁按鈕,而不是後退按鈕)

  • API中沒有方法允許de termine如果應用程序是前景(根據我的定義..)

,如果我沒有錯過API的東西,它是真正的情況 - 爲什麼沒有爲什麼容易確定該應用程序是前景還是沒有???? !!!!

什麼,我知道我可以做以確定是否前臺的應用在這個線程描述 - How to detect when an Android app goes to the background and come back to the foreground

但@Emil說 - 它需要特殊的權限,或者需要一些棘手的邏輯的,其速度非常快成爲問題保持,它聞起來像壞的做法(雖然這是我在做什麼,現在,因爲我沒有更好的主意......)

我的問題基本上都是

  • 有沒有這樣的API方法從好的理由?

  • 考慮到應用程序是否爲前景是一種不好的方法?

  • 是否有任何其他方式知道應用程序是否爲前景?

回答

5

是考慮到如果應用前景與否是個不錯的辦法?

考慮前景與背景是合理的。

是否有任何其他方式知道應用程序是否爲前景?

可以大致可分爲這樣的場景分成兩組:要在在前臺/後臺狀態的變化立即採取行動

  1. 案件

  2. 的包裝箱一些其他事件發生(AlarmManager報警,傳入的系統廣播等),並在此時根據您是否處於前景採取不同的行動

在前一種情況下,onUserLeaveHint()是您最可靠的簡單選項。例如,我不能保證它會覆蓋所有情況,但它應該處理HOME情景。您也歡迎您在靜態數據成員中維護已啓動活動的引用計數,並嘗試使用它。

在後一種情況下,ordered broadcast可能會有用。

+0

你的回答確實在我的腦海中有所作爲......我沒有想到將有序廣播作爲第二種情況的解決方案。對於這種情況看起來很完美。關於第一種情況 - 我不熟悉 - onUserLeaveHint()方法。很高興知道它存在,但正如你所說 - 它仍然沒有涵蓋所有..靜態變量表明開始和不停止的活動的數量是我在做什麼,並猜測在你的建議後,我將與此生活在一起解決方案沒有感覺它這樣一個不好的解決方案.. :) –

0

我有同樣的問題。我想在我的活動不處於前景模式時顯示推送通知。請通過下面的代碼,你會得到你的答案。

Context ctx = context.getApplicationContext(); 

    ActivityManager am = (ActivityManager) context 
      .getSystemService(ACTIVITY_SERVICE); 

    // get the info from the currently running task 
    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); 

    PackageManager pm = this.getPackageManager(); 

    try { 
     /** 
     * take fore ground activity name 
     */ 
     ComponentName componentInfo = taskInfo.get(0).topActivity; 
     if (printLog == true) { 
      Log.d("Home", "CURRENT Activity ::" 
        + taskInfo.get(0).topActivity.getClassName()); 
      Log.d("Home", "Number Of Activities : " 
        + taskInfo.get(0).numRunning); 
      Log.d("Home", 
        "Componenet Info : " + componentInfo.getPackageName()); 
      Log.d("Home", 
        "Componenet Info : " + componentInfo.getClassName()); 
     } 
     /** 
     * All activities name of a package to compare with fore ground 
     * activity. if match found, no notification displayed. 
     */ 
     PackageInfo info = pm.getPackageInfo(
       "<PackageName>", 
       PackageManager.GET_ACTIVITIES); 
     ActivityInfo[] list = info.activities; 

     for (int i = 0; i < list.length; i++) { 
       Log.d("TAG","Activity : "+list[i].name); 
     } 

    } catch (NameNotFoundException e) { 
     e.printStackTrace(); 
    } 

要利用這一點,你必須採取許可,您manifest文件。

使用許可權的android:NAME = 「android.permission.GET_TASKS」

請原諒我,如果我不能得到你的問題。

+0

感謝您的答案,但我附加了一個鏈接到另一個職位,顯示該答案作爲我已經知道abot。你可以在問題的主體中看到它.. –

0

如果你需要知道應用程序是在背景上運行的服務的背景還是前景(否則沒有意義),那麼你可以使用綁定,即 - 綁定到它上所有活動onResume,並解除所有活動onPause。那麼在您的服務中,您不僅可以管理您的應用程序對用戶的可見性,還可以隨時管理哪些活動已打開。它也是防泄漏和穩定的,然後是一個靜態變量(如果需要,可以進行清理),因爲您正在使用android的API並依賴於android操作系統代碼本身的正確性。

相關問題