The only thing I can think of is checking whether the service's process importance indicates that it's running a foreground service or the foreground activity:
private boolean isForegroundOrForegroundService() {
//Equivalent of RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE on API 23
//On prior versions to API 23, maybe the OS just uses 100 as foreground service importance?
int IMPORTANCE_FOREGROUND_SERVICE = 125;
return findThisProcess().importance <= IMPORTANCE_FOREGROUND_SERVICE;
}
private ActivityManager.RunningAppProcessInfo findThisProcess() {
List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo proc : runningAppProcesses)
if (proc.pid == Process.myPid())
return proc;
throw new RuntimeException("Couldn't find this process");
}
For this to work, there are a few constraints:
- The service must be the only service in the process that tries to run in the foreground since otherwise you won't know which service caused the process to enter foreground mode.
- There mustn't be any activities that run in the same process since having an activity open also causes the process to enter foreground mode.
- Nothing else must be able to make the process enter foreground mode other than the service itself for the same reasons as above.
So you'll probably want to put the service in its own dedicated process. Unfortunately, this makes your app structure difficult since multi-process app development is a lot more complicated than single-process.
Note that this is mostly just theory; I haven't tested this much or used it in any real-world applications. Let me know how it goes if you pursue this approach.