Wie kann ich einen Screenshot von einem ausgewählten Bereich des Telefondisplays nicht mit einem Programm, sondern mit Code erstellen?
Antworten
Zu viele Anzeigen?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
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;
}
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.
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
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.
- See previous answers
- Weitere Antworten anzeigen