1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Screenshot einer Activity erstellen und abspeichern

Dieses Thema im Forum "Android OS Entwicklung / Customize" wurde erstellt von FelixL, 29.09.2010.

  1. FelixL, 29.09.2010 #1
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Ich versuche Änderungen am System vorzunehmen, um bei jedem Aufrufen von onPause einen Screenshot der Activity abzuspeichern.

    (Der Grund dafür ist eigentlich hier angegeben, falls es jemanden interessiert:
    http://www.android-hilfe.de/android-app-entwicklung/46480-failed-binder-transaction.html
    Ich will die offizielle Api erhalten, aber trotzdem Screenshots in der vollen Auflösung bekommen.)

    Dafür muss ich einige Änderungen im System vornehmen, vor allem in der Datei ActivityThread.java:
    android.git.geo.kernel.org Git - platform/frameworks/base.git/blob - core/java/android/app/ActivityThread.java

    Das hier sind meine Veränderungen:
    Dieser Teil wird aufgerufen wenn die Activity pausiert wird. Ich hab sie in die Funktion performStopActivityInner() eingefügt, direkt hinter
    //info.thumbnail = createThumbnailBitmap(r);
    (Das ist die deaktivierte offizielle Api.)

    Der Code macht nicht viel, er ruft nur eine eigene Funktion für die eigentliche Erstellung des Screenshots auf, und speichert diese Bitmap dann mittels openFileOutput().
    Code:
    
                    	Bitmap bigThumbnail = createBigThumbnailBitmap(r);
                    	if (bigThumbnail != null){
                    		try {
                    			   FileOutputStream fos= r.activity.openFileOutput("applicationThumbnail.jpg",
                    			      Context.MODE_WORLD_READABLE);
    
                    			   bigThumbnail.compress(Bitmap.CompressFormat.PNG, 90, fos);
    
                    			   fos.flush();
                    			   fos.close();
                    			   } catch (Exception e) {
                    			   Log.e("BigThumbnailAddon", e.toString());
                    			}
                    	}
    Das ist meine veränderte createThumbnailBitmap(r):
    Code:
    private int mBigThumbnailWidth = -1;
        private int mBigThumbnailHeight = -1;
        
        private final Bitmap createBigThumbnailBitmap(ActivityRecord r) {
            Bitmap bigThumbnail = null;
            try {
                int w = mBigThumbnailWidth;
                int h;
                if (w < 0) {
                    Resources res = r.activity.getResources();
                    mBigThumbnailHeight = h =
                        res.getDimensionPixelSize(com.android.internal.R.dimen.big_thumbnail_height);
    
                    mBigThumbnailWidth = w =
                        res.getDimensionPixelSize(com.android.internal.R.dimen.big_thumbnail_width);
                } else {
                    h = mBigThumbnailHeight;
                }
    
                // XXX Only set hasAlpha if needed?
                bigThumbnail = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
                bigThumbnail.eraseColor(0);
                Canvas cv = new Canvas(bigThumbnail);
                if (!r.activity.onCreateThumbnail(bigThumbnail, cv)) {
                	bigThumbnail = null;
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                            "Unable to create bigThumbnail of "
                            + r.intent.getComponent().toShortString()
                            + ": " + e.toString(), e);
                }
                bigThumbnail = null;
            }
    
            return bigThumbnail;
        }
    Was noch zu sagen ist:
    ich hab keine Ahnung wie ich ein ganzes Android quasi in Eclipse importieren kann oder sowas, um dort schon mal Fehlermeldungen auszuschließen. Ich hab nur mal die Activity-Tread.java importiert, und die meisten Fehler konnte ich damit erschlagen. Die die jetzt noch angezeigt werden liegen (hoffentlich) an fehlenden Importen und Klassen drumrum.

    Jetzt sind für mich allerdings noch einige Fragen offen:
    1) Ich will in values.xml in der framework.res zwei weitere Werte hinzufügen.
    Dort gibt es schon
    thumbnail_width und thumbnail_height
    ich will
    big_thumbnail_width und big_thumbnail_height
    mit einbauen, funktioniert das einfach so das ich sie dort einfach nur hinzufüge und das System findet sie?
    Bei einer normalen Android-App ist das ja ähnlich aufgebaut, aber hab ich was vergessen was Eclipse vielleicht automatisch macht?

    2) Ich will dann in der Activity die Funktion openFileOutput() aufrufen, die als default in den Ordner data/data/packagename speichert. Andere Funktionen der Activity werden einfach über r.activity.FUNKTION aufgerufen, das sollte dann hier auch so klappen, oder?
    Beispiel:
    Zeile 3642 r.activity.onDestroy();

    Glaubt ihr das funktioniert so?
    Ich kompiliere das ganze dann nicht selbst sondern gebe es an Feeyo weiter, ist es ein großer Aufwand das zu machen?

    Wäre sehr cool wenn jemand irgendwas dazu sagen kann, da ich mir ein einerseits relativ sicher bin das das funktioniert, sowas aber zum ersten mal mache und es nicht selbst testen kann.
     
    Zuletzt bearbeitet: 29.09.2010
  2. Fr4gg0r, 30.09.2010 #2
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    befindet sich in /system/framework/core.jar bzw. wenn du kein deodexed rom hast, wovon auszugehen ist, dann in core.odex.
    Also zuerst die core.odex deodexen mit baksmali, dann mit smali classes.dex erstellen und in die core.jar packen; anschließend kannst du es mit apktool dekompilieren.

    Dann findest du dort irgendwo deine gesuchte Klasse, diese enthält dann aber keinen java code, sondern irgendwas anderes. :D
    Es soll wohl gehen, in diesen code java code einzufügen; anschließend mit apktool wieder kompilieren und aufs Gerät pushen.

    Gibt von JesusFreeke (Entwickler von apktool) ein Video dazu auf Youtube.

    Achso, du willst dir den Source vom git ziehen und dein eigenes framework bauen..
     
    Zuletzt bearbeitet: 30.09.2010
    FelixL bedankt sich.
  3. FelixL, 30.09.2010 #3
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Um die Uhrzeit bin ich auch nicht mehr so aufnahmefähig, macht nix :D
    Es war aber ansich schon richtig das ich den Code einfach nur zum Laufen bringen will.
    Die baksmali-Variante ist für mich aber quasi raus, da ich ja z.B. den einen Teil meines Codes an der richtigen Stelle einfügen muss, und ich nicht glaube das ich diese finde ;)

    Wenn es komplizierter wird den Code zum laufen zu bringen, du aber auch glaubst das das so funktioniert, dann geb ich den anstrengenden Teil einfach an Feeyo ab, der kann das besser :p
     
  4. Fr4gg0r, 30.09.2010 #4
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    ach, Code finden ist eigentlich nicht das hauptproblem.
    Du kennst den Code ja von AOSP, und der in deinem handy wird sich wohl davon nicht unterscheiden.

    Methodennamen und Variablennamen bleiben nämlich erhalten. ;)
     
  5. FelixL, 30.09.2010 #5
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Gut, dann probiere ich diese Variante am Wochenende (vorher leider keine Zeit :/):

    Hab auch in dem Code da oben noch vergessen das ich die Werte für die Größe je nach Orientierung (Landscape/Portrait) tauschen muss.
    Aber wie gesagt, mal sehen was das Wochenende bringt.
    Danke für deine Hilfe.

    Nachschlag: Hey, dann kann ich mir am Wochenende ein aktuelles Rom drauf ziehen und muss nicht mehr mit ner älteren Version arbeiten nur weil dort die offizielle Api aktiviert ist. Genial :)
    Wenn das so funktioniert wie du das sagst ist das echt einfach...genial ^^
     
  6. FelixL, 30.09.2010 #6
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Code:
        private final Bitmap createBigThumbnailBitmap(ActivityRecord r) {
            Bitmap bigThumbnail = null;
            try {
                int w = mBigThumbnailWidth;
                int h;
                Resources res = r.activity.getResources();
                if (w < 0) {
                    mBigThumbnailHeight = h =
                        res.getDimensionPixelSize(com.android.internal.R.dimen.big_thumbnail_height);
    
                    mBigThumbnailWidth = w =
                        res.getDimensionPixelSize(com.android.internal.R.dimen.big_thumbnail_width);
                } else {
                    h = mBigThumbnailHeight;
                }
                //Swap values depending on orientation:
                if (res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                	int tmpSwap = h;
                	h = w;
                	w = tmpSwap;
                }
                // XXX Only set hasAlpha if needed?
                bigThumbnail = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
                bigThumbnail.eraseColor(0);
                Canvas cv = new Canvas(bigThumbnail);
                if (!r.activity.onCreateThumbnail(bigThumbnail, cv)) {
                	bigThumbnail = null;
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                            "Unable to create bigThumbnail of "
                            + r.intent.getComponent().toShortString()
                            + ": " + e.toString(), e);
                }
                bigThumbnail = null;
            }
    
            return bigThumbnail;
        }
    Jetzt auch orientation-aware ;)
     
  7. FelixL, 30.09.2010 #7
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Das Rom ist anscheinend deodexed, eine core.odex findet er nicht, dafür aber die core.jar, die auch eine classes.dex enthält. Wenn ich jetzt noch den Code finden würde ;)

    Im Ernst, hast du ne Ahnung in welcher Unterdatei das das sein könnte? Ich finde da Haufenweise allgemeinen Java-Zeug, aber nichts was nach Android aussieht...ausser einem Dalvik-Verzeichnis.
    Kann ich dir die core.jar mal schicken?
     
  8. Fr4gg0r, 30.09.2010 #8
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    ist doch gut, wenn es ein deodexed rom ist.
    Dann einfach mit apktool dekompilieren.
    Anschließend hast du einen Ordner mit dem ganzen Code unso.
    Anschließend hast du für jedes Package einen Ordner.. also java, android, app, etc. und in diesen befinden sich die .smali files.
     
  9. FelixL, 30.09.2010 #9
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Ja, apktool hatte ich schon benutzt, hatte mir das mal so erschlossen das die ersten Schritte einfach wegfallen ;)

    Ordnerstruktur:
    -apktool.yml
    -smali
    com
    dalvik
    java
    javax
    junit
    org
    SQLite
    sun

    Um nur mal die obersten Ordner zu zeigen.
    Manche haben noch Unterordner, in manchen sind auch direkt die smali-Dateien.
    Aber wie gesagt, ich finde nichts was in die Richtung Android oder ActivityThread gehen könnte :/
     
  10. Fr4gg0r, 30.09.2010 #10
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    haha
    ich will mich gerade auch dort zu schaffen machen (an der Activity.java) und finde die auch nicht in der core.jar :cursing:

    Edit: habs. guck in die framework.jar
     
    Zuletzt bearbeitet: 30.09.2010
  11. FelixL, 30.09.2010 #11
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    :D
    Wenn du was rausfindest, sag Bescheid. Ich hab keine Ahnung ^^
     
  12. FelixL, 30.09.2010 #12
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Nachschlag: Vielleicht doch...
    apktool macht ja auch erst mal ne Runde baksmali. baksmali hatte aber lange Probleme mit Froyo-Apps. Vielleicht liegt es daran, das die baksmali-Version in apktool veraltet ist?
     
  13. Fr4gg0r, 30.09.2010 #13
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    siehe edit :p
     
  14. FelixL, 30.09.2010 #14
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Das ist natürlich besser.
    Ich machs trotzdem erst morgen, muss erst mal das Galaxy meiner Freundin mit der neuesten Nigthly beglücken ;). Danke für die ganzen Infos!
     
  15. Fr4gg0r, 30.09.2010 #15
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
  16. Fr4gg0r, 01.10.2010 #16
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    da apktool ja nicht geht, muss ich auf die java Methode verzichten. :mellow:
    Nur leider gibt smali garkeinen Output wenn beim rekompilieren von smali code iwas nicht stimmt. Der kompiliert dann die entsprechenden Klassen einfach nicht und der boot prozess verwandelt sich eine reboot schleife. -_-
     
  17. FelixL, 02.10.2010 #17
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Ich hab grad mal die framework.jar mit apktool decompiliert, ohne Änderung compiliert und über ein update.zip gepusht. erstes hochfahren hat lange gedauert (ca. 10 min) dann war es sehr langsam am Anfang, aber es hat funktioniert.
    Hast du es anders gepusht oder Änderungen an der framework.jar gemacht?
    Wenn du es nur anders gepusht hast, versuch es mal mit einer update.zip, die framework-res.apk geht afaik auch nur so ohne reboots.
     
  18. FelixL, 03.10.2010 #18
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Einfach einfügen und mit apktoo kompilieren ist leider nicht möglich.
    Der regt sich schon über alle { auf :D

    Also muss ich schauen ob ich das in smali-Code geschrieben bekomme, oder eine App bauen die den Java-Code beinhaltet, den mit apktool auseinandernehmen, und dann rüberkopieren :D
    Oder vielleicht einfach doch Feeyo fragen...
     
  19. Fr4gg0r, 03.10.2010 #19
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    So langsam kann ich smali besser als Java ;)
     
  20. FelixL, 03.10.2010 #20
    FelixL

    FelixL Threadstarter Ehrenmitglied

    Beiträge:
    4,855
    Erhaltene Danke:
    754
    Registriert seit:
    26.11.2009
    Phone:
    Wileyfox Swift, HTC One M8
    Na dann lass deiner Lust ruhig freien Lauf, der Code steht auf der ersten Seite :D

    Ich mach das morgen Früh, die Laune meiner Freundin sinkt gerade exponentiell...
     

Diese Seite empfehlen