4

実験の一環として、他のアプリや動画などのスクリーンショットを撮影できる iOS アプリを作成する必要があります。アプリをアプリ ストアに公開しないため、プライベート API を使用することにオープンです。メソッド GetUIScreenImage() を使用して、現在の画面 (アプリ画面) のスナップショットを取得できました。

ただし、サンドボックスの制限により、バックグラウンドでスクリーンショットを撮ることができません。「アプリがバックグラウンドにある間は CreateUIScreenImage() を呼び出せません」というエラーが表示されます。

この記事を参照しました - iOS アプリ Display Recorder はプライベート 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. どちらがより正確に聞こえますか -> アプリがバックグラウンドに移動します。画面の最上面を取得し、そこから画像を作成して保存します。どうか明らかにしてください。

4

1 に答える 1

3

「サーフェスを作成して転送するフローを取得する」ことの正確な問題は何ですか? 使用しているコードを投稿して、どの行が機能しないかを指摘できますか。

ジェイルブレイクされたデバイスの場合:

/Application/XCode/Content/Developer/Platforms に移動し、「アプリがバックグラウンドにある間は CreateUIScreenImage() を呼び出せません」という文を grep します。いくつかのフレームワークで見つけることができます (UIKit を想定しています)。次に、それを分解すると、バックグラウンドでスクリーンショットを撮るために必要な権利が見つかります。

また、ジェイルブレイクされたデバイスの ldid で資格を使用する方法をここで見ることができます: iOS Entitlement.plist を使用してアプリのプロパティを指定する方法

于 2012-12-12T19:12:26.650 に答える