Screenshot UX Trialのように、root権限なしにプログラムで他のアプリのスクリーンショットを撮る方法は?
私は自分のアプリでルートビューのビットマップをキャプチャできることを知っています。しかし、アプリがバックグラウンドで実行されている場合、他のアプリのルートビューを取得できません
bitmap = Bitmap.createBitmap(rootview.getDrawingCache());
マニフェストに現在のフレームバッファーをキャプチャする権限があります:Android.permission.READ_FRAME_BUFFER
。しかし、一部のWebサイトでは、署名アプリ専用であると書かれています。
Screenshot UX Trialを試した後、私は許可を読みました:
いずれかのSYSTEM_ALERT_WINDOW
またはGET_TASKS
アプリがスクリーンショットを撮ることを許可します。私はそれがどのように機能するかについて2つの推測を持っています:
Activity
にアクセスでき、Activity
のルートビューを取得し、スクリーンショットをキャプチャできます。glreadpixels
を呼び出す私の推測のいずれかを試してみたら、結果を教えてください。
これは非常に困難です。私はそれをしようとして数年を費やしました。最終的には成功しましたが、解決策には商業的な努力と技術的な努力が必要です。
以下のもののほとんどはもはや最新ではありません。今、すべてのこれらの年後、_Android.media.projection
_パッケージがあります https://developer.Android.com/reference/Android/media/projection/package-summary.html 必要!
完全を期すために、Bitmap.createBitmap(rootview.getDrawingCache());
および同様のメカニズムを使用して独自のアプリケーションの画像をキャプチャできるという独自のコメントを含めたいと思います。
READ_FRAMEBUFFER
_パーミッションを使用するまず、通常のアプリケーションでは「署名」レベルであるため、_READ_FRAMEBUFFER
_パーミッションを使用できないことは間違いありません。つまり、このようなスクリーンショットを撮るには、AndroidシステムROMと同じキーで署名する必要があります。
これは少し悲しいと思ったので、2009年にオープンソースプロジェクトを提出するためにAndroidオープンソースプロジェクトを提出しました 1 。 AndroidアーキテクトのDianne Hackbornからの応答は次のとおりです。
いいえ。絶対に肯定的ではありません。
それで、それはうまくいきました!したがって、この許可は今日までsignature
レベルのままです。
ただし、この許可があれば、captureScreen
のISurfaceComposer
メンバーを呼び出すことができます [2 。この関数にアクセスするには、Android NDKおよびドキュメント化されていないAPIを使用して、ネイティブコードを記述する必要があります。しかし、それは可能です。
内部的にAndroidグラフィックスサブシステム内で、これはglReadPixels
呼び出しを使用して、GPUからCPUにピクセルを取得します。 (GPUはAndroidのほとんどの合成に使用されます。実際、Android 4.0+は追加のハードウェアコンポジターをサポートし、Surface FlingerはこれらのピクセルをCPUに戻すためにさらに多くの作業を行う必要があります。)
この呼び出しは、いくつかの小さな問題を除いて美しく機能します:
...そして1つの大きな問題...
それでも、ほとんどのAndroidデバイスでは、これから毎秒10フレームを取得できます。さらに良いことに、このAPIは実際には、GPUのハードウェアで結果の画像のスケーリングをサポートしているため、賢い場合は、画像を事前にスケーリングできますピクセルがCPUにヒットする前に必要なサイズ。そのため、非常に高いパフォーマンスが得られます。
もちろん、関連するOpenGLコンテキストにアクセスできないため、アプリケーションライターとしてglReadPixels
を呼び出すことはできません。表面のフリンガーが所有しています。
/dev/graphics/fb0
_などを使用するフレームバッファを表すこれらのLinuxデバイスファイルを読み取ろうとする人もいます。ただし、次の3つの問題があります。
captureScreen
APIを呼び出して正しいイメージを取得できます。今、私たちは商業的な行動を必要とするソリューションに入ります。
Androidチップセットメーカーと話をすると、多くの場合、解決策が提示されます。ハードウェアを設計しているため、フレームバッファーにアクセスできます。また、カスタムカーネルドライバーに直接アクセスするだけで、Android権限モデルを完全に回避するライブラリを提供できます。
特定の電話モデルを目指している場合、これは多くの場合、前向きな方法です。もちろん、シリコンメーカーだけでなく、電話メーカーとも協力する必要があるでしょう。
これにより、優れた結果が得られる場合があります。たとえば、一部のハードウェアでは、電話ハードウェアフレームバッファーを直接電話ハードウェアH.264ビデオエンコーダーにパイプし、電話画面にあるものの事前にエンコードされたビデオストリームを取得することができると聞きました。素晴らしい。 (残念ながら、私はknowのみです。これはTI OMAPチップで可能であり、電話市場から徐々に撤退しています)。
Androidは許可モデルを厳密に実施し、セキュリティホールはほとんどありません。ただし、Android OEMは不注意な場合があります。
たとえば、名前がSで始まる大手OEMは、キーストロークを使用して画面をキャプチャする方法を実装しています。 SDカード上の誰でも読み取り可能なファイルに保存します。仮に、これらのキーをインターセプトするものを見つけて、それがどのように機能するかを見ることができるかもしれません。おそらく、あなたは似たようなことをすることができます。
また、おそらく名前がSで始まる別の大手OEM向けの方法があるかもしれません。
いいえ、このセクションではこれ以上詳しく説明しません。これらのことを行う方法を理解するには、リバースエンジニアリングされたソフトウェアが必要です。これは違法かもしれません。幸運を祈ります。
前に説明したように、電話メーカーは動作するAPIにすぐにアクセスできます。また、電話メーカーにはsignature
レベルの権限が必要です。
だから、あなたがする必要があるのは、電話メーカーによって署名されたソフトウェアを取得することを手配することです。
ただし、これはhardです。ソフトウェアに署名することで、電話メーカーはその品質を保証しているため、ソースコードを監査する必要があります。また、Androidの性質により、ソフトウェアに署名する場合は、配布する必要があります。他の人の署名によって署名されている場合、マーケットに置くことはできません。
ただし、OEMはROMに含める必要はありません。Android市場で配布することができます。しかし、できません。
各ベンダーが小さなライブラリに署名すると、一般的なSDKからアクセスできるようになります。それは私を導く...
RealVNCで働いていたので、これについてはよく知っています。これらのシグネチャレベルAPIにアクセスするために、すべての主要なAndroid電話ベンダーと協力しました。これを達成するために必要な多くの人的努力(商業的および技術的)を過度に強調することはできません。一部のOEMはこの作業を公表しています-たとえば、 4 。
私はRealVNCで動作しなくなりました。そのため、彼らのソフトウェアを宣伝しても何も得られません。ただし、本当に本当に複数のAndroidデバイスで画面をキャプチャできるようにしたい場合は、 -リモートコントロールサービスまたはAndroid VNC SDKを使用 5 。これはオープンソースではないので、支払いを期待する必要があります。これらすべてのAndroid OEMとの作業に伴う多大な努力を考えると、これは十分に公平だと思います。
バランスをとるために、他のベンダーもこれについて電話メーカーと協力していることを指摘する必要があります。ソティ。しかし、これらはすべて、一般的なリモートコントロール/イベントインジェクションSDKではなく、特定のデバイス管理ソリューションを提供すると考えています。
別のオプション-USB経由のデバッグ接続をリッスンするadb
デーモンには、通常のアプリケーションよりもわずかに多くの特権があります。そのため、画面を取得できます(ddms
ツールを使用してその画像を表示できます)。 adb
を使用してコマンドを実行できる場合は、それらの特権も取得できます(前述のAndroid-screenshot-libraryに従って)。
最終的に、この問題は私をほこりに減らし、Android電話からピクセルを絞ろうとすることを伴わない、より緑の牧草地に向かいました。
しかし、RealVNCを離れる前に、これらのAPIをAndroidオープンソースプロジェクトに再提供しようとしました。今回は、より肯定的な反応を得ました 6 。要するに、セキュリティのアプローチはほぼ正しいが、グラフィックスシステムがパッチを受け入れるにはあまりにも混乱していることが示唆されました。さて、素晴らしいニュースは、グラフィックシステムが混乱していないことです。実際、グラフィックシステムの変更は一切必要ないというcaptureScreen
APIを持っています。したがって、このAPIを中心にAOSPに新しいセキュリティメカニズムを送信して、この問題を最終的に解決できる可能性があります。
幸運を祈ります!
多分 Android-screenshot-library が助けになるでしょう。しかし、彼らのUsageページでは、adbで開始されたネイティブサービスが必要であると述べています(Android sdk)から)。
PS:スクリーンショットUXはルート化されていないすべての電話で機能するわけではないことに注意してください。