18

我有一个计时器,它在结束时启动通知。但我想仅在应用程序当前不可见时使用 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;
        }
    }
}

但似乎应用程序是否在前台并不重要。我怎样才能做到这一点?

4

4 回答 4

26

但我想仅在应用程序当前不可见时使用 notificationManager 触发通知,并在应用程序处于前台时计时器结束时显示 alertDialog 。

使用有序广播,如果活动在前台,则具有高优先级接收器,如果不在前台,则使用清单注册接收器。

这是一篇概述这种技术的博客文章。

更新 2018-01-04:上述方法有效,但它涉及系统广播,这对于大多数(单进程)应用程序来说不是一个很好的选择。LocalBroadcastManager可以改用事件总线( greenrobot 的 EventBus),具有更好的性能和安全性。请参阅使用LocalBroadcastManager这个示例应用程序和这个使用 greenrobot 的 EventBus 的示例应用程序,它们都实现了这个模式。

于 2011-07-27T16:19:37.070 回答
11

您可以通过以下方式检测您的应用是否可见:

在您的所有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 方法。它更优雅。

于 2011-07-27T16:35:22.060 回答
0

在这种情况下,我建议您使用服务而不是活动。

服务在后台运行,如果正确启动,则不受活动生命周期的影响。

需要记住的重要一点是,当您返回 UI 时,服务必须显式调用 UI 线程,否则您将收到 ANR 错误,因为 UI 线程不是线程安全的。

请通读该文档,它应该可以帮助您为您正在尝试做的事情找到更好的解决方案!

希望这有帮助

于 2011-07-27T15:54:53.230 回答
-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>

所以主要的逻辑是打开和阅读过程。

于 2016-06-04T10:35:59.660 回答