Über dieses Blog...

»Wenn ich einmal alt bin, werde ich nur nörgeln — das wird ein Spaß!«

Tipps und Tricks, aber auch Kritik - breit gefächert von Technik bis hin zum Design, manchmal (oder immer öfter) auch Politik.

Momentaner Fokus: Android/Java, CalDAV, Windows 7 benutzbar machen

Feeds

Interessant gefunden? Mitlesen? Vollständige Beiträge per Feed.

RSS-Feed RSS 2, Atom

Zur Weiterverarbeitung oder zum Einbauen für Ihre Homepage: CSV, JavaScript

Durchsuchen

Tipp: AND & && OR | || XOR - ! NOT ( )

Archiv

Einträge im Februar 2012
MoDiMiDoFrSaSo
12345
6789101112
13141516171819
20212223242526
272829
Beiträge im Archiv zeigen

Android-App: XConstruction + Lösung

Ein Android-Spiel, das mir neuerdings recht viel Freude bereitet, ist XConstruction. In dem Spiel muss man Eisenbahnbrücken bauen, die einen Zug tragen können (der nett animiert darüber fährt *g*). Die Physik-Engine ist zwar nicht das Gelbe vom Ei, aber durchaus brauchbar, um Spielspaß aufkommen zu lassen.

Der Level, der mich bisher am meisten Nerven gekostet hat, ist dabei Level 7 — deshalb hier meine Lösung. Da ich das Bild nicht direkt einbinden will und ich keine Spoiler-Funktionalität hier habe, bitte unten den Dateianhang direkt auswählen.

Zugegeben, ich habe auch erst im Netz gesucht, wie man das angehen sollte — immerhin hat das Abstützen auf dem Boden vorher (in den Leveln vorher) nie so richtig geklappt, deshalb hatte ich das gar nicht mehr versucht. Den Rest werd ich aber wieder komplett selbst machen :) Wer trotzdem Lösungen will, findet hier Ansätze: 1-5 und 6-10. Von dort hab ich auch die Inspiration mit dem Abstützen, konnte aber die dortige Lösung nochmals überbieten im Verbrauch (die übrigens nicht funktioniert hat, wie schon dort von „mit viel Glück“ geahnt werden konnte).

Android: Sensor verwenden - Helligkeit auslesen

Und wieder ein Traum zerplatzt: Da ja Android-Geräte häufig einen Helligkeitssensor verbaut haben, dachte ich — aus Entwicklersicht gesehen — an so etwas wie einen Belichtungsmesser für Fotografen, insbesondere um bspw. die Stärke eines Blitzes ausmessen zu können. Dummerweise reagiert bspw. mein Sensor nur ab Lichtschwankungen, die ungefähr eine Sekunde Mindestdauer haben. Bei Blitzen, die kürzer als 1/1000 und so sind, leider inakzeptabel.

Hier trotzdem mal der Code bzw. das Vorgehen:

import android.hardware.*;

Wichtig :)

public class TestActivity extends Activity implements SensorEventListener {
    SensorManager sm;
    TextView tv;

Wir benötigen einen SensorEventListener, wofür sich im Moment die Klasse anbietet, und etwas zum Anzeigen.

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv = new TextView(this);
        setContentView(tv);
        sm = (SensorManager)getSystemService(SENSOR_SERVICE);
    }

Hier ist die Zeile mit dem SensorManager wichtig.

    protected void onResume() {
        super.onResume();
        sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_FASTEST);
    }
    
    protected void onStop() {
        super.onStop();
        sm.unregisterListener(this);
    }

Die Sensor-Events sollten aus Akkugründen nur bei aktivierter Anwendung verarbeitet werden, deshalb in onResume und onStop die entsprechenden Vorgänge. Möglicherweise ist es eine gute Idee, sm.getDefaultSensor vor dem Weiterreichen zu prüfen. Gibt die Funktion null zurück, gibt es nämlich keinen Sensor :)

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
    public void onSensorChanged(SensorEvent event) {
        tv.setText(„Aktuell: „+event.values[0]);
    }

