如何通过应用程序标识确定哪些应用程序是背景和iOS应用程序的前台

前端之家收集整理的这篇文章主要介绍了如何通过应用程序标识确定哪些应用程序是背景和iOS应用程序的前台前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用 this question中描述的方法,我可以得到在iOS设备上运行的应用程序的列表.
我知道PID并访问他们的kinfo_proc结构.
如何确定哪些是前台进程,哪些是背景(假设我的应用程序是背景)?

我试图通过kp_proc.p_priority在kinfo_proc(见第一个链接)中找到这个信息,但是看起来不可能从优先级推断背景/前景状态.

我不太在乎AppStore Review是否正常工作,但我宁愿使用一种无​​越狱的方法(即私有API可以,但是哪些?).我希望这至少在iOS 5上运行

我考虑编写一个简单的MobileSubstrate扩展,将其注入到所有应用程序中,并且只是钩住每个人的applicationDidBecomeActive,但这需要越狱,并且是太侵入性的.

解决方法

那么,看起来像一些使用nm和IDA在SpringBoardServices二进制从模拟器帮助我这个.
以下代码适用于在iPod Touch 4,iPhone 4和iPad1 WiFi(所有非JB)上运行的iOS 5.0.1
当然你也不应该试图把它提交给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,"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,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,process,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,appId,isFrontmostN,nil] 
                                                                            forKeys:[NSArray arrayWithObjects:@"ProcessID",@"ProcessName",@"AppID",@"isFrontmost",nil]];

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

            free(process);
            return array;
        }
    }
  }

    dlclose(sbserv);
}

当然,第二个循环并不是绝对必要的,但是我需要非本地化的名称& PID也是.

猜你在找的iOS相关文章