Erfahrungen mit Madvertise

6. November 2011 2 Kommentare

Da ich beim diesjährigen Android DevCamp viel gutes über Madvertise gehört habe, habe ich testweise einen Madvertise-Banner in eine meiner Android Apps integriert. Nun ist der Banner schon über 4 Monate in der App und ich kann von den Erfahrungen mit Madvertise berichten.

Madvertise versucht im umkämpften Markt der Werbenetzwerke durch guten Support und Offenheit herauszustechen. Sie antworten stets schnell und persönlich auf Support-Anfragen. Außerdem haben sie meist eine hohe Erfüllungsrate die an die 100% geht und die Vergütung pro Klick ist verglichen mit Anbietern wie AdMob sehr hoch, was aber am Madvertise Developer Fund liegt.

Offenheit versucht Madvertise dadurch zu realisieren, dass alle SDKs als Open-Source zur Verfügung gestellt werden. Das ist zwar eine nette Idee, allerdings entspricht die Umsetzung ganz und gar nicht meinem Verständnis von Offenheit. Das Android SDK wurde fast während der gesamten 4 Monate kein einziges mal aktualisiert. Bei guter Code-Qualität könnte man ja zumindest argumentieren, dass das auch nicht nötig währe, aber das SDK ist voller Fehler und Memory-Leaks. Bug-Reports wurden während der gesamten Zeit gekonnt ignoriert. Auch war nirgends zu erkennen, ob an einer neuen Version gearbeitet wird bzw. wann diese erscheinen wird. Ohne selbst Hand anzulegen, war das SDK überhaupt nicht einsetzbar. Am 20. Oktober wurde dann eine neue Version veröffentlicht, ohne Ankündigung, Changelog usw. Das alles ist meiner Meinung nach alles andere als offen.

Bis heute hatte ich immer die Annahme, dass das SDK für Android deshalb so eine schlechte Qualität hatte, weil Madvertise momentan den Fokus noch auf iOS legt. Allerdings wurde ich jetzt eines Besseren belehrt. Heute wollte ich Madvertise mittels AdWhirl in eine iPhone App integrieren. Aufgrund einer Ankündigung an alle Madvertise Kunden im Juli und einem Eintrag im  Madvertise-Wiki war ich guter Hoffnung, dass das SDK eine AdWhirl Integration enthält. Genauere Forschungen in der Github Versiongeschichte haben aber ergeben, dass das neue SDK Anfang August stillschweigend zurückgezogen wurde. Als Commit-Kommentar wurde nur angegeben “removed bogus commit, update will follow soon“. Bis heute konnte ich nirgends eine Begründung oder ähnliches finden. Das ist ebenfalls alles andere als offen.

Zusätzlich zu dem Ärger mit den SDKs wurde mir einmal vorgeworfen ich hätte ein “Auffälliges Klickverhalten” produziert und mein Account wurde für 24 Stunden gesperrt. Tatsächlich hatte ich an dem Tag eine außergewöhnlich hohe Klickrate von der ich bis heute nicht weiß wie sie zustande kam. So etwas ist danach auch nie wieder vorgekommen. Vermutlich hat sich ein Benutzer aus welchen Gründen auch immer einen Scherz erlaubt und mehrmals auf den Banner geklickt. Eine Sperrung für 24 Stunden halte ich allerdings für weit überzogen. Warum wird der gesamte Account gesperrt und nicht einfach die IP-Adresse des Benutzers der das Klickverhalten verursacht hat, schließlich kann auf diese Weise ein böswilliger Benutzer einen großen Schaden verursachen? Bei einer Nachfrage beim Support erhielt ich dann als Antwort nur “Dies hat technische Gründe” — Wo bleibt die Offenheit? Außerdem wurde mir geraten, ich solle das Problem durch eine Klick-Begrenzungen selbst in der App lösen. Abgesehen davon, dass dadurch das Problem nur für Benutzer gelöst wird, die das Update installieren, finde ich nicht, dass es Aufgabe des Kunden sein sollte solche Beschränkungen einzubauen. Entweder das Problem wird am Server gelöst, oder im SDK von Madvertise.

Alles in allem muss ich aufgrund der gemachten Erfahrungen von Madvertise momentan noch abraten. Madvertise selbst empfehle ich, massiv an ihren SDKs zu arbeiten, andernfalls laufen die Publisher davon.

KategorienAllgemein Tags:

SamyGo Remote – Android als Samsung Fernbedienung

7. Februar 2011 79 Kommentare

