Serielle Kommunikation über Bluetooth

Für ein kleines Projekt (Mobiltelefon steuert Arduino) habe ich mir ein HC-06 Bluetooth Modul für wenig Geld in China besorgt. Bluetooth habe ich nie gemocht, weil ich nie viel Freude daran hatte diese Gerätschaften unter Linux zu konfigurieren, aber der Preisunterschied zu Arduino WLAN Modulen hatte dann doch den Ausschlag gegeben:).
 Über GUI ließ sich das Gerät leider nicht konfigurieren, aber  mit den bluez-utils auf der Kommandozeile ließ sich das Problem rasch beheben.

Zuerst muß die MAC Adresse des Moduls in Erfahrung gebracht werden.

ms@debian:~/$ hcitool scan
Scanning ...
	0C:DF:A4:DE:01:54	S3350
	20:14:04:11:15:16	HC-06

Das File rfcomm.conf anpassen

root@debian:/# cat /etc/bluetooth/rfcomm.conf 
#
# RFCOMM configuration file.
#
 
rfcomm0 {
#	# Automatically bind the device at startup
	bind yes;
#
#	# Bluetooth address of the device
	device 20:14:04:11:15:16;
#	# RFCOMM channel for the connection
	channel	1;
#
#	# Description of the connection
	comment "HC-06";
}

Nun die Pin des Geräts (Default ist 1234) setzen – Mac Adresse am Besten per Tabulator vervollständigen
root@debian:/# sudo echo „20:14:04:11:15:16 1234“ >> /var/lib/bluetooth/08\:3E\:8E\:E5\:1C\:5E/pincodes

Und den Bluetooth Daemon neu starten.

root@debian:/# sudo /etc/init.d/bluetooth restart

Befehle an den Bluetooth Client senden

Strings kann man nun einfach an das Gerät redirecten
ms@debian:~$ echo „beep“ >/dev/rfcomm0

Ausgabe des Bluetooth Clients lesen

Einfach mit cat die Gerätedatei ausgeben

ms@debian:~$ cat /dev/rfcomm0
==Commands==
led on
led off
beep
beep_d [duration]
==Commands==
led on
led off
beep
beep_d [duration]

fin.

Über Shared Preferences mit einem Service kommunizieren

Für ein Live Wallpaper mit Settings-Dialog brauche ich einen Callback im Service um Änderungen in den Einstellungen so schnell wie möglich  zu verarbeiten. Periodisches Pollen zur Laufzeit ist nicht nur unelegant sondern braucht auch CPU Zeit. Der einfachste Weg für micht geht über SharedPreferences und einem OnSharedPreferenceChanceListener Interface.

 
private class MyWallpaperEngine extends Engine implements OnHttpRequestResultListener, OnSharedPreferenceChangeListener {
 
        public MyWallpaperEngine() {
		    //get the image
		    SharedPreferences sp = getApplicationContext().getSharedPreferences(
					Constants.NAMESPACE_SETTINGS, Activity.MODE_PRIVATE);
			sp.registerOnSharedPreferenceChangeListener(this);
	}
 
        /* .... */
	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
		draw();
 
	}
}

In der implementierten Methode onSharedPreferenceChanged wird einmal neu gezeichnet. Fertig.

Prüfen ob Service aktiv ist

Ich schreibe momentan ein Live Wallpaper für Android, mit einer Activity um Infos zum aktuellen Bild darzustellen. Um komfortabel das Live Wallpaper zu aktivieren brauche ich eine Prüfung, ob das auch läuft. WallpaperService ist von Service abgeleitet und damit ist dies kein Problem:

    /* ..... */
	private boolean isMyServiceRunning(String className) {
	    ActivityManager manager = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE);
	    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
	        if (className.equals(service.service.getClassName())) {
	            return true;
	        }
	    }
	    return false;
	}
    /* ..... */

Nun kann bei Bedarf der Wallpaper Picker angezeigt werden:

	if(isMyServiceRunning(MyWallpaperService.class.getName())){
			Log.d(TAG, "active" );
	} else {
			Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
			startActivity(Intent.createChooser(intent, getActivity().getString(R.string.title_for_wallpaper_chooser)));
	}

Fin.

Links in TextView clickbar machen

