- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想模拟点击越狱 iPhone 主屏幕上的应用程序图标。我使用了下面的代码,但是无法生效。我做错了什么吗?
getFrontMostAppPort()
的方法对吗?如果我尝试使用 GSSendSystemEvent()
事件,它没有任何效果。
顺便说一句,我的意思是越狱设备。谁能帮我?非常感谢。
// Framework Paths
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
static mach_port_t getFrontMostAppPort() {
bool locked;
bool passcode;
mach_port_t *port;
void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() = dlsym(lib, "SBSSpringBoardServerPort");
void* (*SBGetScreenLockStatus)(mach_port_t* port, bool *lockStatus, bool *passcodeEnabled) = dlsym(lib, "SBGetScreenLockStatus");
port = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(lib);
SBGetScreenLockStatus(port, &locked, &passcode);
void *(*SBFrontmostApplicationDisplayIdentifier)(mach_port_t *port, char *result) = dlsym(lib, "SBFrontmostApplicationDisplayIdentifier");
char appId[256];
memset(appId, 0, sizeof(appId));
SBFrontmostApplicationDisplayIdentifier(port, appId);
NSString * frontmostApp=[NSString stringWithFormat:@"%s",appId];
if([frontmostApp length] == 0 || locked)
return GSGetPurpleSystemEventPort();
else
return GSCopyPurpleNamedPort(appId);
}
static void sendTouchEvent(GSHandInfoType handInfoType, CGPoint point) {
uint8_t touchEvent[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];
// structure of touch GSEvent
struct GSTouchEvent {
GSEventRecord record;
GSHandInfo handInfo;
} * event = (struct GSTouchEvent*) &touchEvent;
bzero(touchEvent, sizeof(touchEvent));
// set up GSEvent
event->record.type = kGSEventHand;
event->record.subtype = kGSEventSubTypeUnknown;
event->record.windowLocation = point;
event->record.timestamp = GSCurrentEventTimestamp();
event->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
event->handInfo.type = handInfoType;
event->handInfo.x52 = 1;
bzero(&event->handInfo.pathInfos[0], sizeof(GSPathInfo));
event->handInfo.pathInfos[0].pathIndex = 1;
event->handInfo.pathInfos[0].pathIdentity = 2;
event->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03 : 0x00;;
event->handInfo.pathInfos[0].pathLocation = point;
mach_port_t port = (mach_port_t)getFrontMostAppPort();
GSSendEvent((GSEventRecord *)event, port);
}
// why nothing happened?
static clickOnHome() {
sendTouchEvent(kGSHandInfoTypeTouchDown, CGPointMake(100, 200));
sleep(1);
sendTouchEvent(kGSHandInfoTypeTouchUp, CGPointMake(100, 200));
}
最佳答案
是的,我认为您的getFrontMostAppPort()
方法很好,if you got it from here .
我正在尝试了解您的需求:
如果您只是想打开一个特定的应用程序(通过 bundleId),那么我建议使用 Cydia 上可用的命令行 open
实用程序。您可以使用 system()
或 exec
调用以编程方式调用它。或者,如果您想将此“开放”功能构建到您自己的应用程序中,see my answer here .
现在,也许您正在为后台的应用或调整编写代码,而不是前台应用。而且,也许您真的需要触摸特定的 {x,y} 坐标,而不是通过其 bundleId 打开应用程序。如果你真的想要,这段代码对我有用(based on this answer ... with corrections):
static void sendTouchEvent(GSHandInfoType handInfoType, CGPoint point) {
uint8_t gsTouchEvent[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];
// structure of touch GSEvent
struct GSTouchEvent {
GSEventRecord record;
GSHandInfo handInfo;
} * touchEvent = (struct GSTouchEvent*) &gsTouchEvent;
bzero(touchEvent, sizeof(touchEvent));
touchEvent->record.type = kGSEventHand;
touchEvent->record.subtype = kGSEventSubTypeUnknown;
touchEvent->record.location = point;
touchEvent->record.windowLocation = point;
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->record.timestamp = GSCurrentEventTimestamp();
//touchEvent->record.window = winRef;
//touchEvent->record.senderPID = 919;
bzero(&touchEvent->handInfo, sizeof(GSHandInfo));
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
GSHandInfo touchEventHandInfo;
touchEventHandInfo._0x5C = 0;
touchEventHandInfo.deltaX = 0;
touchEventHandInfo.deltaY = 0;
touchEventHandInfo.height = 0;
touchEventHandInfo.width = 0;
touchEvent->handInfo = touchEventHandInfo;
touchEvent->handInfo.type = (handInfoType == kGSHandInfoTypeTouchDown) ? 2 : 1;
touchEvent->handInfo.deltaX = 1;
touchEvent->handInfo.deltaY = 1;
touchEvent->handInfo.pathInfosCount = 0;
touchEvent->handInfo.pathInfos[0].pathIndex = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03: 0x00;
touchEvent->handInfo.x52 = 1; // iOS 5+, I believe
touchEvent->handInfo.pathInfos[0].pathLocation = point;
//touchEvent->handInfo.pathInfos[0].pathWindow = winRef;
GSEventRecord* record = (GSEventRecord*) touchEvent;
record->timestamp = GSCurrentEventTimestamp();
GSSendEvent(record, getFrontMostAppPort());
}
- (void) simulateHomeScreenTouch {
CGPoint location = CGPointMake(50, 50);
sendTouchEvent(kGSHandInfoTypeTouchDown, location);
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
sendTouchEvent(kGSHandInfoTypeTouchUp, location);
});
}
只要 SpringBoard 是最前面的应用程序(没有打开其他应用程序),这就会向 SpringBoard 发送触摸向下/向上事件对。此外,您还可以看到 handInfoType
值映射到 2
或 1
的位置,用于触碰和触碰事件。上面的代码假定这些是您生成的仅有的两种类型的事件。
注意:我首先尝试使用您的坐标 x=100,y=200,但没有任何反应。我认为坐标在两个主屏幕图标之间。使用其他坐标(例如 x=50、y=50)也能正常工作。
注二:我认为这个解决方案实际上不需要越狱。它使用私有(private) API,因此无法提交到 App Store,但这应该适用于企业或业余爱好者部署中的 jailed 手机。
关于iphone - 如何模拟点击(越狱)iPhone 的主屏幕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17915012/
我正在为 Cydia 做一个调整,我想在状态栏上添加一个图标。几个小时以来,我一直在通过 Google 搜索我能想到的每一个可能的短语,但似乎什么都没有。 我知道使用 Apple SDK 是不可能的,
我想覆盖静音开关以在开关切换时创建一个新 Action 。那么当开关改变时触发的方法是什么? 谢谢 最佳答案 在 SpringBoard 中 Hook 这个方法 SBMediaController -
如果我没记错的话(如果我错了,请纠正我),未越狱的 iPhone 提供了两个广泛的存储空间: 适用于应用(以及与应用捆绑的数据); 用于用户管理的文件。 据我所知,前者是 protected 存储,这
我编写了一个将数据从一个 i-Device 传输到另一个 i-Device 的代码,但是由于 Apple 提供了官方解锁设备,我想扩展解决方案以将数据从 i-Device 传输到另一个基于平台的设备。
我的应用程序(越狱的 iOS)是否有一种优雅的方式( Objective-C 或 C)来检查特定的动态库在 iOS 中是否可用,而不是使用 NSFileManager 检查实际的 dylib 文件是否
是否可以使用 Objective-C 在越狱的 iOS 中以编程方式开始和结束调用?我知道使用非越狱设备是不可能的(尤其是调用结束),但我要求越狱版本。 最佳答案 开始通话使用 [[UIApplica
在越狱的 iOS 设备上,一个应用程序是否可以调用另一个应用程序的方法(实例方法,而不是静态方法)?另一种表达方式:如何获取应用程序的实例(假设应用程序正在运行)以便我可以调用它的方法之一? 背景:我
我很清楚使用私有(private) API 访问网络信息会导致您的应用被拒绝。 但是,假设我有一个越狱设备,是否可以通过编程在两个 WiFi 网络之间切换? 最佳答案 你将不得不使用 MobileAp
我正在开发一个简单的工具,请求设备从命令行解锁。但是,使用下面的这些代码,似乎没有发生任何事情(使用 Cycript 验证 sharedInstance 代码是否正确,并且设备确实收到了解锁请求) #
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwa
无法让我的 Javascript 正确显示我的 HTML 锁屏上的时间。 我一直在研究其他几个,他们没有使用 document.write() 而是使用 document.getElementById
我想模拟点击越狱 iPhone 主屏幕上的应用程序图标。我使用了下面的代码,但是无法生效。我做错了什么吗? getFrontMostAppPort() 的方法对吗?如果我尝试使用 GSSendSyst
如何在越狱的 iOS 6.x 设备上检索应用程序的作者(或开发者或发布者等)?在 iOS 4.x 和 5.x 中,SBApplication 类中有一个 author 成员。但是在 iOS 6.1 中
在iOS7之前,我使用UIGetScreenImage()函数来轻松截取屏幕截图,但在iOS7中,它已被弃用,现在有什么好的方法可以存档吗?谢谢! 补充:我需要在任意 View 截取整个屏幕 最佳答案
我有我的 iOS 应用程序(具有合法配置的标准应用程序)。它从网络获取有关电话号码的信息并显示给用户。应用程序可以与网络一起工作,有存储空间,而且非常聪明:)。 此外,我对 InCallService
我想以root身份运行应用程序 稍后,我通过一个间接脚本运行该应用程序,并使用 6755 权限设置运行该应用程序,该部分有效并运行该应用程序。 MyApp.app/MyApp MyApp.app/My
我正在为越狱的 iPhone 开发一个 iOS 应用程序。作为启动守护进程,它需要在手机启动时运行。所以这就是问题所在,下载包时,守护程序的 plist 已放置在/System/Library/Lau
有一个很好的开源库,它使用 Apple 的私有(private)框架将音频文件添加到越狱的 iOS 设备上的 iTunes 库中,libipodimport .它缺少的是在添加音乐文件时也可以添加艺术
我有问题。我需要为 越狱 iOS 解决这个问题。我的应用程序在后台模式下工作。我希望该应用程序在某些事件后从后台进入前台模式。我尝试了下一条指令: system([[NSString stringWi
我正在为越狱的 iPhone 构建一个守护程序应用程序,并遵循了 stackoverflow 上的几个问题和答案中描述的指南,当然还有 Chris Alvares 的网页 http://chrisal
我是一名优秀的程序员,十分优秀!