我有一个计时器,当它结束时会启动通知。但我想仅在应用程序当前不可见的情况下使用notificationManager发出通知,并在应用程序处于前台时显示计时器结束时显示alertDialog。
我已经尝试过这个:
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;
}
}
}
但似乎应用程序是否为前景并不重要。我怎么能这样做?
答案 0 :(得分:25)
但我想仅在应用程序当前不可见的情况下使用notificationManager发出通知,并在应用程序处于前台时显示计时器结束时显示alertDialog。
使用有序广播,如果活动位于前台,则活动具有高优先级接收器,如果不在前台,则使用清单注册接收器。
Here is a blog post概述了这项技术。
更新2018-01-04 :上述方法有效,但涉及系统广播,对于大多数(单进程)应用来说,这不是一个很好的选择。可以使用事件总线(LocalBroadcastManager
,greenrobot的EventBus),具有更好的性能和安全性。请参阅this sample app that uses LocalBroadcastManager
和this sample app that uses greenrobot's EventBus,两者都实现了这种模式。
答案 1 :(得分: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方法。它更优雅。
答案 2 :(得分:0)
我建议你在这种情况下使用Service而不是活动。
服务在后台运行,如果正确启动,则不受活动生命周期的影响。
要记住的一件重要事情是,当您返回UI时,服务必须显式调用UI线程,否则您将获得ANR错误,因为UI线程不是线程安全的。
请仔细阅读该文档,它可以帮助您更好地解决您尝试做的事情!
希望这有帮助
答案 3 :(得分:-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");
}
&#13;
编辑:如果要查看特定活动(班级),请使用此项;
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;
}
}
&#13;
在您的清单档案中:
<activity android:name=".PINSayfasi"
android:process=":PIN"></activity>
&#13;
所以主要的逻辑是开放和阅读过程。