qrcodeDank des SamyGo Projektes wurde mein gewöhnlicher Fernseher Samsung LE37B650 zum High-Tech Gerät. Da er einen Netzwerkanschluss besitzt und von Werk aus Linux darauf läuft, kann man damit einige Dinge anstellen. So kann man sich zum Beispiel einen Server installieren der Fernbedienungs-Signale auch per LAN annimmt. Dafür installiert man sich beispielsweise über die Content-Library die Anwendung “Remote Lan Control“. Wie das geht, wird unten erklärt. Für C-Serie und D-Serie Geräte ist das nicht einmal notwendig, diese haben einen entsprechenden Server von Haus aus installiert.

Da es für die B-Serie momentan nur einen Client für Windows gibt und der Android Client für die C-Serie und D-Serie nur auf Samsung Geräten läuft, habe ich einen Android-Client geschrieben. Das Ergebnis sieht folgendermaßen aus und kann ab sofort im Android Market heruntergeladen werden. Der Code steht unter der GPLv2 Lizenz und kann hier bezogen werden.

Die App funktioniert nur zusammen mit B-Series Fernsehern (Edit: Jetzt auch für C-Serie und D-Serie Fernseher, ohne “Remote Lan Control”) von Samsung, da “Remote Lan Control” momentan nur auf diesen Geräten läuft. Für C-Series Geräte gibt es zwar schon eine Ferbedienungs-App von Samsung, die läuft aber auch nur auf Samsung-Geräten. C-Series Geräte unterstützen deshalb schon von Haus aus das Empfangen von Fernbedienungs-Signalen über das Netzwerk (mittels UPnP), aber ich hab keine Ahnung wie ich das genau ansteuere. Falls jemand ein C-Series Gerät besitzt und interesse daran hat, dass die App auch mit diesen Fernsehern läuft, könnte z.B. mit dem UPnP Inspector versuchen mehr herauszufinden.

C-Serie Geräte werden jetzt auch unterstützt, und zwar ohne jegliche Modifikation des Fernsehers. Falls du trotzdem eine Anleitung brauchst, dann siehe unten!

Anleitung für B-Serie:

Da die SamyGo Seiten momentan etwas unübersichtlich sind, erkläre ich hier noch mal wie man “Remote Lan Control” auf seinem TV laufen lässt. Das Verfahren ist normalerweise relativ sicher, da nach einem Neustart alles wieder beim Alten sein sollte, aber ich übernehme keine Haftung für irgendwelche Schäden die dadurch entstehen.

  1. “Remote Lan Control” herunterladen: Klick mich
  2. Zip-Datei entpacken und auf einen USB-Stick kopieren (USB-Stick sollte in FAT32 formatiert sein)
  3. USB-Stick in den Fernseher einstecken
    • Wenn der Fernseher an ist, sollte jetzt nach einiger Zeit ein Fenster auftauchen, dort “Content Library” auswählen
    • Wenn der Fernseher nicht an war oder kein Fenster auftaucht, kann man auch manuell in die Content Library gehen (Knopf “CONTENT” auf der Fernbedienung und dann das Symbol ganz rechts auswählen)
  4. Jetzt links “USB” auswählen und dann auf Spiele (bzw. Games) gehen: ENTER
    • Falls es keinen Eintrag für “Spiele” gibt, kann man versuchen den Eintrag zu erstellen (Telnet muss dafür laufen). Wie das geht steht hier.
  5. Jetzt sollte eine Liste der auf dem USB-Stick verfügbaren Programme auftauchen. Dort “SamyGO Remote” auswählen und ENTER drücken. Dann kann man das Programm laufen lassen. Wenn man will, kann man es auch auf den internen Speicher des Fernsehers kopieren und von dort aus Starten, dann braucht man zukünftig keinen USB-Stick mehr eingesteckt zu haben
    • Falls jetzt eine Meldung “Nicht Verfügbar” kommt, dann bedeutet dass, dass du eine zu neue Firmware installiert hast. Das letzte Firmware-Update von Samsung hat solche Modifikationen unmöglich gemacht. Damit diese wieder möglich werden, musst du die Firmware downgraden. Wie das geht, steht hier.
  6. Es kommt KEINE Rückmeldung, dass das Programm gestartet wurde, aber es sollte nun gestartet sein
  7. Jetzt noch in der App die IP-Adresse konfigurieren. Die kann man über den Button “Automatisch finden” herausfinden. Falls der Fernseher nicht gefunden wird, ist man entweder nicht mit dem WLAN verbunden, das WLAN ist falsch konfiguriert oder der Fernseher wird nicht unterstützt.

Kleiner Wermutstropfen: Das Programm muss bei jedem Neustart des Fernsehers erneut ausgeführt werden. Momentan gibt es noch keine ganz einfache Lösung für das Problem. Die einzige Lösung ist, die Firmware zu modifizieren, die Modifikation auf den Fernseher aufzuspielen und dann mittels gdb (gdbtrick.sh) oder injectso die Applikation im Start-Script starten. Das ist aber nur für fortgeschrittene Benutzer etwas. Vielleicht erkläre ich das irgendwann mal in einem separaten Post. Mehr Informationen gibt’s auch hier.

