我需要创建一个iOS应用程序,可以作为实验的一部分截取其他应用程序、视频等的屏幕截图。由于我不会将该应用发布到应用商店,因此我可以使用私有API。我可以成功使用GetUIScreenImage()方法来截取当前屏幕(应用屏幕)的快照。
然而,由于沙盒限制,我无法在后台截取屏幕截图。我会收到错误提示 - “Cannot call CreateUIScreenImage() while the app is in background”。
我参考了这篇文章 - How does the iOS app Display Recorder record the screen without using private API?,建议使用IOMobileFramebuffer和IOSurface绕过沙盒限制,以及这个链接 - http://www.iphonesheep.com/2009/11/25/iphone%E2%80%99s-framebuffer-secrets-revealed/。但是我无法理解如何创建和传输表面。非常感谢对此话题的任何帮助。
另外,有没有办法在越狱设备的后台中调用UIGetScreenImage()?
更新: 我能够获取主屏幕表面并将其放在应用程序层上,但我的用例是能够打开其他应用程序并能够通过我创建的应用程序记录它们。我覆盖在我的应用程序层上的表面是静态的。
编辑: 这是我理解的-附加到主显示层的主屏幕表面需要放置在当前层上。这样做后,我应该能够浏览其他应用程序,从刚刚粘贴的表面打开它们。
这是代码(它将主屏幕表面放在应用程序层的顶部,但我无法使用该表面,即打开应用程序等):
我知道我可能遗漏了某些东西并且做错了一些事情。如果您能指出来,那将是很大的帮助。 更新
我认为我的基本假设可能是错误的。
1. 我的假设 -> 应用程序交换表面(或图层),以便用户现在可以在主屏幕上浏览。该应用程序从未移动到后台。
2. 更正确的做法 -> 应用程序移至后台。获取屏幕上的最顶层表面,创建其图像并保存。
请澄清。
然而,由于沙盒限制,我无法在后台截取屏幕截图。我会收到错误提示 - “Cannot call CreateUIScreenImage() while the app is in background”。
我参考了这篇文章 - How does the iOS app Display Recorder record the screen without using private API?,建议使用IOMobileFramebuffer和IOSurface绕过沙盒限制,以及这个链接 - http://www.iphonesheep.com/2009/11/25/iphone%E2%80%99s-framebuffer-secrets-revealed/。但是我无法理解如何创建和传输表面。非常感谢对此话题的任何帮助。
另外,有没有办法在越狱设备的后台中调用UIGetScreenImage()?
更新: 我能够获取主屏幕表面并将其放在应用程序层上,但我的用例是能够打开其他应用程序并能够通过我创建的应用程序记录它们。我覆盖在我的应用程序层上的表面是静态的。
编辑: 这是我理解的-附加到主显示层的主屏幕表面需要放置在当前层上。这样做后,我应该能够浏览其他应用程序,从刚刚粘贴的表面打开它们。
这是代码(它将主屏幕表面放在应用程序层的顶部,但我无法使用该表面,即打开应用程序等):
IOMobileFramebufferConnection connect;
kern_return_t result;
CoreSurfacebufferRef screenSurface = NULL;
io_service_t framebufferService = IOServiceGetMatchingService (kIOMasterPortDefault, IOServiceMatching ("AppleH1CLCD"));
if(!framebufferService)
io_service_t framebufferService = IOServiceGetMatchingService (kIOMasterPortDefault, IOServiceMatching ("AppleM2CLCD"));
if(!framebufferService)
io_service_t framebufferService = IOServiceGetMatchingService (kIOMasterPortDefault, IOServiceMatching ("AppleCLCD"));
result = IOMobileFramebufferOpen( framebufferService, mach_task_self(), 0 , &connect);
result = IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &screenSurface);
CALayer *Layer;
Layer = [CALayer layer];
[Layer setFrame: CGRectMake(0, 0, 768, 1024)];
[Layer setOpaque:YES];
IOSurfaceLock(screenSurface, 0, NULL);
[Layer setContents: (_bridge id)(screenSurface)];
IOSurfaceUnlock(screenSurface, 0, NULL);
[self.view.layer addSublayer:Layer];
我知道我可能遗漏了某些东西并且做错了一些事情。如果您能指出来,那将是很大的帮助。 更新
我认为我的基本假设可能是错误的。
1. 我的假设 -> 应用程序交换表面(或图层),以便用户现在可以在主屏幕上浏览。该应用程序从未移动到后台。
2. 更正确的做法 -> 应用程序移至后台。获取屏幕上的最顶层表面,创建其图像并保存。
请澄清。