2014-04-27

Pimp my FairPhone

In meinem Post über 100 Tage FairPhone hatte ich das Dilemma mit dem zu kleinen internen Speicher beklagt. Dabei ist die Lösung eigentlich simpel: in dem von mir ebenfalls verlinkten Foren-Thread wird mehrfach auf die Damen und Herren von xda developers verwiesen. Dort findet sich eine Schritt-für-Schritt-Anleitung. Diese enthält den Link zu einer Software, die das FairPhone umpartitioniert. Man muss sich nur trauen, die App zu installieren und zu starten. In einer Auswahl kann man zwischen mehreren Speicherzuteilungen wählen. Ich habe mich für 4 GB internen Speicher entschieden. Nach dem obligatorischen Boot in den Recovery Mode von Android folgt man ein paar Anweisungen. Und hat dann ein frisch aufgesetztes System ohne Speichersorgen. Ganz wichtig: bei der Prozedur gehen alle Daten verloren, ein Backup auf eine SD-Karte ist also angeraten. Da ich ein frisches System wollte, habe ich mich dagegen entscheiden.
Android-Bootoptionen
Mein FairPhone nach der Umpartitionierung
Für mich hat sich dieser kleine Eingriff gelohnt; mein FairPhone hat wieder die Apps drauf, die ich brauche. Man darf gespannt sein, was nach dem angekündigten Softwareupdate passiert. Ich werde natürlich berichten.

2014-04-26

Tipp: Was es mit NPEs in updateInputState() auf sich hat

Ich wurde von einer Firma angeschrieben, die im Auftrag eines Geräteherstellers Fehlern in Android-Apps nachgeht. Die Fehlerbeschreibung schien zunächst unspezifisch; nachstellen konnte ich das Problem nicht. Allerdings liefert die Developer Console ja zum Glück tiefere Einblicke in die Abstürze:

 

java.lang.RuntimeException: Unable to pause activity {com.thomaskuenneth.android.birthday/com.thomaskuenneth.android.birthday.TKBirthdayReminder}: java.lang.NullPointerException
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3204)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3159)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3137)
at android.app.ActivityThread.access$900(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1337)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5450)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.widget.TimePicker.updateInputState(TimePicker.java:846)
at android.widget.TimePicker.onSaveInstanceState(TimePicker.java:561)
at android.view.View.dispatchSaveInstanceState(View.java:13117)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2822)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.View.saveHierarchyState(View.java:13100)
at com.android.internal.policy.impl.PhoneWindow.saveHierarchyState(PhoneWindow.java:1930)
at android.app.Dialog.onSaveInstanceState(Dialog.java:405)
at android.app.TimePickerDialog.onSaveInstanceState(TimePickerDialog.java:216)
at android.app.Activity.saveManagedDialogs(Activity.java:1269)
at android.app.Activity.performSaveInstanceState(Activity.java:1187)
at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1240)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3185)
... 12 more

Warum sollte eine interne Methode meine App abstürzen lassen? Erstaunlicherweise liefert die Suche nach updateInputState hilfreiche Treffer, unter anderem diesen. Dort steht:

When running on an ICS device, but using against an old build target the TimePicker shows the older AM/PM button instead of the newer spinner. This is dealt with in code for backwards compatibility - TimePicker.java attaches listeners either to mAmPmButton or mAmPmSpinnerInput accordingly. There are checks in most applicable to handle the appropriate case. The function updateInputState() however has no check and is blindly assuming mAmPmSpinnerInput isn't null. This will cause a force close on apps using it that have an active InputMethodManager at the time (line 553 in TimePicker.java).

TKBirthdayReminder ist in der noch aktuellen Version 2.0.6 tatsächlich auf API Level 7 eingestellt, läuft also im Kompatibilitätsmodus. Ich werde den jetzt mal auf 17 setzen und sehen, was passiert. Haben Sie ähnliche Phänomene beobachtet? Schreiben Sie mir…

2014-04-24

100 Tage FairPhone