Anleitung für C-Serie und D-Serie:

  1. Fernseher anschalten
  2. Damit die Fernbedienung funktioniert, muss vorher im Menü erst das Empfangen von Remote-Control Signalen über das Netzwerk aktiviert werden. Der entsprechende Menüpunkt befindet sich in den Systemeinstellungen. Falls es so einen Menüpunkt nicht gibt, wird der Fernseher leider nicht unterstützt.
  3. Handy per WLAN mit dem selben Netzwerk wie den Fernseher verbinden
  4. SamyGo Remote starten
  5. Menü -> Einstellungen -> Hostname -> Automatisch finden (Achtung, damit das automatische Finden funktioniert, muss der Fernseher in der selben Broadcast-Domäne wie das Handy sein. Manche Router wie die Fritz!Box haben eine Einstellung, die verhindert, dass Broadcast Pakete weitergeleitet werden. Bei der Fritz!Box muss man im Menüpunkt “Funkeinstellungen” das Häkchen bei “WLAN-Netzwerkgeräte dürfen untereinander kommunizieren” setzen)
  6. Falls ein Gerät gefunden wurde, ist dies an eine Vibration zu spüren. Der entsprechende TV-Typ wird automatisch eingestellt. Falls ihr ein C- oder D-Serie Gerät besitzt, es wurde jedoch B-Serie als Typ eingestellt, dann wird euer Fernseher nicht unterstützt.
  7. Falls kein Gerät gefunden wurde, könnt ihr noch versuchen die IP-Adresse des Fernsehers manuell herauszubekommen und in das Feld einzutragen.
  8. Jetzt müsste die Fernbedienung funktionieren

 

 

Android Cache

28. Dezember 2010 Kommentare ausgeschaltet

Häufig benötigt man in Android eine Möglichkeit Daten zu cachen, beispielsweise wenn Bilder aus dem Internet heruntergeladen werden, die an mehreren Stellen verwendet werden. Da Caches aber auch Speicher aufbrauchen und dieser auf Android-Geräten in der Regel knapp bemessen ist, muss eine Möglichkeit gefunden werden den Cache so zu organisieren, dass er bei Speichermangel Daten frei gibt. Dafür bietet sich die Klasse SoftReference an, die eine Referenz zu einem beliebigen Objekt enthält, das aber jederzeit vom Garbage Collector vernichtet werden darf (ganz stimmt das nicht, genauere Informationen in der Dokumentation). Daraus lässt sich dann ein flexibler Cache basteln, der automatisch ohne Zutun auf Speicherknappheit reagiert:

public class Cache<TKey, TValue> {

	private Map<TKey, SoftReference<TValue>> cache;

	public Cache() {
		 cache = new Hashtable<TKey, SoftReference<TValue>>();
	}

	public Cache(int capacity) {
		 cache = new Hashtable<TKey, SoftReference<TValue>>(capacity);
	}

	public void clear() {
		cache.clear();
	}

	public TValue get(TKey key) {
		synchronized (this) {
			SoftReference<TValue> valueReference = cache.get(key);
			if (valueReference != null) {
				TValue value = valueReference.get();
				if (value != null) return value;
				else cache.remove(key); // Garbage Collector freed the reference
			}
			return null;
		}
	}

	public TValue put(TKey key, TValue value) {
		synchronized (this) {
			SoftReference<TValue> newReference = new SoftReference<TValue>(value);
			SoftReference<TValue> previousValueReference = cache.put(key, newReference);
			if (previousValueReference != null) {
				TValue previousObject = previousValueReference.get();
				previousValueReference.clear(); // Free the reference
				return previousObject;
			}
			return null;
		}
	}
}

Der Cache besteht in Wesentlichen aus den 2 Methoden public void put(TValue obj) und public TValue get(). Die Methode put() erstellt eine SoftReference und fügt diese in die Hashtable ein. Falls zuvor schon ein Objekt mit dem angegebenen Schlüssel in der Hashtable lag, wird dieses bereinigt, damit es sofort vom Garbage-Collector erfasst werden kann. Die Methode get() holt sich zuerst das SoftReference-Objekt aus der Hashtable und prüft dann ob der Wert noch existiert. Falls nicht, so kann das SoftReference-Objekt aus der Hashtable entfernt werden.

Zu beachten ist, dass es nicht möglich ist eine Methode public boolean contains(TKey key) zu implementieren, denn es könnte passieren, dass der Garbage-Collector zwischen den beiden Aufrufen contains und get aktiv wird und somit die Methode contains() zwar true zurück gibt, die Methode get() aber null.
Deshalb sollte ein Zugriff auf den Cache immer folgendermaßen aussehen:

