问题
when receiving a GCM message, the behaviour of my app depends on if it is in the foreground or not. Prior to API 21 I used the following:
Boolean onForeground = this.getPackageName().equalsIgnoreCase(
((ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE))
.getRunningTasks(1).get(0).topActivity.getPackageName()
);
Now getRunningTasks() is deprecated and behaving differently on API 21, what would be the best way on API 21 to detect if my app is in the foreground?
Google recommends
public ActivityManager.RecentTaskInfo getTaskInfo ()
but I do not see how I can get the information I need from there.
Thank you in advance.
Edit: As proposed by @CommonsWare and @Chris Stratton, I could keep track of onResume/onPause states. A app-crash cause by a WebView (content outside my control) would leave the system in the wrong state. Sending a GCM in such wrong state would cause an other crash confusing the user (he/she is not doing anything at that moment with my app).
I am therefore looking for another solution. (I am using Fragments and only have 1 activity, so implementing this would be trivial)
回答1:
You can use an ordered broadcast approach where you
- Create a
BroadcastReceiver
registered in your manifest which does the background behavior - Dynamically register a
BroadcastReceiver
in your activity with a positive priority (the default is0
), making sure to register it inonStart()
/onResume()
and unregistering it inonStop()
/onPause()
- this does the foreground behavior and should call abortBroadcast() to ensure the manifest registeredBroadcastReceiver
is not called
Your GCM receiver can then use sendOrderedBroadcast() to send a broadcast (preferably with a custom action that both your other BroadcastReceiver
s register for) which will be received by the dynamically registered receiver if it exists and the manifest registered receiver if it does not exist.
回答2:
I detect using getRunningAppProcesses
boolean isOnForeground = true;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH)
{
List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses)
{
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
{
for (String activeProcess : processInfo.pkgList)
{ if(activeProcess.equals(context.getPackageName()))
{
isOnForeground = false;
}
}
}
}
}
else
{
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if(componentInfo.getPackageName().equals(context.getPackageName()))
{
isOnForeground = false;
}
}
来源:https://stackoverflow.com/questions/26456398/how-to-detect-if-your-android-app-is-in-the-foreground-api-21