Html Markup bringt man am einfachsten auf diesem Weg in TextViews:

/***** .... *****/
TextView mContent;
mContent.setText(Html.fromHtml("<a href=\"http://www.giftimessen.de\">Link</a>"));
/***** .... *****/

Beim Draufdrücken passiert leider noch nicht soviel. Um die Links gangbar zu machen einfach die MovementMethod setzen:

 
mContent.setMovementMethod(LinkMovementMethod.getInstance());

fertig :).

Led Lampen mit WLAN Anbindung

Ein Thema das mich immer wieder fasziniert ist die Vernetzung von Gegenständen des Alltags. Meine Wohnzimmerlampe glänzt nicht nur durch hässliche Form sondern auch durch kaltes Licht und Quecksilber im Leuchtmittel. Deshalb ersetze ich nach und nach Kompaktleuchtstofflampen durch LED Lampen. Der Zufall brachte mich zu diesem Lampenset mit WLAN Anbindung (Affiliate) vom Hersteller LimitlessLED. Die Lampen passen in E27 Sockel, haben 6 Watt Leistung und können mit 230V ~  betrieben werden. Die Grundidee ist die Lampen via Smartphone oder auf anderen Wegen einzuschalten, die Farben zu ändern und dimmen.Neben den 3 Lampen werden eine Fernbedienung und was viel interessanter ist einem Controller mit dokumentierter API geliefert. Apps gibt es auch! Pro Fernbedienung und Controller kann man 4 Lampen steuern. Dabei kann man die Parameter Helligkeit, Farbe regeln.

2013-10-15 16.56.18

 

Impressionen

Inbetriebnahme

Lampen

Jede Lampe muß konfiguriert werden. Dabei spielt es keine Rolle, ob man sie der Fernbedienung oder in der App konfiguriert.

Lampe in Fassung drehen und binnen 2 Sekunden nach Anlegen von Spannung auf der Fernbedienung einen Kanal aktivieren – die Lampe ist nun dem entsprechenden Kanal zugewiesen. Die erfolgreiche Zuweisung  wird durch Blinken quittiert. Um die Lampe aus dem Kanal zu lösen innerhalb von 2 Sekunden nach dem Einschalten 5 mal den entsprechenden Kanal auf der Fernbedienung aktivieren.

Controller

Der Controller wird per Micro-USB Kabel mit Spannung versorgt. Ich nutze ein Ladegerät für Smartphones. Nach dem Booten sollte man ein WLAN mit der SSID milight finden. Nun kann man der Anleitung folgen oder was ich als angenehmer per Webinterface konfigurieren. Dazu ins eigene WLAN verbinden und http://192.168.0.100/home.html aufrufen – ob die IP immer die gleiche ist kann ich nicht sagen. Hier muß in den STA Interface Settings das eigene WLAN konfiguriert werden.

App

Momentan nutze ich die in der Anleitung vorgeschlagene App Es gibt auch noch eine puristischere Version mit
Anbindung an Tasker – die  ohne Anpassungen leider nicht läuft.

LED Lampen ansteuern

Beim Hersteller gibt es eine Dokumentation.  Die Beispiele sind leider ein wenig inkonsistent, da irgendwann die Portnummer von 50000 auf 8899 umgestellt wurde.

Die Lampen werden per UDP Kommandos gesteuert. Dabei werden immer 3 Byte übertragen.

Byte 1 ist das Kommando an welches immer der Suffix 0x00  0x55 angehängt werden muß.

In PHP kann mit diesen Zeilen alle Kanäle einschalten:

&lt;?php
define("CONTROLLER_IP", "192.168.0.100");
function executeCommand( $ip, $command, $suffix1=00, $suffix2='55'){
	fwrite(fsockopen("udp://$ip", 8899), chr(hexdec($command)) . chr(hexdec($suffix1)) . chr(hexdec($suffix2)));
}
 
executeCommand(CONTROLLER_IP, 42);

Wer php5-cli installiert hat kann das Script auch auf der Kommandozeile nutzen. Für Freunde der Bash gibt es auch ein Script (geklaut bei Smileytechadventures)

#!/bin/bash 
 
if [ -z "$1" ] ; then 
    echo "You must enter a parameter: "  
    echo "  e.g. $0 allon" 
    exit 1 
fi 
 