...
Object value = cache.get(key);
if (value == null) {
	value = ... // Fetch value
	cache.put(key, value);
}
... // Use value

Automatischer Error-Report in Android

21. Dezember 2010 4 Kommentare

Mit Android 2.2 (Froyo) hat Google eine Funktion eingeführt, die es Benutzern erlaubt beim Absturz einer Anwendung aus dem Market dem Entwickler einen Fehlerbericht zu schicken. Da Froyo momentan erst auf knapp 43% der Geräte installiert ist, tappt der Entwickler für einen Großteil seiner Anwender im Dunkeln. Außerdem hat das Error-Reporting-System von Google viele Einschränkungen. Beispielsweise werden so gut wie keine Informationen zum System auf dem der Fehler aufgetreten ist, gesendet. Das macht es extrem schwer den Fehler nachzuvollziehen, da man im Wesentlichen nur den Stacktrace hat.

Deshalb habe ich mich auf die Suche nach einer Alternative gemacht und bin dabei auf android-remote-stacktrace gestoßen. Die Beschreibung klang nicht schlecht, allerdings hat sich später herausgestellt, dass die Umsetzung nicht sehr sauber war. Wenn eine Exception entsteht, während keine Internetverbindung besteht, so wird die Exception einfach gelöscht. Dadurch geht ein großer Teil der Fehler verloren (z.B. Fehler die nur durch die fehlende Internetverbindung zustande kamen). Ein weiteres Problem ist, dass die Fehlermeldung im gleichen Prozess wie die Anwendung selbst durchgeführt wird. Da Android jedoch bei einer unbehandelten Exception den Anwendungs-Prozess beendet, wird der Fehler erst gemeldet werden, wenn die Anwendung das nächste mal gestartet wird. Die letzte Einschränkung dieser Bibliothek ist, dass es nicht möglich ist, Fehler manuell zu melden, die man zwar abgefangen hat um die Anwendung nicht zum Absturz zu bringen, die aber trotzdem normalerweise nie auftreten sollten.

Um meine Anforderungen an so eine Bibliothek zu erfüllen, habe ich mich mal hingesetzt und den Android-Error-Reporter geschrieben und auf Github gestellt. Die Bibliothek erlaubt es (ähnlich wie die oben genannte) unbehandelte Fehler per HTTP-POST automatisch an eine vorgegebene URL zu senden. Die Integration in das eigene Projekt ist sehr einfach und wird auf der Projektseite beschrieben. Der Vorteil gegenüber der genannten Bibliothek ist, dass die Fehler in einem separaten Prozess gemeldet werden, der unabhängig von dem Anwendungs-Prozess läuft, wodurch die Fehler sofort gemeldet werden und nicht erst, wenn die Anwendung das nächste mal gestartet wird. Sollte ein mal keine Internetverbindung bestehen, so wird der Fehler in die Warteschleife gesteckt und es wird später erneut versucht ihn zu senden. Außerdem ist es möglich Fehler manuell zu melden. Ein weiterer Vorteil ist, dass die Bibliothek mehr Informationen über das System des Benutzers senden kann (die Daten die gesendet werden sollen, können konfiguriert werden).

WordPress mit SQLite

20. Dezember 2010 4 Kommentare

Da ich gerade diesen Blog installiert habe, erkläre ich in meinem ersten Beitrag, wie ich WordPress mit SQLite (anstatt wie üblich mit MySQL) installiert habe.

  1. Falls noch nicht vorhanden, PDO und SQLite für PHP installieren, z.B. mit
    apt-get install php5-sqlite
  2. WordPress herunterladen und installieren. Die neuste Version gibt es hier. Einfach am gewünschten Ziel entpacken.
  3. Das Plugin PDO for WordPress installieren, das im wesentlichen der Datenbank-Schnittstelle von WordPress eine weitere Abstraktionsebene hinzufügt. Die Installation des Plugins ist relativ einfach und wird hier erklärt.
  4. WordPress hat bei mir häufig folgende Fehlermeldung angezeigt:
    Warning: implode() [function.implode]: Invalid arguments passed in /wp-includes/post.php on line 2558
    Die Lösung habe ich hier gefunden:
    Die Datenbank-Klasse des PDO-Plugins erbt von der Standard Datenbank-Klasse wpdb
    und überschreibt dabei die Methode escape() fehlerhaft. Um das Problem zu beheben in der Datei wp-content/pdo/db.php einfach die Methode escape() auskommentieren und das Problem ist behoben. Also einfach den folgenden Teil in /* und */ einschließen.

    function escape($string) {
        return addslashes($string);
    }
  5. Der Rest der Installation kann ganz normal fortgesetzt werden.

[UPDATE] Siehe meinen Kommentar

KategorienServer Tags: , , ,