<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>onCreate.nl</title>
	<atom:link href="http://www.oncreate.nl/feed" rel="self" type="application/rss+xml" />
	<link>http://www.oncreate.nl</link>
	<description>Nederlandse Android Developers Groep</description>
	<lastBuildDate>Sun, 09 Jan 2011 20:54:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Een C# ontwikkelaar op Android</title>
		<link>http://www.oncreate.nl/archives/191</link>
		<comments>http://www.oncreate.nl/archives/191#comments</comments>
		<pubDate>Sun, 09 Jan 2011 20:52:34 +0000</pubDate>
		<dc:creator>Richard de Zwart</dc:creator>
				<category><![CDATA[Applicaties]]></category>
		<category><![CDATA[monodroid]]></category>

		<guid isPermaLink="false">http://www.oncreate.nl/?p=191</guid>
		<description><![CDATA[Ik wilde gewoon even laten weten dat ik &#8211; een die-hard C# ontwikkelaar, net mijn eerste Android app heb gebouwd en gedraaid. Zowel op de emulator als op een heuse telefoon! Dank aan het Mono team voor het uitbrengen van MonoDroid!]]></description>
			<content:encoded><![CDATA[<p>Ik wilde gewoon even laten weten dat ik &#8211; een die-hard C# ontwikkelaar, net mijn eerste Android app heb gebouwd en gedraaid. Zowel op de emulator als op een heuse telefoon!</p>
<p>Dank aan het Mono team voor het uitbrengen van <a href="http://monodroid.net">MonoDroid</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncreate.nl/archives/191/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>App Inventor voor Android</title>
		<link>http://www.oncreate.nl/archives/130</link>
		<comments>http://www.oncreate.nl/archives/130#comments</comments>
		<pubDate>Mon, 06 Dec 2010 21:22:38 +0000</pubDate>
		<dc:creator>wtreur</dc:creator>
				<category><![CDATA[Applicaties]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[App Inventor for Android]]></category>

		<guid isPermaLink="false">http://www.oncreate.nl/?p=130</guid>
		<description><![CDATA[Iedereen kent het wel. Op een of ander moment kom je op een punt dat je iets moet doen wat iets te veel of vervelend werk is. Vaak gaat het om niet heel ingewikkelde dingen, waarbij je iets moet onthouden, uitrekenen of afspreken met meer dan één persoon. En lui als wij zijn komt dan]]></description>
			<content:encoded><![CDATA[<p>Iedereen kent het wel. Op een of ander moment kom je op een punt dat je iets moet doen wat iets te veel of vervelend werk is. Vaak gaat het om niet heel ingewikkelde dingen, waarbij  je iets moet onthouden, uitrekenen of afspreken met meer dan één persoon. En lui als wij zijn komt dan al snel de opmerking &#8220;Had mijn telefoon daar maar een applicatie voor.&#8221; (Of het wordt gevolgd door &#8220;There’s an App for that!&#8221; door &eacute;&eacute;n van onze iPhone vrienden) Ik heb zelf vrij vaak zo’n ingeving, en ondanks mijn Java kennis doe ik daar meestal vrij weinig mee. Zeker als ik de documentatie van een of andere gps/sms/twitter api moet napluizen is mijn lyrische stemming over dat ik het meest geweldige idee ooit heb bedacht, vreselijk getemperd en sta ik weer met beide benen op de grond. Gelukkig heeft Google daar een briljant meta-idee voor gehad in de vorm van <a href="http://appinventor.googlelabs.com/">App Inventor voor Android</a>. Ofwel: Klik je Android applicatie in elkaar zonder een regel code. Tijd om een van mijn &#8216;betere&#8217; ideeën in praktijk te brengen.</p>
<p><strong>Het idee</strong><br />
Meer dan eens parkeer ik mijn auto op een parkeerplaats en ik na terugkomst niet meer weet waar die precies stond. Kon ik dat maar in mijn telefoon opslaan! (Uiteraard kan dat al, want iedereen heeft dat probleem en het is al honderd keer opgelost, maar daar hebben we het nu even niet over) Tijd voor de App Inventor.</p>
<p><a href="http://www.oncreate.nl/wp-content/uploads/2010/12/app-inventor-designer.png"><img src="http://www.oncreate.nl/wp-content/uploads/2010/12/app-inventor-designer-300x249.png" alt="" width="300" height="249" class="alignright size-medium wp-image-150" /></a>De App Inventor bestaat uit twee delen. De designer en de block editor. De designer draait in je browser en gebruik je voor het bouwen van alle gedragscomponent. Feitelijk niet meer dan een simpele WYSIWYG editor waar je ook alle niet visuele component maakt, zoals een location sensor of database.<br />
In de block editor ga je vervolgens alle logica ‘uitprogrammeren’ In deze Java Web Start applicatie kun je door het letterlijk slepen van bouwblokken je gedrag van je applicatie bepalen.<br />
De block editor regelt verder de communicatie met je telefoon. Hierdoor kun je hem tussentijds lanceren, maar ook kun je hiermee vanuit de designer direct op je telefoon zien hoe je scherm er uit gaat zien. Erg handig!</p>
<p><strong>Klikkerdeklik</strong><br />
Dus, men neme een paar componenten. Slepen die op het scherm en zie daar, het invoervenster voor het opslaan van je parkeerplaats. Belangrijk is dat je er ook een database en gps component in sleept, om de locatie uiteindelijk op te slaan.<br />
Vanuit de designer kun je de block editor open. Deze biedt aan de linkerkant een lijst met puzzelstukjes; zogenaamde <em>code blocks</em>. In de ‘My Blocks’ tab vind je de code blocks gerelateerd aan de &#8216;Save&#8217; knop en kun je bijvoorbeeld het &#8216;Click&#8217; event in je workspace slepen Deze kan dan vervolgens gevuld worden met andere code blocks die worden uitgevoerd als de knop wordt ingedrukt. Het is letterlijk even puzzelen, maar je klikt zo al binnen een paar minuten de rest van je applicatie in elkaar.</p>
<p><a href="http://www.oncreate.nl/wp-content/uploads/2010/12/app-inventor-block-editor.png"><img src="http://www.oncreate.nl/wp-content/uploads/2010/12/app-inventor-block-editor-300x235.png" alt="" width="300" height="235" class="alignleft size-medium wp-image-149" /></a>Eén van de wat &#8216;lastigere&#8217; dingen was het openen van de Maps applicatie. Dit was namelijk niet het inslepen van een of andere kant-en-klare Maps component, maar gebeurd met een Activity Starter. Met dit component kun je een intent aanroepen (De meeste Android developers wel bekend) en met een DataURI de juiste intent met parameters aanroepen. Gelukkig staat het meeste goed beschreven in <a href="http://appinventor.googlelabs.com/learn/">de documentatie</a>.</p>
<p><strong>Laatste ingredi&euml;nt: Wel een goed idee.</strong><br />
De App Inventor is erg handig om snel een nieuw idee uit werken. Het heeft nagenoeg alles om een fatsoenlijke Android applicatie in elkaar te zetten. Google Maps, Twitter, camera of email. Je kunt het allemaal gebruiken zonder erg veel moeite. Dit maakt het uitermate geschikt een snel en goedkoop een prototype applicatie in elkaar te sleutelen. Ook voor niet programmeurs is het best een leuke tool, om in de vrije avonduren wat in elkaar te knutselen. Met relatief weinig technische kennis kom je een heel eind. Toch denk ik dat het daar ook bij zal blijven. Voor echte volwaardige applicaties ben je beter af met de normale SDK, omdat deze simpelweg gewoon meer kan en meer controle biedt. In de eerste fase van een ontwikkeltraject is de App Inventor daarom een handige tool om de eerste ideeën uit te werken of meer ideeën op te doen en vervolgens met de normale SDK de volwaardige applicatie uit werken.</p>
<p>De complete applicatie kun je zelf <a href="http://www.oncreate.nl/wp-content/uploads/2010/12/WhereIsMyCar.zip">downloaden</a> en <a href="http://www.google.com/search?q=share+project+code+with+other+app+inventor+users">importeren in App Inventor</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncreate.nl/archives/130/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UI testen met Android JUnit of Robotium?</title>
		<link>http://www.oncreate.nl/archives/122</link>
		<comments>http://www.oncreate.nl/archives/122#comments</comments>
		<pubDate>Tue, 30 Nov 2010 13:35:45 +0000</pubDate>
		<dc:creator>ians</dc:creator>
				<category><![CDATA[Applicaties]]></category>
		<category><![CDATA[Testen]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Android JUnit]]></category>
		<category><![CDATA[Luminis]]></category>
		<category><![CDATA[Robotium]]></category>
		<category><![CDATA[UI Testen]]></category>

		<guid isPermaLink="false">http://www.oncreate.nl/?p=122</guid>
		<description><![CDATA[Ik ben een student aan de Hogeschool in Arnhem en ik studeer informatica. Ik loop nu stage bij Luminis Software Development. Ik heb o.a. de opdracht gekregen om te onderzoeken hoe een Android applicatie getest kan worden. De Android developers website geeft al een aantal voorbeelden voor het UI testen van een applicatie. Het schrijven]]></description>
			<content:encoded><![CDATA[<p>Ik ben een student aan de Hogeschool in Arnhem en ik studeer  informatica. Ik loop nu stage bij Luminis Software Development. Ik heb  o.a. de opdracht gekregen om te onderzoeken hoe een Android applicatie  getest kan worden. De Android developers website geeft al een aantal  voorbeelden voor het UI testen van een applicatie. Het schrijven van een  UI test zoals de Android developers website beschrijft is redelijk  complex en zorgt ook voor veel code.</p>
<p>Na wat onderzoek ben ik tegen het test framework Robotium aangelopen.  De website geeft aan dat het framework gebruikt kan worden voor  functie, systeem en acceptatie testen. Een onderdeel van een systeem  test is een (G)UI test.</p>
<h2><a name="UItestenmetAndroidJUnitofRobotium?-Waarover?"></a>Waarover?</h2>
<p>In dit artikel bespreek ik door middel van een voorbeeld het verschil  tussen een UI test met Android JUnit en een UI test met Robotium.</p>
<h2><a name="UItestenmetAndroidJUnitofRobotium?-UITestmetAndroidJUnit"></a>UI Test met Android JUnit</h2>
<p>Op de Android developers <a rel="nofollow" href="http://developer.android.com/resources/tutorials/testing/activity_test.html">pagina</a> is een kleine handleiding te vinden hoe je een Android UI test schrijft voor een Spinner applicatie.</p>
<p>De UI test ziet er dan als volgt uit:</p>
<div>
<div><strong>SpinnerActivityTest.java</strong></div>
<div>
<pre>public void testSpinnerUI() {
		mActivity.runOnUiThread(new Runnable() {
			public void run() {
				mSpinner.requestFocus();
				mSpinner.setSelection(INITIAL_POSITION);
			}
		});
		this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
		for (int i = 1; i &lt;= TEST_POSITION; i++) {
			this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
		}
		this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
		mPos = mSpinner.getSelectedItemPosition();
		mSelection = (String) mSpinner.getItemAtPosition(mPos);
		TextView resultView = (TextView) mActivity
				.findViewById(com.android.example.spinner.R.id.SpinnerResult);
		String resultText = (String) resultView.getText();
		assertEquals(resultText, mSelection);
	}</pre>
</div>
</div>
<h2><a name="UItestenmetAndroidJUnitofRobotium?-UITestmetRobotium"></a>UI Test met Robotium</h2>
<p>Op de website van <a rel="nofollow" href="http://code.google.com/p/robotium/">Robotium</a> is meer te vinden over Robotium en hoe je er mee aan de slag kan.</p>
<p>Wanneer een vergelijkbare UI test met Robotium wordt geschreven ziet het er als volgt uit:</p>
<div>
<div><strong>SpinnerActivityTest.java</strong></div>
<div>
<pre>public void testSpinnerUI() throws Exception {
		ArrayList&lt;Spinner&gt; spinners = solo.getCurrentSpinners();
		int itemCount = solo.getCurrentSpinners().get(0).getCount();
		solo.pressSpinnerItem(0, -itemCount);
		solo.pressSpinnerItem(0, TEST_POSITION);
		String currentItem = spinners.get(0).getSelectedItem().toString();
		assertEquals(RESULT_SELECTION, currentItem);
	}</pre>
</div>
</div>
<h2><a name="UItestenmetAndroidJUnitofRobotium?-Hetverschil?"></a>Het verschil?</h2>
<ol>
<li>Het is meteen duidelijk dat de hoeveelheid code meteen wordt gehalveerd.</li>
<li>Voor Robotium is er weinig kennis van de code nodig, sterker nog  wanneer je de APK hebt hoef je de source code niet eens te hebben.</li>
<li>Robotium doet heel veel dingen die je anders zelf moet doen, zie  bijvoorbeeld de mSpinner.requestFocus() functie die zoals de naam als  doet vermoeden voor de focus zorgt, dit is bij Robotium niet nodig&#8230;</li>
</ol>
<h2><a name="UItestenmetAndroidJUnitofRobotium?-Conclusie"></a>Conclusie</h2>
<p>Ik kan geen groot nadeel bedenken bij het gebruik van Robotium ten  overstaande van Android JUnit testen. Het lijkt erop dat Robotium alleen  iets trager is in deze test.</p>
<p>Er wordt nog steeds hard gewerkt aan Robotium, dus we kunnen hopelijk  binnenkort weer nieuwe functionaliteiten verwachten zoals een  screenshot bij een gefaalde test.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncreate.nl/archives/122/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android en OSGi</title>
		<link>http://www.oncreate.nl/archives/110</link>
		<comments>http://www.oncreate.nl/archives/110#comments</comments>
		<pubDate>Sun, 03 Oct 2010 10:59:39 +0000</pubDate>
		<dc:creator>Marcel Offermans</dc:creator>
				<category><![CDATA[Applicaties]]></category>
		<category><![CDATA[Akquinet]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Apache ACE]]></category>
		<category><![CDATA[Apache Felix]]></category>
		<category><![CDATA[EZdroid]]></category>
		<category><![CDATA[Luminis]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://www.oncreate.nl/?p=110</guid>
		<description><![CDATA[Hergebruik en het ontwikkelen van software op basis van bestaande componenten is een van de aspecten van software ontwikkeling die steeds belangrijker wordt. In een tijd waarin producten van steeds sneller naar de markt moeten en de complexiteit van software toeneemt, kun je het je niet meer veroorloven om alles zelf te doen en telkens]]></description>
			<content:encoded><![CDATA[<p>Hergebruik en het ontwikkelen van software op basis van bestaande componenten is een van de aspecten van software ontwikkeling die steeds belangrijker wordt. In een tijd waarin producten van steeds sneller naar de markt moeten en de complexiteit van software toeneemt, kun je het je niet meer veroorloven om alles zelf te doen en telkens van scratch te beginnen.</p>
<p>Het ontwerpen van applicaties op basis van herbruikbare componenten heeft zichzelf in de Java wereld al lang bewezen. Het meest gebruikte framework hiervoor is <a href="http://osgi.org/">OSGi</a>, wat je in staat stelt om componenten (zogenaamde &#8220;bundles&#8221;) te maken die een duidelijk gedefinieerde interface hebben en waarvan je de interne code niet van buiten kunt benaderen. Zo gebouwde applicaties zijn bovendien dynamisch, in de zin dat componenten, zonder de applicatie te moeten stoppen, toegevoegd, geupdate en verwijderd kunnen worden.</p>
<p>Omdat het OSGi framework zelf zeer licht van gewicht is &#8212; het is immers ooit ontworpen om in embedded omgevingen gebruikt te worden &#8212; is het prima geschikt om Android applicaties modulair te maken. Hierdoor wordt het hergebruik van componenten sterk vereenvoudigd. Al toen de eerste Android SDK door Google werd vrijgegeven, hebben we binnen Luminis uitgezocht <a href="http://lsd.luminis.nl/en/osgi-on-google-android-using-apache-felix/">hoe je Apache Felix (een implementatie van de OSGi standaard) op de Dalvik VM kon draaien</a>. In het begin hadden we daar nog ongedocumenteerde APIs voor nodig, maar inmiddels heeft Google die allemaal netjes gepubliceerd en als je momenteel een release van <a href="http://felix.apache.org/">Apache Felix</a> downloadt, werkt die zonder verdere wijzigingen op Android.</p>
<p>Het gebruik van OSGi op Android wordt extra interessant als je gaat kijken naar de software distributie mogelijkheden die je daardoor krijgt. Zo kun je met <a href="http://incubator.apache.org/ace/">Apache ACE</a>, een software distributie (of provisioning) framework &#8212; componenten van afstand updaten, zonder tussenkomst van een gebruiker. Hierdoor ontstaat flexibiliteit die je in staat stelt om je applicaties bijvoorbeeld adaptief te maken (ze kunnen zich aanpassen aan hun omgeving).</p>
<p>Al een tijdje geleden hebben <a href="http://lsd.luminis.nl/en/ezdroid-launched/">Luminis en Akquinet de koppen bij elkaar gestoken</a> om een omgeving te maken waarin Android en OSGi op elkaar afgestemd zijn op basis van eerdergenoemde open source projecten: Apache Felix en Apache ACE. Dat initiatief heet <a href="http://www.ezdroid.com/">EZDroid</a> en op die website kun je daar meer over te weten komen.</p>
<div id="_mcePaste">Samengevat is er geen enkele reden meer om Android applicaties nog langer als monolieten te ontwikkelen. De komende tijd zal ik in verdere artikelen ingaan op het gebruik van OSGi op Android. Als er in de tussentijd al vragen zijn, hoor ik ze hier graag!</div>
]]></content:encoded>
			<wfw:commentRss>http://www.oncreate.nl/archives/110/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>De _changes API van CouchDB in een Android MapView applicatie</title>
		<link>http://www.oncreate.nl/archives/72</link>
		<comments>http://www.oncreate.nl/archives/72#comments</comments>
		<pubDate>Sun, 26 Sep 2010 18:52:06 +0000</pubDate>
		<dc:creator>Dennis Geurts</dc:creator>
				<category><![CDATA[Applicaties]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[CouchDB]]></category>

		<guid isPermaLink="false">http://www.oncreate.nl/?p=72</guid>
		<description><![CDATA[hoe je binnen android gebruik kunt maken van de couchdb _changes api.]]></description>
			<content:encoded><![CDATA[<p>Soms kun je hele simpele zaken combineren, en daarmee toch hele interessante functionaliteit bereiken. Dit geldt ook voor de combinatie tussen een MapView en een _changes feed van <a href="http://http://couchdb.apache.org/">CouchDB</a>. Iedereen kent vast de <a href="http://developer.android.com/guide/tutorials/views/hello-mapview.html">Hello MapView</a> tutorial wel. Hierin wordt uitgelegd hoe je op een eenvoudige manier eigen Points Of Interest (POIs) op een MapView als overlay kunt toevoegen. De enige vraag blijft nu: &#8220;Waar haal je nu die POIs vandaan?&#8221;. Nu kun je natuurlijk een of andere statische lijst ophalen en die over de MapView heen leggen, maar dan ben je natuurlijk snel uitgekeken. Mij leek het wat leuker om een iets dynamischere versie te maken, met POIs die actuele events weergeven. Dit had ik ook al eens gedaan voor de <a href="http://lsd.luminis.nl/en/getting-to-know-couchdb-2x/">iPhone</a>; nu wou ik dat voor elkaar krijgen in Android.</p>
<p>CouchDB is een noSQL oftewel document database. De documenten bestaan uit JSON objecten. Elk welgevormd JSON object kan in zo&#8217;n database opgeslagen worden. Een eenvoudige REST interface stelt ons in staat documenten toe te voegen, aan te passen en te verwijderen. Daarnaast is het ook mogelijk te &#8216;luisteren&#8217; naar alle veranderingen die op de database plaatsvinden. Dit kan door middel van de _changes API. Een simpele HTTP GET naar de database (bijvoorbeeld http://localhost:5984/db/_changes) levert alle (meest recente) aanpassingen op alle documenten op. Wederom wordt dan een welgevormd JSON object geretourneerd. Het mooie aan deze _changes API is, dat je ook kunt aangeven vanaf welke verandering je de aanpassingen wilt volgen. Dit kan door middel van de request parameter &#8216;since&#8217;. In de &#8216;since&#8217; parameter moet je dan de update sequence opgeven vanaf wanneer je de updates wilt ontvangen. Zo kun je  bijvoorbeeld aangeven dat je alleen aanpassingen vanaf &#8216;nu&#8217; wilt ontvangen. Als je niet weet wat de huidige update sequence is, kun je die opvragen door de database meta-data op te vragen (dit gaan via bijvoorbeeld http://localhost:5984/db). Dit levert bijvoorbeeld:</p>
<pre class="brush: java; title: ;">
{&quot;db_name&quot;:&quot;db&quot;,&quot;doc_count&quot;:30,&quot;doc_del_count&quot;:0,&quot;update_seq&quot;:32,
&quot;purge_seq&quot;:0,&quot;compact_running&quot;:false,&quot;disk_size&quot;:237657,
&quot;instance_start_time&quot;:&quot;1285418445080300&quot;,&quot;disk_format_version&quot;:5,
&quot;committed_update_seq&quot;:32}
</pre>
<p>Waar de &#8216;update_seq&#8217; staat voor de allerlaatste update. Op basis hiervan kun je dus alle vorige updates negeren door de &#8216;since&#8217; parameter een waarde &#8217;32&#8242; mee te geven. Dit is mooie functionaliteit, maar het zou beter zijn als je een notificatie kunt krijgen van updates op het moment dat ze plaats vinden! Gelukkig is ook dat mogelijk.</p>
<p>De _changes API laat toe een request parameter &#8216;feed=continuous&#8217; mee te geven. Als je dat doet (in combinatie met de &#8216;since&#8217; parameter) zal de _changes feed vanaf dat moment voor alle aanpassingen op de database een welgevormd JSON object uitsturen. Dit gebeurt elke keer op een enkele regel, dus het inlezen is heel eenvoudig; Als voorbeeld:</p>
<pre class="brush: java; title: ;">

http://localhost:5984/db/_changes?feed=continuous&amp;include_docs=true&amp;since=35&quot;

{&quot;seq&quot;:36,&quot;id&quot;:&quot;f0a4a559fac65ab3cca87baf1cf8f007&quot;,
&quot;changes&quot;:[{&quot;rev&quot;:&quot;1-3b5146f14cd4a82d0a7075f0e59c8d9a&quot;}],\
&quot;doc&quot;:{\
   &quot;_id&quot;:&quot;f0a4a559fac65ab3cca87baf1cf8f007&quot;,\
   &quot;_rev&quot;:&quot;1-3b5146f14cd4a82d0a7075f0e59c8d9a&quot;,\
   &quot;type&quot;:&quot;EVENT&quot;,&quot;name&quot;:&quot;example1&quot;,\
   &quot;lat&quot;:42.036964,&quot;lng&quot;:3.624541,&quot;email&quot;:&quot;user@example.com&quot;}\
}
.
.
.
{&quot;seq&quot;:37,&quot;id&quot;:&quot;f0a4a559fac65ab3cca87baf1cf905d1&quot;,\
&quot;changes&quot;:[{&quot;rev&quot;:&quot;1-3b5146f14cd4a82d0a7075f0e59c8d9a&quot;}],\
   &quot;doc&quot;:{&quot;_id&quot;:&quot;f0a4a559fac65ab3cca87baf1cf905d1&quot;,\
   &quot;_rev&quot;:&quot;1-3b5146f14cd4a82d0a7075f0e59c8d9a&quot;,\
   &quot;type&quot;:&quot;EVENT&quot;,&quot;name&quot;:&quot;example2&quot;,\
   &quot;lat&quot;:42.036464,&quot;lng&quot;:3.624541,&quot;email&quot;:&quot;user@example.com&quot;}\
}
{&quot;last_seq&quot;:37}
</pre>
<p>Waar de puntjes staan kunnen meerdere secondes verlopen zijn (de opmaak is wat aangepast voor de leesbaarheid). Als er langer dan 1 minuut geen updates zijn (server-side) dan zal de verbinding verbroken worden. Voordat dit gebeurt, laat de _changes feed nog even weten wat de laatste update_seq was (37 in dit geval). Dit maakt het wat gemakkelijker om opnieuw een verbinding met de _changes API te maken (als request parameter &#8216;since&#8217; zal dan &#8217;37&#8242; gebruikt moeten worden). In bovenstaande URL is nog een request parameter opgenomen: &#8216;include_docs&#8217;. Dit zorgt ervoor dat niet alleen de document ids van de aangepaste (of toegevoegde) documenten in de feed terecht komen, maar ook de inhoud van de documenten! Dit maakt het mogelijk meteen de inhoud van de aangepaste documenten te gebruiken.</p>
<p>Na deze inleiding in de _changes feed kunnen we weer terug naar Android. In Android is het wel heel erg makkelijk om gebruik te maken van deze _changes feed: maak een URL aan, open de InputStream, en maak op basis van die InputStream een BufferedReader aan:</p>
<pre class="brush: java; title: ;">
URL url = new URL(&quot;http://localhost:5984/db/_changes?feed=continuous&amp;include_docs=true&amp;since=35&quot;);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), &quot;UTF-8&quot;));
</pre>
<p>Nu is het slechts een kwestie van regels lezen, omzetten naar JSON en binnen je applicatie gebruiken.</p>
<p>Hiervoor heb ik (net als in het Hello MapView voorbeeld) een eigen ItemizedOverlay aangemaakt. Elke keer dat er een event binnenkomt via de _changes API wordt op basis van dit object een OverlayItem aangemaakt en aan de custom ItemizedOverlay toegevoegd:</p>
<pre class="brush: java; title: ;">
    private void addEvent(JSONObject doc) {
    	int late6 = (int)Math.round(doc.optDouble(&quot;lat&quot;, 0)*1E6);
    	int lnge6 = (int)Math.round(doc.optDouble(&quot;lng&quot;, 0)*1E6);

        GeoPoint point = new GeoPoint(late6,lnge6);

        String title = doc.optString(&quot;name&quot;, &quot;unknown&quot;);
        String email = doc.optString(&quot;email&quot;, &quot;unknown&quot;);

        OverlayItem overlayitem = new OverlayItem(point, title, email);
    	Drawable marker = null;
        try {
        	marker = m_gravatar.getDrawable(email);
        } catch (Exception e) {
        	e.printStackTrace();
        }

        m_events.addOverlay(overlayitem, marker);
	m_mapView.postInvalidate();
    }
</pre>
<p>waarin het m_gravatar object een custom class is die mij in staat stelt een plaatje bij gravatar.com op te halen, dat bij het email adres hoort.</p>
<p>Mijn custom ItemizedOverlay heeft in plaats van addOverlay(OverlayItem) een addOverlay(OverlayItem, Drawable) methode, om zo elk OverlayItem een eigen plaatje te kunnen geven.</p>
<pre class="brush: java; title: ;">
	public void addOverlay(OverlayItem item, Drawable balloon) {
		if (balloon != null) {
			item.setMarker(boundCenterBottom(balloon));
		}
	    m_overlays.add(item);
	    populate();
	    //now mark it for deletion
	    m_handler.postDelayed(new ItemRemover(item), 8000);
	}
</pre>
<p>Om te voorkomen dat de MapView helemaal vol met OverlayItems komt te staan, zorg ik ervoor dat elk OverlayItem na 8 seconden wordt verwijderd:</p>
<pre class="brush: java; title: ;">
private class ItemRemover implements Runnable {
.
.
.
	public void run() {
		m_overlays.remove(m_item);
		m_mapView.postInvalidate();
	}
}
</pre>
<p>De postInvalidate() op de MapView zorgt ervoor dat de verwijderde overlays meteen verschijnen/ verdwijnen.</p>
<p>Zoals ik al in het begin vertelde: het combineren van enkele simpele technologieën kan toch al snel leuke functionaliteit opleveren. Dit simpele voorbeeld kan makkelijk uitgebouwd worden tot een applicatie die de gebruikers op een dynamische (real-time!) manier van locatie-gerelateerde informatie voorziet. Je zou bijvoorbeeld op eenvoudige wijze een applicatie kunnen bouwen die je eigen locatie naar de server stuurt. Iedereen die naar deze updates luistert zal automatisch jouw locatie op de kaart kunnen zien (en jij natuurlijk hun locatie).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncreate.nl/archives/72/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CouchDB</title>
		<link>http://www.oncreate.nl/archives/49</link>
		<comments>http://www.oncreate.nl/archives/49#comments</comments>
		<pubDate>Sun, 26 Sep 2010 11:37:59 +0000</pubDate>
		<dc:creator>Dennis Geurts</dc:creator>
				<category><![CDATA[Applicaties]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://www.oncreate.nl/?p=49</guid>
		<description><![CDATA[Enige tijd geleden ben in begonnen met CouchDB te spelen. Kennis maken met nieuwe technologieën gaat wat mij betreft altijd het beste door het bedenken van een soort project. Nu CouchDB 1.0.0  (1.0.1 is nu je beste optie!) is uitgebracht dacht ik dat het goed zou zijn om (eindelijk) een blog over mijn bevindingen tot]]></description>
			<content:encoded><![CDATA[<p><span style="color: #000000;">Enige tijd geleden ben in begonnen met CouchDB te spelen. Kennis maken met nieuwe technologieën gaat wat mij betreft altijd het beste door het bedenken van een soort project. Nu CouchDB 1.0.0  (1.0.1 is nu je beste optie!) is uitgebracht dacht ik dat het goed zou zijn om (eindelijk) een blog over mijn bevindingen tot nu toe te schrijven.</span></p>
<p><span style="color: #000000;">Ik bedacht het volgende project: Een eenvoudige (OSGi) log listener die zijn log berichten in een CouchDB database opslaat.</span></p>
<p><span style="color: #000000;">In Luminis maken we veel gebruik van </span><a href="http://osgi.nl"><span style="color: #0000ff;">OSGi</span></a><span style="color: #000000;">. Het is een modulaire framework (geschreven in Java) die je toestaat om verschillende modules (de zogenaamde &#8216;bundels&#8217;) te combineren. Elke module kan zelfstandig werken of maakt gebruik van de functionaliteiten die door andere bundels worden </span><span style="color: #000000;">aangeboden</span><span style="color: #000000;">. Een slimme combinatie van verschillende bundels zal (bijna als &#8216;emerging behavior&#8217;) resulteren in</span><span style="color: #000000;"> een volledige applicatie die perfect bij uw behoeften past.</span><span style="color: #000000;"> De functionaliteit van een bepaalde bundel wordt beschikbaar gemaakt via interfaces, zodat implementaties kunnen veranderen zonder de interactie met andere bundels te veranderen.</span></p>
<p><span style="color: #000000;">Een van de compendium diensten die beschikbaar zijn is de </span><a href="http://www.osgi.org/javadoc/r4v42/index.html?org/osgi/service/log/LogService.html"><span style="color: #0000ff;">LogService</span></a><span style="color: #000000;">. Deze service biedt andere services de mogelijkheid berichten in een centrale log aan te maken. Het is vervolgens aan de logservice implementatie waar deze log berichten belanden. Logging wordt meestal verstuurd naar je console of een bestand, wat goed is in de meeste gevallen. Soms echter, is inloggen op het apparaat zelf en het ophalen van het logboekbestand voor inspectie geen gemakkelijke taak. Neem bijvoorbeeld een Android toestel. Met dank aan Aaron Miller&#8217;s </span><a href="http://github.com/apage43/couch-android-launcher"><span style="color: #0000ff;">werk</span></a><span style="color: #000000;">, we zijn nu in staat om CouchDB draaien op Android. Android apps (</span><a href="http://www.ezdroid.com/"><span style="color: #0000ff;">EZDroid</span></a><span style="color: #000000;"> apps) zijn nu in staat om hun logging gegevens op te slaan in deze lokale instantie van CouchDB. Deze gegevens kunnen vervolgens eenvoudig worden gerepliceerd naar een andere instantie voor inspectie.</span></p>
<p><span style="color: #000000;">Ook voor beperkte apparaten (waar er bijvoorbeeld beperkte opslagruimte beschikbaar is) loggen naar een<br />
bestand is gewoon geen optie.</span></p>
<p><span style="color: #000000;">Daarom dacht ik aan de volgende scenario&#8217;s waar</span></p>
<ul>
<li><span style="color: #000000;">CouchDB is lokaal geïnstalleerd op het apparaat/server. Toegang tot CouchDB is dan gegarandeerd en geen logging wordt gemist. Een nadeel zou kunnen zijn dat de OSGi applicatie een lokale installatie van CouchDB vereist (voor degenen die dat als een nadeel zien!).</span></li>
<li><span style="color: #000000;">CouchDB is geïnstalleerd op een externe instantie. Toegang tot de CouchDB instantie zou wegens het netwerk instabiliteit kunnen worden onderbroken. Dan kunnen sommige log berichten verloren gaan. Omdat de meeste applicaties een werkende internet verbinding vereisen, ik denk dat we hiermee kunnen leven.</span></li>
</ul>
<p><span style="color: #000000;">Het doel van het project is een JSON representatie van de werkelijk gelogde berichten op te slaan in CouchDB. Dit kan gemakkelijk worden bereikt door middel van een </span><a href="http://www.osgi.org/javadoc/r4v42/index.html?org/osgi/service/log/LogListener.html"><span style="color: #0000ff;">LogListener</span></a><span style="color: #000000;"> .</span></p>
<p><span style="color: #000000;">In beide gevallen ontvangt de OSGi LogListener, die binnen de OSGi applicatie &#8216;leeft&#8217;, alle </span><a href="http://www.osgi.org/javadoc/r4v42/index.html?org/osgi/service/log/LogEntry.html"><span style="color: #0000ff;">LogEntries</span></a><span style="color: #000000;"> die naar de logservice worden verzonden (met wat extra meta-data). Het enige wat de LogListener dan nog hoeft te doen is de conversie naar JSON en het aanmaken van een nieuw document in een database op het CouchDB server. Als men dan de log-berichten zou willen inspecteren, kan een enkele call naar de CouchDB server een replicatie van de database naar uw lokale CouchDB instantie initiëren. Zodra dit gebeurd is, kun je off-line de logs inspecteren.</span></p>
<p><span style="color: #000000;">Installatie en het basis gebruik van CouchDB wordt hier niet beschreven, er zijn al uitstekende beschrijvingen beschikbaar op de </span><a href="http://wiki.apache.org/couchdb/Installing_on_OSX"><span style="color: #0000ff;">Wiki</span></a><span style="color: #000000;">, </span><a href="http://github.com/halorgium/couchdb"><span style="color: #0000ff;">Halorgium&#8217;s GitHub</span></a><span style="color: #000000;"> en </span><a href="http://guide.couchdb.org/"><span style="color: #0000ff;">O&#8217;Reilly Free Book</span></a><span style="color: #000000;"> .</span></p>
<p><span style="color: #000000;">Om bovengenoemde te testen heb ik een LogListener implementatie gemaakt. Ik gebruik </span><a href="http://code.google.com/p/json-simple/"><span style="color: #0000ff;">json-simple</span></a><span style="color: #000000;"> om een LogEntry te converteren naar JSON en dat resulteert in een JSON Object, zoals bijvoorbeeld:</span></p>
<pre class="brush: java; title: ;">
{
'message': 'This is a test message',
'time': 1269783246909,
'level': 'LOG_DEBUG',
'serviceReference': {},
'bundle': {
   'id': 5,
    'lastModified': 1269783246510,
    'location': 'file:bundle/net.luminis.log.couchdb-1.0.0.jar',
    'symbolicName': 'net.luminis.log.couchdb'
    }
}
</pre>
<p><span style="color: #000000;">Een unieke serverID/instanceID zou ook kunnen worden toegevoegd om onderscheid te kunnen maken tussen server instanties, mocht je logging van verschillende apparaten naar een centrale server te sturen.</span></p>
<p><span style="color: #000000;">De bovenstaande JSON data POST ik naar de server. Omdat ik zelf geen &#8216;_id&#8217; in de JSON string heb gedefinieerd, zal CouchDB er een voor mij aanmaken. De HTTP (1.0) POST wordt uitgevoerd door middel van een kale socket naar de CouchDB server.:</span></p>
<pre class="brush: java; title: ;">
POST /db HTTP/1.0
Content-Length: xxx
Content-Type: application/json

{ ... the data here ... }
</pre>
<p><span style="color: #000000;">Het antwoord is ook een geldig JSON object die kan worden gecontroleerd om te kijken of alles is goed gegaan (samen met de HTTP response code, natuurlijk).</span></p>
<p><span style="color: #000000;">In mijn huidige implementatie, kan ik kiezen tussen twee modes; ofwel elk bericht wordt verstuurd naar de CouchDB instantie op een bepaalde tijdstip, of ik stuur alle berichten in bulk-modus elke x seconden. De laatste is waarschijnlijk het beste voor remote couchdb gevallen.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.oncreate.nl/archives/49/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating OnCreate</title>
		<link>http://www.oncreate.nl/archives/10</link>
		<comments>http://www.oncreate.nl/archives/10#comments</comments>
		<pubDate>Tue, 21 Sep 2010 12:51:28 +0000</pubDate>
		<dc:creator>Dimitriy</dc:creator>
				<category><![CDATA[Nieuws]]></category>

		<guid isPermaLink="false">http://www.oncreate.nl/?p=10</guid>
		<description><![CDATA[Op dit moment wordt er aan OnCreate community gewerkt. // onCreate.java public class createOnCreate { public static void main (String args[]) { System.out.println (&#34;OnCreate is being created!&#34;); } }]]></description>
			<content:encoded><![CDATA[<p>Op dit moment wordt er aan OnCreate community gewerkt.</p>
<pre class="brush: java; title: ;">//  onCreate.java
public class createOnCreate {
   public static void main (String args[]) {
      System.out.println (&quot;OnCreate is being created!&quot;);
   }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.oncreate.nl/archives/10/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

