553 Stimmen

Wie macht man programmgesteuert einen Screenshot unter Android?

Wie kann ich einen Screenshot von einem ausgewählten Bereich des Telefondisplays nicht mit einem Programm, sondern mit Code erstellen?

495voto

taraloca Punkte 8891

Hier ist der Code, mit dem mein Screenshot auf einer SD-Karte gespeichert und später für andere Zwecke verwendet werden kann:

Zunächst müssen Sie eine entsprechende Berechtigung zum Speichern der Datei hinzufügen:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Und so sieht der Code aus (der in einer Activity läuft):

private void takeScreenshot() {
    Date now = new Date();
    android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);

    try {
        // image naming and path  to include sd card  appending name you choose for file
        String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";

        // create bitmap screen capture
        View v1 = getWindow().getDecorView().getRootView();
        v1.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        v1.setDrawingCacheEnabled(false);

        File imageFile = new File(mPath);

        FileOutputStream outputStream = new FileOutputStream(imageFile);
        int quality = 100;
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
        outputStream.flush();
        outputStream.close();

        openScreenshot(imageFile);
    } catch (Throwable e) {
        // Several error may come out with file handling or DOM
        e.printStackTrace();
    }
}

Und so können Sie das kürzlich erstellte Bild öffnen:

private void openScreenshot(File imageFile) {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    Uri uri = Uri.fromFile(imageFile);
    intent.setDataAndType(uri, "image/*");
    startActivity(intent);
}

Wenn Sie dies in der Fragmentansicht verwenden möchten, verwenden Sie:

View v1 = getActivity().getWindow().getDecorView().getRootView();

anstelle von

View v1 = getWindow().getDecorView().getRootView();

auf takeScreenshot() Funktion

Hinweis :

Diese Lösung funktioniert nicht, wenn Ihr Dialog eine Oberflächenansicht enthält. Für Details lesen Sie bitte die Antwort auf die folgende Frage:

Android Screenshot von Surface View zeigt schwarzen Bildschirm

163voto

JustinMorris Punkte 7099

Rufen Sie diese Methode auf und übergeben Sie die äußerste ViewGroup, von der Sie ein Bildschirmfoto erstellen möchten:

public Bitmap screenShot(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
            view.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

43voto

Hinweis: Funktioniert nur bei gerooteten Handys

Programmatisch können Sie Folgendes ausführen adb shell /system/bin/screencap -p /sdcard/img.png wie unten

Process sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/img.png").getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();    

dann lesen img.png als Bitmap und nach Belieben verwenden.

31voto

Jeegar Patel Punkte 24720

Keine Root-Erlaubnis ou keine große Kodierung ist für diese Methode erforderlich.


Auf der adb-Shell können Sie mit dem folgenden Befehl einen Screenshot erstellen.

input keyevent 120

Dieser Befehl erfordert keine Root-Berechtigung, so dass Sie ihn auch über den Java-Code der Android-Anwendung ausführen können.

Process process;
process = Runtime.getRuntime().exec("input keyevent 120");

Mehr über Keyevent-Code in Android siehe http://developer.Android.com/reference/Android/view/KeyEvent.html

Hier haben wir verwendet. KEYCODE_SYSRQ sein Wert ist 120 und wird für die Taste Systemanfrage / Bildschirm drucken verwendet.


Wie CJBS sagte, wird das Ausgabebild in /sdcard/Bilder/Screenshots

19voto

Rui Marques Punkte 7344

Eine Möglichkeit, den Bildschirm (und nicht nur die Anwendungsaktivität) zu erfassen, ist die Erfassung der Framebuffer (Gerät /dev/graphics/fb0). Dazu müssen Sie entweder Root-Rechte haben oder Ihre App muss eine App mit Signaturberechtigungen ("Eine Erlaubnis, die das System nur erteilt, wenn die anfragende Anwendung mit demselben Zertifikat signiert ist wie die Anwendung, die die Erlaubnis erklärt hat") - was sehr unwahrscheinlich ist, es sei denn, Sie haben Ihr eigenes ROM kompiliert.

Jedes Framebuffer-Capture von einigen Geräten, die ich getestet habe, enthielt genau ein Bildschirmfoto. Es wurde berichtet, dass er mehr enthält. Ich schätze, das hängt von der Bild-/Anzeigegröße ab.

Ich habe versucht, den Framebuffer kontinuierlich zu lesen, aber es scheint für eine feste Anzahl von Bytes gelesen zurückzukehren. In meinem Fall sind das (3 410 432) Bytes, was ausreicht, um ein Bild von 854*480 RGBA (3 279 360 Bytes) zu speichern. Ja, das von fb0 ausgegebene Bild in binärer Form lautet RGBA in meinem Gerät. Dies wird wahrscheinlich von Gerät zu Gerät abhängen. Dies wird für Sie wichtig sein, um es zu entschlüsseln =)

In meinem Gerät /dev/graphics/fb0 Berechtigungen sind so, dass nur Root und Benutzer der Gruppe graphics die fb0 lesen können.

Grafik ist eine eingeschränkte Gruppe, so dass Sie wahrscheinlich nur mit einem gerooteten Telefon über den Befehl su auf fb0 zugreifen können.

Android-Apps haben die Benutzerkennung (uid) = app_## y gruppe id (guid) = app_## .

Adb-Shell a uid = shell y guid = Schale die viel mehr Berechtigungen hat als eine App. Sie können diese Berechtigungen unter /system/permissions/platform.xml überprüfen

Das bedeutet, dass Sie fb0 in der adb-Shell ohne Root lesen können, aber Sie können es nicht innerhalb der App ohne Root lesen.

Auch die Vergabe von READ_FRAME_BUFFER- und/oder ACCESS_SURFACE_FLINGER-Berechtigungen in der Datei AndroidManifest.xml bringt für eine normale App nichts, da diese nur für ' Unterschrift ' Apps.

Prüfen Sie auch dies geschlossenes Thema für weitere Einzelheiten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X