incmd="$1" 
ipaddress="192.168.0.201" 
portnum="50000" 
 
allon="\x35\00\x55" 
alloff="\x39\00\x55" 
zone1on="\x38\00\x55" 
zone1off="\x3B\00\x55" 
zone2on="\x3D\00\x55" 
zone2off="\x33\00\x55" 
zone3on="\x37\00\x55" 
zone3off="\x3A\00\x55" 
zone4on="\x32\00\x55" 
zone4off="\x36\00\x55" 
 
eval incmd=\$$incmd 
 
echo -n -e "$incmd" &gt;/dev/udp/"$ipaddress"/"$portnum"

Ein wenig Heimautomatisierung ist auch schnell betrieben. Dieses Skript prüft, ob die Sonne untergegangen ist und schaltet in diesem Fall alle Lampen ein.

#!/usr/bin/php
&lt;?php define("CONTROLLER_IP", "192.168.0.100"); define("ZEIT_FUER_BETT", "23:59"); function executeCommand( $ip, $command, $suffix1=00, $suffix2='55'){ fwrite(fsockopen("udp://$ip", 8899), chr(hexdec($command)) . chr(hexdec($suffix1)) . chr(hexdec($suffix2))); } function getIp(){ return file_get_contents("http://icanhazip.com/"); } function getLatLongByIp($ip){ $geoplugin = unserialize( file_get_contents('http://www.geoplugin.net/php.gp?ip='.$ip) ); if ( is_numeric($geoplugin['geoplugin_latitude']) &amp;&amp; is_numeric($geoplugin['geoplugin_longitude']) ) { $ret['lat']= $geoplugin['geoplugin_latitude']; $ret['lon']=$geoplugin['geoplugin_longitude']; return $ret; } } $ret= getLatLongByIp(getIp()); $dateSunset=date_sunset(time(), SUNFUNCS_RET_TIMESTAMP,$ret['lat'], $ret['lon'], 90, 1); $dateSunrise=date_sunrise(time(), SUNFUNCS_RET_TIMESTAMP, $ret['lat'], $ret['lon'], 90, 1); //Zu einer festen Uhrzeit ausschalten if(date("H:i")&gt;= date(ZEIT_FUER_BETT)){
echo "schlafen";
	executeCommand(CONTROLLER_IP, 41);
	exit;
}  
//Nach Sonnenuntergang und vor Aufgang
if ( time() &gt;=$dateSunset &amp;&amp; $dateSunset &gt;$dateSunrise){
 
	executeCommand(CONTROLLER_IP, 42);
}else {
	executeCommand(CONTROLLER_IP, 41);
}

Das kleine Skript fühlt sich auf kleinen Linuxrechnern im eigenen Netzwerk sehr wohl und sollte per Cronjob alle 1 Minuten angestoßen werden.

*/1 *    * * *   /home/pi/sunrise.php

Inzwischen habe ich die Lampen seit einer Woche in Betrieb und viel Spaß damit. Die Lichtausbeute ist ausreichend, der Stromverbrauch in Ordnung. Der Preis ist mit 99 EUR schon sehr happig, aber es macht auch sehr sehr viel Spaß Skripte für die Lampen zu schreiben.

Facebook SDK für Android einrichten

Quelle: Facebook Developers

 

  •  SDK runterladen 
  • Zip entpacken, alles nach Eclipse exportieren (ohne in den Workspace zu kopieren)
  •  Evtl. Project -> Clean ausführen
  • Developer Account anlegen
  • Key Hash mit dem keytool  (liegt in <JDK Folder>/bin) erzeugen
  • (Linux, Mac) keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
  • (Windows) keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64
  • Im Profil Key Hash unter Sample App Settings eintragen.

 

Beispiele Testen.

Chromecast endlich eingetroffen

Mein Bekannter ist endlich aus USA zurück und hat mir einen Chromecast mitgebracht. Die Einrichtung war äußerst simpel: Chromecast per USB mit Strom versorgen und an den Fernseher anschließen, Konfiguration via PC, Windows7.

 

Chromecast

 

 

Das Gerät lässt sich von allen Android Geräten ansteuern die im gleichen WLAN wie der Dongle sind. Bis jetzt habe ich Youtube, Google Music und – Play Movies gestest.

