2011-07-27 45 views
18

我有一個計時器,它在結束時開始通知。但是我想僅在應用程序當前不可見的情況下使用notificationManager觸發通知,並且在應用程序處於前臺時計時器結束時顯示alertDialog。如何知道我的android應用是否可見?

我已經嘗試過這一點:

ActivityManager actMngr = (ActivityManager) ValeoMobileApplication.getContext().getSystemService(Activity.ACTIVITY_SERVICE); 
List<RunningAppProcessInfo> runningAppProcesses = actMngr.getRunningAppProcesses(); 
Tools.log("TimerBroadcastReceiver", "onReceive", "All running processes are listed below :"); 
for (RunningAppProcessInfo pi : runningAppProcesses) { 
    //Check pi.processName and do your stuff 
    //also check pi importance - check if process is in foreground or background 
    Tools.log("TimerBroadcastReceiver", "onReceive", pi.processName + " importance = "+pi.importance); 
    if(pi.processName.equalsIgnoreCase("MY_APP_PROCESS_NAME")){ 
     if (pi.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { 
      isApplicationInForeground = true; 
     } 
    } 
} 

但似乎如果應用程序是前景或沒有也沒關係。我怎樣才能做到這一點?

回答

25

但我想火用notificationManager只有當應用程序當前不可見的通知,如果計時器結束而應用程序是在前臺顯示的alertDialog。

使用有序廣播,如果活動位於前臺,則該活動具有高優先級接收者,如果該活動不在前臺,則使用清單註冊的接收者。

Here is a blog post概述了這種技術。

UPDATE 2018-01-04:上述方法可行,但涉及系統廣播,對大多數(單進程)應用來說這不是一個好選擇。一個事件總線(LocalBroadcastManager,greenrobot的EventBus)可以用來代替,具有更好的性能和安全性。見this sample app that uses LocalBroadcastManagerthis sample app that uses greenrobot's EventBus,這兩者的實現這種模式。

+0

謝謝,這就是我一直在尋找的! – PhilippeAuriach

+3

如果您的主要活動正在啓動另一項新活動,則這不起作用。那時,由於onPause被觸發,取消註冊將會發生。但是,從最終用戶的角度來看,該應用程序仍然可見。 –

+0

據我所知,這種方法不再適用於Android Oreo。因爲不可能通過manifest來註冊隱式接收器。 – MyDogTom

0

我會建議你使用Service,而不是在這種情況下的活動。

服務在後臺運行,並且如果正確啓動不受活動的生命週期。記住

一個重要的事情是,當你回到UI,服務必須顯式調用UI線程,否則你將得到ANR錯誤,作爲UI線程不是線程安全的。

請通過文檔閱讀,它應該幫助你得到你想要做一個更好的解決方案!

希望這有助於

10

您可以檢測到您的應用程序是否可見或不可見以下方式:

在你一切你Activity,設爲:

@Override 
protected void onResume() { 
    super.onResume(); 

    myVisibilityManager.setIsVisible(true); 
} 

@Override 
protected void onPause() { 
    myVisibilityManager.setIsVisible(false); 

    super.onPause(); 
} 

(這可能會導致你定義一個超類中所有活動這將實現這一行爲)

然後創建一個VisibilityManager(這是一個非常基本的,你可能需要一些更高級):

public class VisibilityManager { 
    private boolean mIsVisible = false; 

    public void setIsVisible(boolean visible) { 
     mIsVisible = visible; 
    } 

    public boolean getIsVisible() { 
     return mIsVisible; 
    } 
} 

,然後在你的計時器線程,當倒數到零:

if (VisibilityManager.getIsVisible()) { 
    showAlertDialog(); 
} 
else { 
    showNotification(); 
} 

編輯:但我甚至寧願在這個頁面在這裏描述的CommonsWare的做法。它更優雅。如果

getIntent()

返回null您的活動

+0

CommonsWare的方法很聰明和有趣。但是,這種方法非常簡單。我們可能想知道應用程序是否在其他地方的前臺。所以我選擇了這個。 – rpattabi

+0

VisibilityManager中的方法和var應該是靜態的 – Lester

+0

@Lester哦,是的,這是對的謝謝。 – Shlublu

-2

是不是在前臺。

-1

這裏是解決方案:

public static boolean uygulamaCalisiyormu(Context context) 
 
    { 
 
     ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
 
     List<ActivityManager.RunningAppProcessInfo> islemler = activityManager.getRunningAppProcesses(); 
 
     for (ActivityManager.RunningAppProcessInfo uygulamaIslemi : islemler) 
 
     { 
 
      if (uygulamaIslemi.processName.equals(context.getPackageName())) 
 
      { 
 
       if (uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE || uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) 
 
       { 
 
        return true; 
 
       } 
 
      } 
 
     } 
 
     return false; 
 
    } 
 

 

 
... 
 
if (uygulamaCalisiyormu(getApplicationContext())) 
 
     { 
 
      Log.d("asd","App Already Started"); 
 
     } 
 
     else 
 
     { 
 
Log.d("asd","App Started"); 
 
}

編輯:如果您想查詢的特定活動(類)使用;

if (uygulamaIslemi.processName.equals("com.TRSoft.timetab:PIN")) 
 
      { 
 
       if (uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE || uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) // Lanet olasıca şey Visible ile Foreground arasındaki fark ne oç illaha ya da yı kullanarak olduğunu keşfetmem mi lazım! 
 
       { 
 
        return true; 
 
       } 
 
      }

而在你的清單文件:

<activity android:name=".PINSayfasi" 
 
      android:process=":PIN"></activity>

所以主要邏輯是打開和讀取過程。

相關問題