Auch hier sollte man aufpassen, dass event.values auch tatsächlich ein Element enthält, sonst schmiert's ab, aber generell funktioniert's so.

Android: ContextMenu in einer ListView anzeigen

Ein ContextMenu für eine ListView kann man relativ einfach anzeigen. Erst mal muss man ihm sagen, wer das Ding erzeugen soll:

lvResults.setOnCreateContextMenuListener(this);

Dazu implementiert man das entsprechende Interface und schreibt sich eine Funktion der folgenden Art:

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    menu.setHeaderTitle(„Menü-Titel“);
    menu.add(ContextMenu.NONE, 123, ContextMenu.NONE, „Eintrag 1“);
    menu.add(ContextMenu.NONE, 124, ContextMenu.NONE, „Eintrag 2“);
}

Reagieren darauf ist auch nicht weiter schwer:

public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        …

Theoretisch gibt's, um herauszukriegen, auf welchen Eintrag sich die gewählte Aktion nun beziehen soll, die Funktion getSelectedItem() — stellt die ListView einfach so bereit. Nun kommen wir allerdings zu dem Haken an der Sache: Wählt man Einträge mit der Hand über Touchscreen an, behalten diese ihre Markierung nicht — diese verschwindet, sobald man loslässt bzw. ein Menü angezeigt wird.

Die Folge: Die Funktionen mit getSelected… liefern immer -1. Grundsätzlich. Das ist natürlich nicht das, was wir eigentlich erwartet hätten und stellt uns vor eine neue Herausforderung, die nicht ohne weiteres lösbar zu sein scheint. Die Click-Ereignisse (insbesondere das LongClick, bei dem ja das Menü angezeigt wird) werden nicht ausgelöst.

Ich habe das Problem vorerst einfach mal so gelöst: Zuerst setze ich die Eigenschaft LongClickable auf false.

lvResults.setLongClickable(false);

Anschließend taucht natürlich kein ContextMenu mehr auf. Das muss man nun selbst tun, dafür hab ich mir erst mal das normale Click-Menü rausgesucht:

lvResults.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        lvResultsSelected = position;
        lvResults.showContextMenu();
    }
});

Darin wird die Position zwischengespeichert (wird dankenswerterweise übergeben) und das Menü per Hand aufgerufen. Inwiefern das jetzt bei einem LongClick noch funktioniert, wäre natürlich die nächste Frage… Ausprobiert habe ich es nicht, aber vermutlich gibt es sowieso noch eine elegantere Lösung für das Problem, die Workarounds unnötig macht.

Android: Such-Textfeld

Eine interessante Aufgabe ist es, eine Suchbox zu realisieren, in die der Nutzer nacheinander Zeichen eingeben kann und keinen Suchbutton betätigen muss. Dazu muss also nach einer Eingabe automatisch losgesucht werden. Wenn die Suche allerdings länger dauert, sollte man das nicht sofort, sondern mit einer kleinen Verzögerung machen.

Android bietet dafür eine CountDownTimer-Klasse an, die man dazu hernehmen kann (lastTvSearchIdx ist ein int auf Klassenebene, startSearch die entsprechende Suchfunktion):

public void afterTextChanged(Editable arg0) {
    final int myCounter = ++lastTvSearchIdx;
    new CountDownTimer(2000, 250) {
        public void onTick(long millisUntilFinished) {
            if (myCounter < lastTvSearchIdx) cancel();
        }
        public void onFinish() {
            if (myCounter == lastTvSearchIdx) startSearch();
        }
    }.start();
}

Möglicherweise kann man das noch sinnvoller implementieren, aber zumindest funktioniert es.

Ältere Einträge - Alle Nachrichten finden Sie im Archiv.

Register