Die Bedienung ist simpel: In den Apps taucht ein neues Menü auf mit dem man die Wiedergabe auf einen Chromecast umlenken kann. Dabei wird nicht gestreamt wie bei Miracast sondern es werden Steueranweisungen  vom Android Gerät an den Dongle übergeben. Die Architektur nennt sich Google Cast. Dieser holt sich dann die Medien aus dem Internet. Das hat den Vorteil, daß man Rechenzeit auf dem Telefon spart, aber das Streamen von lokalen Dateien ist nicht ohne weiteres möglich.

.

Die PC Version des Chromebrowsers bietet die Möglichkeit einzelne Tabs an Chromecast zu übertragen. Webseiten sind kein Problem,  Videos schauen macht aufgrund des Streamingkonzepts und der hohen Latenz  (meiner DSL Leitung) wenig Sinn.

 

Für die Streaming-Architektur gibt es ein SDK mit Dokumentation, welches explizit als Preview deklariert ist. Ich werde noch ein wenig abwarten bevor ich mir das anschaue. Vor knapp einem Monat sperrte Google per Chromecast-Update die App Allcast aus mit der es möglich war lokal vorliegende Dateien abzuspielen. Google weiß anscheinend selbst noch nicht, wie restriktiv der Chromecast werden soll.

 

 

Google Cloud Messaging (GCM) Tutorial

In diesem Beitrag geht es darum wie man Nachrichten via GCM an Apps verschicken kann.

Viele Android Apps sind klassische Client/Server Anwendungen. Der Client tätigt Requests an einen Server und bekommt im besten Fall eine vernünftige Antwort. In anderer Richtung ist dies jedoch nicht so einfach. Wenn der Server Daten an 1 bis n Clients senden möchte ist das in diesem Szenario nicht so einfach. Mobiltelefone sind meist nicht über eine statische IP zu erreichen, es ist nicht sichergestellt, daß das Gerät mit dem Internet verbunden ist wenn eine Nachricht versendet wird. Wenn der Client regelmäßig den Server anpollt kostet das Bandbreite und elektische Leistung.

Continue reading

Eclipse – Android Quelltexte einbinden

Beim Debuggen von Android Apps kann es sehr hilfreich sein einen Blick in die Systemklassen zu werfen. Davon abgesehen hat das Lesen von fremdem Code noch keinem geschadet.

Wenn die Sourcen von Android nicht eingebunden werden sieht man beim  Klick auf eine Systemklasse meistens sowas

Class Editor - acitivity not found

 

Das Einbinden der Quelltexte ist keine große Herausforderung, allerdings ist der Weg ein wenig schwer zu merken (deswegen dieser Artikel). Die Anleitung bezieht sich auf  die Android Developer Tools Build: v22.0.0-675183 auf Windows 7. Der Vorgang sollte auf richtigen Betriebssystem analog verlaufen.

Zuerst müssen die Sourcen via SDK Manager installiert werden:

sdkmanager

Anschließend muß der Build Path angepasst werden

3_config_bpath

 

Nun auf Libraries klicken, android.jar ausklappen, edit und den Pfad auf die Sourcen setzen.

Du findest den Code im Verzeichniss

$ECLIPSE_DIR\adt-bundle-windows-x86_64-20130514\sdk\sources\android-17

Wenn der Pfad korrekt gesetzt wurde kann sollte es so ausschauen:

5_fin

Fin.

 

Noch ein wenig Off-topic

Wer diesen Artikel via androidblogs.de gelesen hat wird sich vielleicht wundern wer ich bin und was das alles hier soll. Da ich keinen Hallo Welt Artikel in den Planeten jagen wollte nutze ich meinen 1. Artikel um mich vorzustellen:

Mein Name ist Michael, auf meinem Blog geht’s um alles mögliche, Linux, Android, Skripten + Programmieren, kleine Computer und was mir sonst so geschieht oder schief geht. Verschiedenste Telefone und Tablets mit dem Google Betriebssystem nutze ich seit ca 3. Jahren.

Java programmiere ich seit mehreren Jahren, als kleines Nebenprojekt arbeite ich mich in die Entwicklung von Android ein. Wenn Interesse besteht werde ich interessante oder nützliche Dinge in den Feed von Androidblogs.de jagen.