Wie kann ich den Bildschirminhalt des Android-Geräts erfassen?

Mögliche Duplikate:
Wie programmiere ich einen Screenshot auf Android?

Wie kann ich den Bildschirminhalt des Android-Geräts erfassen und mithilfe der Snapshot-Daten eine Bilddatei erstellen? Welche API sollte ich verwenden oder wo finde ich verwandte Ressourcen?

BTW: nicht Kamera-Snapshot, aber Gerätebildschirm

    Gemäß diesem Link ist es möglich, ddms im Tools-Verzeichnis des Android SDK zu verwenden, um Bildschirmaufnahmen zu machen.

    Um dies innerhalb einer Anwendung (und nicht während der Entwicklung) zu tun, gibt es auch Anwendungen dafür. Aber @ @ zed_0xff weist darauf hin, dass es root braucht.

    Verwenden Sie den folgenden Code:

    Bitmap bitmap; View v1 = MyView.getRootView(); v1.setDrawingCacheEnabled(true); bitmap = Bitmap.createBitmap(v1.getDrawingCache()); v1.setDrawingCacheEnabled(false); 

    Hier ist MyView die View durch die wir auf dem Bildschirm MyView müssen. Sie können DrawingCache von jedem View diese Weise getRootView() ohne getRootView() ).

    Es gibt auch einen anderen Weg ..
    Wenn wir ScrollView als root view haben, dann ist es besser folgenden Code zu verwenden,

     LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE); FrameLayout root = (FrameLayout) inflater.inflate(R.layout.activity_main, null); // activity_main is UI(xml) file we used in our Activity class. FrameLayout is root view of my UI(xml) file. root.setDrawingCacheEnabled(true); Bitmap bitmap = getBitmapFromView(this.getWindow().findViewById(R.id.frameLayout)); // here give id of our root layout (here its my FrameLayout's id) root.setDrawingCacheEnabled(false); 

    Hier ist die getBitmapFromView() -Methode

     public static Bitmap getBitmapFromView(View view) { //Define a bitmap with the same size as the view Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888); //Bind a canvas to it Canvas canvas = new Canvas(returnedBitmap); //Get the view's background Drawable bgDrawable =view.getBackground(); if (bgDrawable!=null) //has background drawable, then draw it on the canvas bgDrawable.draw(canvas); else //does not have background drawable, then draw white background on the canvas canvas.drawColor(Color.WHITE); // draw the view on the canvas view.draw(canvas); //return the bitmap return returnedBitmap; } 

    Es zeigt den gesamten Bildschirm einschließlich des in Ihrer ScrollView verborgenen ScrollView

    AKTUALISIERT AM 20-04-2016

    Es gibt eine andere bessere Möglichkeit, Screenshot zu machen.
    Hier habe ich einen Screenshot von WebView .

     WebView w = new WebView(this); w.setWebViewClient(new WebViewClient() { public void onPageFinished(final WebView webView, String url) { new Handler().postDelayed(new Runnable(){ @Override public void run() { webView.measure(View.MeasureSpec.makeMeasureSpec( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); webView.layout(0, 0, webView.getMeasuredWidth(), webView.getMeasuredHeight()); webView.setDrawingCacheEnabled(true); webView.buildDrawingCache(); Bitmap bitmap = Bitmap.createBitmap(webView.getMeasuredWidth(), webView.getMeasuredHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); int height = bitmap.getHeight(); canvas.drawBitmap(bitmap, 0, height, paint); webView.draw(canvas); if (bitmap != null) { try { String filePath = Environment.getExternalStorageDirectory() .toString(); OutputStream out = null; File file = new File(filePath, "/webviewScreenShot.png"); out = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 50, out); out.flush(); out.close(); bitmap.recycle(); } catch (Exception e) { e.printStackTrace(); } } } }, 1000); } }); 

    Hoffe das hilft..!

    AFAIK, Alle Methoden, um einen Screenshot von Android zu erstellen, verwenden den / dev / graphics / fb0 Framebuffer. Dies schließt ddms ein. Es benötigt root, um von diesem Stream zu lesen. ddms verwendet adbd, um die Informationen anzufordern, daher ist root nicht erforderlich, da adb über die erforderlichen Berechtigungen verfügt, um die Daten von / dev / graphics / fb0 anzufordern.

    Der Framebuffer enthält 2+ “Frames” von RGB565-Bildern. Wenn Sie die Daten lesen können, müssten Sie die Bildschirmauflösung kennen, um zu wissen, wie viele Bytes benötigt werden, um das Bild zu erhalten. Jedes Pixel ist 2 Bytes. Wenn also der Bildschirm res 480×800 hätte, müssten Sie 768.000 Bytes für das Bild lesen, da ein 480×800 RGB565-Bild 384.000 Pixel hat.

    Für neuere Android-Plattformen kann man ein System-Dienstprogramm screencap in /system/bin ausführen, um den Screenshot ohne Root-Berechtigung zu erhalten. Sie können versuchen, /system/bin/screencap -h zu sehen, wie Sie es unter adb oder einer Shell verwenden.

    Übrigens denke ich, dass diese Methode nur für einzelne Schnappschüsse geeignet ist. Wenn wir mehrere Frames für die Bildschirmwiedergabe aufnehmen möchten, ist dies zu langsam. Ich weiß nicht, ob es einen anderen Ansatz für eine schnellere Bildschirmaufnahme gibt.

    [Basierend auf dem Android-Quellcode:]

    Auf der C ++ Seite implementiert der SurfaceFlinger die captureScreen API. Dies wird über die Binder-IPC-Schnittstelle angezeigt, wobei jedes Mal ein neuer Aschembereich zurückgegeben wird, der die Rohpixel von dem Bildschirm enthält. Der eigentliche Screenshot wird über OpenGL erstellt.

    Für die System-C ++ – Clients wird die Schnittstelle über die in für Android <4.1; definierte Klasse ScreenshotClient verfügbar gemacht. Für Android> 4.1 verwenden Sie

    Vor JB, um einen Screenshot in einem C ++ – Programm zu machen, war das genug:

     ScreenshotClient ssc; ssc.update(); 

    Mit JB und mehreren Displays wird es etwas komplizierter:

     ssc.update( android::SurfaceComposerClient::getBuiltInDisplay( android::ISurfaceComposer::eDisplayIdMain)); 

    Dann können Sie darauf zugreifen:

     do_something_with_raw_bits(ssc.getPixels(), ssc.getSize(), ...); 

    Mit dem Android-Quellcode können Sie Ihre eigene gemeinsam genutzte Bibliothek kompilieren, um auf diese API zuzugreifen, und sie dann über JNI für Java verfügbar machen. Um einen Screenshot Ihrer App zu erstellen, muss die App über die READ_FRAME_BUFFER verfügen. Aber selbst dann können Sie anscheinend nur Screenshots von Systemanwendungen erstellen, also solche, die mit demselben Schlüssel wie das System signiert sind. (Diesen Teil verstehe ich noch nicht ganz, da ich das Android Permissions System nicht kenne.)

    Hier ist ein Stück Code für JB 4.1 / 4.2:

     #include  #include  #include  #include  #include  static void do_save(const char *filename, const void *buf, size_t size) { int out = open(filename, O_RDWR|O_CREAT, 0666); int len = write(out, buf, size); printf("Wrote %d bytes to out.\n", len); close(out); } int main(int ac, char **av) { android::ScreenshotClient ssc; const void *pixels; size_t size; int buffer_index; if(ssc.update( android::SurfaceComposerClient::getBuiltInDisplay( android::ISurfaceComposer::eDisplayIdMain)) != NO_ERROR ){ printf("Captured: w=%d, h=%d, format=%d\n"); ssc.getWidth(), ssc.getHeight(), ssc.getFormat()); size = ssc.getSize(); do_save(av[1], pixels, size); } else printf(" screen shot client Captured Failed"); return 0; } 

    Sie können die folgende Bibliothek ausprobieren: Android Screenshot Library (ASL) ermöglicht die programmgesteuerte Erfassung von Screenshots von Android-Geräten, ohne dass Root-Zugriffsrechte erforderlich sind. Stattdessen verwendet ASL einen nativen Dienst, der im Hintergrund ausgeführt wird und über die Android Debug Bridge (ADB) einmal pro Gerät gestartet wird.

    Wenn Sie Screen-Capture von Java-Code in der Android-App AFAIK machen wollen, müssen Sie Root-functionen haben.

    Framebuffer scheint der Weg zu sein, es wird nicht immer 2+ Frames enthalten, wie von Ryan Conrad erwähnt. In meinem Fall enthielt es nur einen. Ich schätze, das hängt von der Bildgröße ab.

    Ich habe versucht, den Framebuffer kontinuierlich zu lesen, aber es scheint für eine feste Menge gelesener Bytes zurückzukehren. In meinem Fall sind das (3 410 432) Bytes, was ausreicht, um einen Anzeigerahmen von 854 * 480 RGBA (3 279 360 Bytes) zu speichern. Ja, der binär von fb0 ausgegebene Frame ist RGBA in meinem Gerät . Dies hängt höchstwahrscheinlich von Gerät zu Gerät ab . Dies ist wichtig für Sie, um es zu dekodieren =)

    In meinem Gerät sind / dev / graphics / fb0 Berechtigungen so, dass nur root und Benutzer von Gruppengrafiken den fb0 lesen können. Grafiken sind eine eingeschränkte Gruppe, so dass Sie wahrscheinlich nur mit einem verwurzelten Telefon auf fb0 zugreifen, indem Sie den Befehl su verwenden.

    Android-Apps haben die Benutzer-ID (uid) app _ ## und die Gruppen-ID (guid) app _ ## .

    adb shell hat uid shell und guid shell , die viel mehr Berechtigungen als eine App hat. Sie können diese Berechtigungen unter /system/permissions/platform.xml überprüfen

    Das heißt, Sie können fb0 in der AdB-Shell ohne root lesen, aber Sie werden es nicht ohne root in der App lesen.

    Wenn Sie die Berechtigungen READ_FRAME_BUFFER und / oder ACCESS_SURFACE_FLINGER für AndroidManifest.xml erteilen, wird auch nichts für eine normale App ausgeführt, da diese nur für Signaturanwendungen funktionieren.