如何知道我的Android应用程序是否可见?

时间:2011-07-27 15:49:12

标签: android background foreground

我有一个计时器,当它结束时会启动通知。但我想仅在应用程序当前不可见的情况下使用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 个答案:

答案 0 :(得分:25)

  

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

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

Here is a blog post概述了这项技术。

更新2018-01-04 :上述方法有效,但涉及系统广播,对于大多数(单进程)应用来说,这不是一个很好的选择。可以使用事件总线(LocalBroadcastManager,greenrobot的EventBus),具有更好的性能和安全性。请参阅this sample app that uses LocalBroadcastManagerthis 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)

以下是解决方案:

&#13;
&#13;
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;
&#13;
&#13;

编辑:如果要查看特定活动(班级),请使用此项;

&#13;
&#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;
&#13;
&#13;

在您的清单档案中:

&#13;
&#13;
 <activity android:name=".PINSayfasi"
            android:process=":PIN"></activity>
&#13;
&#13;
&#13;

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