How to Determine Which Apps Are Background and Which App Is Foreground on iOS by Application Id

how to determine which apps are background and which app is foreground on iOS by application id

Well, looks like some usage of nm and IDA on SpringBoardServices binary from simulator helped me on this.
Following code works on iOS 5.0.1 running on iPod Touch 4, iPhone 4 and iPad1 WiFi(all non-JB)
Of course you should never try to submit that to AppStore

- (NSArray*) getActiveApps
{
mach_port_t *p;
void *uikit = dlopen(UIKITPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() =
dlsym(uikit, "SBSSpringBoardServerPort");
p = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(uikit);

void *sbserv = dlopen(SBSERVPATH, RTLD_LAZY);
NSArray* (*SBSCopyApplicationDisplayIdentifiers)(mach_port_t* port, BOOL runningApps,BOOL debuggable) =
dlsym(sbserv, "SBSCopyApplicationDisplayIdentifiers");
//SBDisplayIdentifierForPID - protype assumed,verification of params done
void* (*SBDisplayIdentifierForPID)(mach_port_t* port, int pid,char * result) =
dlsym(sbserv, "SBDisplayIdentifierForPID");
//SBFrontmostApplicationDisplayIdentifier - prototype assumed,verification of params done,don't call this TOO often(every second on iPod touch 4G is 'too often,every 5 seconds is not)
void* (*SBFrontmostApplicationDisplayIdentifier)(mach_port_t* port,char * result) =
dlsym(sbserv, "SBFrontmostApplicationDisplayIdentifier");



//Get frontmost application
char frontmostAppS[256];
memset(frontmostAppS,sizeof(frontmostAppS),0);
SBFrontmostApplicationDisplayIdentifier(p,frontmostAppS);
NSString * frontmostApp=[NSString stringWithFormat:@"%s",frontmostAppS];
//NSLog(@"Frontmost app is %@",frontmostApp);
//get list of running apps from SpringBoard
NSArray *allApplications = SBSCopyApplicationDisplayIdentifiers(p,NO, NO);
//Really returns ACTIVE applications(from multitasking bar)
/* NSLog(@"Active applications:");
for(NSString *identifier in allApplications) {
// NSString * locName=SBSCopyLocalizedApplicationNameForDisplayIdentifier(p,identifier);
NSLog(@"Active Application:%@",identifier);
}
*/

//get list of all apps from kernel
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t miblen = 4;

size_t size;
int st = sysctl(mib, miblen, NULL, &size, NULL, 0);

struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;

do {

size += size / 10;
newprocess = realloc(process, size);

if (!newprocess){

if (process){
free(process);
}

return nil;
}

process = newprocess;
st = sysctl(mib, miblen, process, &size, NULL, 0);

} while (st == -1 && errno == ENOMEM);

if (st == 0){

if (size % sizeof(struct kinfo_proc) == 0){
int nprocess = size / sizeof(struct kinfo_proc);

if (nprocess){

NSMutableArray * array = [[NSMutableArray alloc] init];

for (int i = nprocess - 1; i >= 0; i--){

int ruid=process[i].kp_eproc.e_pcred.p_ruid;
int uid=process[i].kp_eproc.e_ucred.cr_uid;
//short int nice=process[i].kp_proc.p_nice;
//short int u_prio=process[i].kp_proc.p_usrpri;
short int prio=process[i].kp_proc.p_priority;
NSString * processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid];
NSString * processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm];


BOOL systemProcess=YES;
if (ruid==501)
systemProcess=NO;



char * appid[256];
memset(appid,sizeof(appid),0);
int intID,intID2;
intID=process[i].kp_proc.p_pid,appid;
SBDisplayIdentifierForPID(p,intID,appid);/

NSString * appId=[NSString stringWithFormat:@"%s",appid];

if (systemProcess==NO)
{
if ([appId isEqualToString:@""])
{
//final check.if no appid this is not springboard app
NSLog(@"(potentially system)Found process with PID:%@ name %@,isSystem:%d,Priority:%d",processID,processName,systemProcess,prio);
}
else
{

BOOL isFrontmost=NO;
if ([frontmostApp isEqualToString:appId])
{
isFrontmost=YES;
}
NSNumber *isFrontmostN=[NSNumber numberWithBool:isFrontmost];
NSDictionary * dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName,appId,isFrontmostN, nil]
forKeys:[NSArray arrayWithObjects:@"ProcessID", @"ProcessName",@"AppID",@"isFrontmost", nil]];

NSLog(@"PID:%@, name: %@, AppID:%@,isFrontmost:%d",processID,processName,appId,isFrontmost);
[array addObject:dict];
}
}
}

free(process);
return array;
}
}
}

dlclose(sbserv);
}

Of course 2nd loop is not strictly necessary but I needed non-localized names & PIDs too.

Detect which app is in foreground on iOS9 without jailbreak

Unfortunately, I was looking for a similar solution and have come to the conclusion that, at least at this point in time, there are no known methods that will allow you to determine app usage on iOS. Even the MDM providers such as Good, Airwatch, MobileIron, etc. don't seem to be able to do this. If anyone is able to come up with a solution, I'd love to see it.

For now, however, I think we would have seen a solution if someone had one that worked on the latest iOS.

Detect if the application in background or foreground in swift

[UIApplication sharedApplication].applicationState will return current state of applications such as:

  • UIApplicationStateActive
  • UIApplicationStateInactive
  • UIApplicationStateBackground

or if you want to access via notification see UIApplicationDidBecomeActiveNotification

Swift 3+

let state = UIApplication.shared.applicationState
if state == .background || state == .inactive {
// background
} else if state == .active {
// foreground
}

switch UIApplication.shared.applicationState {
case .background, .inactive:
// background
case .active:
// foreground
default:
break
}

Objective C

UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateBackground || state == UIApplicationStateInactive) {
// background
} else if (state == UIApplicationStateActive) {
// foreground
}


Related Topics



Leave a reply



Submit