Am 15. Januar 2014 wurde nach einer gefühlten Ewigkeit mein FairPhone geliefert. Ich hatte meine ersten Eindrücke in diesem Post mit Ihnen geteilt. Seitdem sind etwa 100 Tage vergangen. Ich habe das Gerät jeden Tag intensiv genutzt: als Telefon, als Adressbuch, als Notizspeicher, als Kamera… Dabei hat sich das nicht ganz leichte Klötzchen als durchweg alltagstauglich erwiesen. Die Verarbeitung ist gut, die Laufzeit des Akkus passt gerade noch (man übersteht einen Tag ganz gut), die Kamera ist ok, die Software halbwegs stabil.
Ein ganz dickes Problem gibt es aber:
Screenshot_2014-04-23-10-45-58
Das FairPhone hat zu wenig Speicher. Das mag sich merkwürdig anhören, wenn man liest, dass es mit 16 GB ausgestattet ist. Der so genannte interne Speicher ist 1 GB groß. Und der macht Kummer. Denn man kann viele Apps in den so genannten Telefonspeicher verschieben, aber nicht alle. Schon bei wenigen installierten Apps tauchen bei mir regelmäßig Meldungen auf, dass dieser oder jener Dienst aufgrund von Speichermangel gestoppt wird. Im Forum gibt es hierzu einen laaaaaangen Thread, in dem der Tenor der FairPhone-Angestellten ist, dass das alles ja gar nicht so schlimm sei. Ist es aber leider. Es scheint, dass sich im Laufe der Zeit Müll ansammelt, weil z. B. Logfiles anschwellen. Die Option, den internen Speicher bei einem Software-Update zu vergrößern, wurde bisher nicht genutzt.
Für mich schränkt das die Nutzbarkeit des Geräts leider ziemlich ein. Zumal ich kein App-Junkie bin, der unzählige Programme hortet.
Hergeben werde ich das FairPhone deshalb aber nicht. Das Experiment geht weiter…

2014-04-22

Bilder-Tour: In Visual Studio Express 2013 ein Projekt zu einem Git-Repository hinzufügen

Nicht nur in Java kann Git Spaß machen. Ganz ehrlich, sauberer kann man eine Versionsverwaltung nicht integrieren. Top!
Auswahl der Versionsverwaltung
Ausgabe in der Console
Kontextmenü
Der erste Commit

2014-04-20

WinMerge-Tipp: Vergleichen von Word-Dateien

Nach dem Buch ist vor dem Buch. Bevor die eigentliche Arbeit losgeht, bringt man seine Werkzeuge auf den aktuellen Stand. Früher hieß dies Bleistift spitzen oder neues Farbband in die Schreibmaschine einlegen. Und heute? Hardware aktualisieren. (Kleiner Scherz) Da ich mir erst vor kurzem einen der letzten Vaio Pro 13 gegönnt habe, fehlt dem guten Stück noch die eine oder andere Software. WinMerge ist seit langem eine der Perlen, die auf keinem Rechner fehlen sollte. In der stabilen Version 2.14.0 ist ein Plug-in zum Vergleichen von Word-Dateien enthalten. Hier ein Screenshot:
eingebautes WinMerge-Plug-in
Seit wann dem so ist, weiß ich offen gesagt nicht. Ich hatte bislang nämlich xdocdiff von S. Kohno verwendet. Heute bin ich eher zufällig über das eingebaute Modul gestolpert. An dem ist praktisch, dass es (wie auf dem Screenshot zu sehen ist) bestimmte Attribute wie Autor und Beschreibung der Worddatei anzeigt. Dies tut xdocdiff nicht. Allerdings geht dieses meiner Wahrnehmung nach erheblich schneller zu Werke. Die Installation von xdocdiff ist schnell erledigt. Nach dem Entpacken des Archivs werden die beiden Dateien xdoc2txt.exe und zlib.dll in das WinMerge-Installationsverzeichnis kopiert. Die Datei amb_xdocdiffPlugin.dll muss in das Unterverzeichnis MergePlugins.
Tipp: Achten Sie darauf, dass vor dem Vergleichsvorgang im Plugins-Menü das automatische Entpacken aktiviert ist. Und: um xdocdiff zu deaktivieren, einfach amb_xdocdiffPlugin.dll in .dl_ umbenennen und Plugins neu laden auswählen.

