为了账号安全,请及时绑定邮箱和手机立即绑定

如何通过应用程序ID确定哪些应用程序是后台应用程序,哪个应用程序是iOS前台应用程序

如何通过应用程序ID确定哪些应用程序是后台应用程序,哪个应用程序是iOS前台应用程序

iOS
12345678_0001 2019-11-13 15:57:58
使用此问题中描述的方法,我可以获得在iOS设备上运行的应用程序的列表。我知道PID并可以访问其kinfo_proc结构。我如何确定哪些是前台进程,哪些是后台进程(假设我的应用程序是后台进程)?我试图通过中的信息kinfo_proc(请参阅第一个链接)找到此信息kp_proc.p_priority,但似乎无法根据优先级推断背景/前景状态。我不太在乎是否可以在AppStore Review中正常工作,但我更喜欢一种无需越狱即可工作的方法(即,私有API可以,但是哪些API?)。我希望它至少在iOS 5上能正常工作我考虑过编写一个简单的MobileSubstrate扩展程序,将其注入所有应用程序中,然后就钩住每个人的了applicationDidBecomeActive,但这需要越狱,而且过于侵入性。
查看完整描述

3 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

好答案!但是您的代码中有一个小的错字,应该是:


首先,请确保已定义SBSERVPATH并包含正确的头文件:


#import <sys/sysctl.h>

#import <dlfcn.h>


#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"

然后,首先找到正确的SB端口:


mach_port_t *port;

void *lib = dlopen(SBSERVPATH, RTLD_LAZY);

int (*SBSSpringBoardServerPort)() = 

dlsym(lib, "SBSSpringBoardServerPort");

port = (mach_port_t *)SBSSpringBoardServerPort(); 

dlclose(lib);

然后找到活动的应用程序:


mach_port_t * port = [self getSpringBoardPort];

// open springboard lib

void *lib = dlopen(SBSERVPATH, RTLD_LAZY);


// retrieve function SBFrontmostApplicationDisplayIdentifier

void *(*SBFrontmostApplicationDisplayIdentifier)(mach_port_t *port, char *result) =

dlsym(lib, "SBFrontmostApplicationDisplayIdentifier");


// reserve memory for name

char appId[256];

memset(appId, 0, sizeof(appId));


// retrieve front app name

SBFrontmostApplicationDisplayIdentifier(port, appId);


// close dynlib

dlclose(lib);


查看完整回答
反对 回复 2019-11-13
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

这对所有IOS设备都适用:


#define UIKITPATH "/System/Library/Framework/UIKit.framework/UIKit"

#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"


 - (NSArray*) getActiveApps

 {

mach_port_t *p;

void *uikit = dlopen(UIKITPATH, RTLD_LAZY);

int (*SBSSpringBoardServerPort)() =

dlsym(uikit, "SBSSpringBoardServerPort");

p = (mach_port_t *)SBSSpringBoardServerPort();

dlclose(uikit);


if(self.frameWorkPath == nil || self.frameWorkPath.length == 0)

{

    self.frameWorkPath = @SBSERVPATH;

    self.frameWorkPath = [self.frameWorkPath stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];

}


const char *cString = [self.frameWorkPath cStringUsingEncoding:NSUTF8StringEncoding];

//const char *bar = [self.frameWorkPath UTF8String];

void *sbserv = dlopen(cString, 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[512];

memset(frontmostAppS,sizeof(frontmostAppS),0);

SBFrontmostApplicationDisplayIdentifier(p,frontmostAppS);

NSString * frontmostApp=[NSString stringWithFormat:@"%s",frontmostAppS];


if([self iOsMajorVersion] >= 7){

    NSNumber *topmost = [NSNumber numberWithBool:YES];

    NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];

    NSMutableArray  * splitted = [frontmostApp componentsSeparatedByString:@"."];

    if(frontmostApp.length > 0 && splitted != nil && splitted.count > 1 && topmost.boolValue == YES){

        NSString *appname = [splitted lastObject];

        [dict setObject:[appname capitalizedString] forKey:@"ProcessName"];

        [dict setObject:frontmostApp forKey:@"ProcessID"];

        [dict setObject:frontmostApp forKey:@"AppID"];

        [dict setObject:topmost forKey:@"isFrontmost"];

        NSLog(@"Running TOPMOST App %@",dict);

        return @[dict];

    }

    else{

        return nil;

    }

}

//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);

 }


查看完整回答
反对 回复 2019-11-13
  • 3 回答
  • 0 关注
  • 609 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信