2014-04-13

Tipp: bessere Vorschläge in Eclipse

Vor einigen Wochen bin ich über die Bing Code Search für Visual Studio gestolpert. Die Idee dieses Plug-ins ist, die klassischen “Wie geht denn das?”-Fragen direkt aus der IDE heraus zu stellen. Fundstellen können dann unmittelbar übernommen werden. Auf Channel 9 gibt es ein Video dazu. Natürlich kann man darüber streiten, ob auf diese Weise bessere oder schlechtere Programme entstehen. Ob man aber Code direkt aus Stack Overflow kopiert oder dafür ein Tool nutzt, ist egal. Wie bei allen Werkzeugen ist es am Nutzer, es maß- und sinnvoll zu verwenden.
Da ich die Idee grundsätzlich sehr gut finde, habe ich mich gefragt, ob es so etwas ähnliches auch für Eclipse gibt. Dabei bin ich auf das Projekt CODE RECOMMENDERS gestoßen. Dieses Plug-in integriert sich in die Content Assist-Funktion von Eclipse. Um Code Recommenders in der aktuellen Version verwenden zu können, muss mindestens Eclipse 4.2 installiert sein. Öffnen Sie über Help, Install new Software den Dialog Install und fügen im Eingabefeld neben Work with die URL der Plug-in-Update Site (http://download.eclipse.org/recommenders/updates/stable/) ein. Drücken Sie Enter, um die Liste der Plug-ins zu aktualisieren.
Installation des Plug-ins
Nach dem Download und dem obligatorischen Neustart steht das Plug-in zur Verfügung.
Die Einstellungsseite des Plug-ins
Um das Plug-in auszuprobieren, legen Sie am besten ein einfaches Java-Projekt mit einer beliebigen Klasse an. Fügen Sie dieser eine main()-Methode hinzu und tippen dann:
Date
Mit Steuerung-Leertaste rufen Sie Content Assist auf.
Aktivierung des Plug-ins
Aktivieren Sie die intelligente Vervollständigung, indem Sie den entsprechenden Eintrag mit Doppelklick oder Enter auswählen. Weiteres Durchblättern mit Steuerung-Leertaste öffnet Eclipse-typisch verschiedene Proposals-Arten. Code Recommenders fügt unter anderem die folgenden hinzu:
  • Call Completion schlägt wahrscheinliche Methoden vor. Bei den Vorschlägen wird berücksichtigt, was andere Entwickler in einem vergleichbaren Quelltextumfeld an Methoden aufgerufen haben
  • Override Completion schlägt die Methoden vor, die am wahrscheinlichsten überschrieben werden sollten
  • Subwords Completion unterstützt alle anderen Vorschlagsmechanismen oder arbeitet für sich alleine; hiermit werden Vorschläge auch auf Basis von Teilwörtern innerhalb eines Worts gemacht, nicht nur von Beginn an
Lassen Sie uns nun etwas ausprobieren. Wir haben gehört, dass die Klasse Calendar Instanzen von Date-Objekten erzeugen kann. Nur, wie? Tippen Sie Date date = Calendar.get und drüclen dann Steuerung-Leertaste.
Ist Ihnen aufgefallen, dass die ersten drei Buchstaben (get) eine andere Farbe haben? Wählen Sie die parameterlose Variante von getInstance() und drücken Enter. Außer einem hinzugefügten import (und das würde Eclipse auch ohne das Plug-in tun) ist noch nichts passiert. Geben Sie nun einen Punkt ein.
Relevanz-basierte Vorschlagsliste
Im Gegensatz zur früher erscheinenden alphabetisch sortierten Methodenliste sehen Sie nun eine nach Relevanz sortierte Vorschlagsliste. Mit ihr ist unsere fiktive Fragestellung schnell geklärt.
Wie finden Sie die Idee dieses Plug-ins. Schreiben Sie mir. Ich werde jedenfalls weiter damit experimentieren.