FlitsWoorden – Een onverwacht succes?

Niets zo leuk als voorlezen voor de kinderen. Op een zeker moment gaan de appeltjes van je oog ook zelf het lezen ontdekken. Maar voordat geen Donald Duck meer veilig is, moet eerst worden geoefend. Op school wordt gewerkt met ‘kernen’. Kleine woordjes, die worden aangeleerd en getest. De kernen in de App komen niet exact overeen met de school-kernen, maar ze zijn wel ongeveer van hetzelfde moeilijkheidsniveau.Als een klas het eind van een kern bereikt heeft, worden één-minuut leestesten afgenomen. Hoe meer woordjes het kind kan lezen in een minuut, hoe beter.

Rond dit idee zette ik FlitsWoorden in de markt. Ik had niet de verwachting dat het een groot succes zou gaan worden. Ik dacht dat ouders liever een boek zouden pakken om hun kinderen te helpen met lezen. Toch werd FlitsWoorden in 3 maanden tijd bijna 3.200 keer geïnstalleerd! Het idee achter de app is vrij eenvoudig. Er wordt een woordje getoond. Als je tikt op het woordje, verschijnt het volgende woord. Eind maart 2012 maakte ik de extra test-functionaliteit; Een stopwatch die een minuut loopt en telt hoeveel woordjes er zijn gelezen.

Doordat de App op verschillende sites werd besproken en zelfs in nieuwsbrieven van basisscholen naar voren kwam, hoefde ik zelf qua marketing weinig te doen. Het af en toe sturen van een tweet naar een basisschool (of beter : de it-beheerder van die school) was voldoende.

TECHNIEK

FlitsWoorden bevat een interessante techniek voor het opslaan en ophalen van de woordjes. Een SQL Database wordt, samen met de applicatie, op de telefoon geïnstalleerd. In die database staan de ca 3.500 woordjes. Het was een behoorlijke uitdaging om ervoor te zorgen dat de App ook te updaten was. Als een programma update plaatsvindt, hoeft de Database niet te worden vervangen. Als ik een nieuwe database op de telefoon wil installeren, dan zal ik de oude moeten verwijderen. Om dit te borgen, heb ik in de Database een versietabel opgenomen. In de App wordt de versie van de geïnstalleerde database vergeleken met de versie van de database die in het pakket (.APK) zit. Als er een verschil is, wordt de database op de telefoon vervangen. In de code snippets laat ik zien hoe dat werkt.

In de eerste versie van FlitsWoorden, werd de Database gevuld op het moment dat de App voor het eerst werd opgestart. Dit duurde lang en was niet full-proof (als de telefoon uitgeschakeld werd, zou de database corrupt raken). Daarom heb ik besloten de database in te pakken bij de App (in de Assets-folder).

Qua lettertypen is FlitsWoorden ook een hele puzzel geweest. Ik wilde zo dicht mogelijk blijven bij het lettertype dat ook op school wordt aangeboden. Door een oerwoud van pedagogen, onderwijsdeskundigen, dyslexie-specialisten kwam ik uiteindelijk op 2 lettertypen. De App moest dus de keuze tussen deze 2 lettertypen mogelijk te maken. Ik kreeg van de deskundigen (die ik voor mijn eigen vermaak maar “Schriftgeleerden” noemde 🙂 ) allerlei suggesties, die elkaar soms ook tegenspraken. Uiteindelijk moest ik denken aan mijn doel en besloot ik te stoppen met het onderzoeken van de onderwijskundige kant. De kindjes moesten zelf maar besluiten wat ze het liefst zouden lezen. 😀

VERDIENMODEL

FlitsWoorden maakt gebruik van in-app advertising. Onderaan het scherm worden advertenties getoond. Ik voelde me enigszins bezwaard. Was het wel ‘chique’ om geld te verdienen aan een App voor kinderen? Gelukkig merkte ik snel dat de advertenties die Google uitkoos om te laten zien, echt waarde toevoegden! Leuke vakanties, uitjes voor kinderen, remedial teaching. Echt bijzondere extraatjes in mijn App!

TIPS

  1. Laat je, zeker op belangrijke punten, adviseren door professionals. Door kennis te maken met deze mensen worden ook deuren geopend die anders misschien gesloten blijven.
  2. Kies met zorg de categorieën waarin je de App publiceert. Op basis van deze categorisering worden advertenties uitgekozen om te tonen. De juiste advertenties voegen waarde toe aan je App.
  3. De technische Architectuur van je App moet zoveel mogelijk fool-proof zijn. Als een eindgebruiker de App afbreekt, of onverwachte dingen doet, moet je App voldoende robuust zijn om daar op een correcte wijze op te reageren.

CODE SNIPPETS

Om een database-update makkelijk mogelijk te maken, moet worden gecontroleerd welke versie geinstalleerd is op de telefoon. Deze versie wordt vergeleken met de versie die in de .APK is opgenomen (PackedDBVersion). Als er verschillen zijn, wordt de database uit de APK naar de telefoon gekopieerd (overwrite).

public void CheckInstalledDBVersion() throws NullPointerException, IOException {
	try {	

		Cursor cursor = (Cursor) WoordData.fetchDBInfo();
		cursor.moveToFirst();
		InstalledDBversion = cursor.getString(0);
		cursor.close();
		WoordData.close();
		Log.d("Installed", "" + InstalledDBversion);
		Log.d("Packed", "" + PackedDBversion);

		} 

	catch (RuntimeException e) {
		InstalledDBversion = "00";
		Log.d("RTE", ".. but we've catched it!");
	} finally {
		if (InstalledDBversion.equals(PackedDBversion)) {
			Log.d("Check", "They are the same");
			initialiseDatabase = true;
			// Installed DBVersion == Packed DBVersion .. nothing happens
		} else {
			showDialog(DBCHECKFAILDIALOG);
			initialiseDatabase = false;
			copyDB();
		}
	}
}

Ook een leuk extra’tje ; De knop om de selectielijsten aan en uit te zetten verandert van functie (en dus ook het opschrift verandert). Als minder dan de helft van de kernen geselecteerd is, heeft de knop de functie “alles uitzetten”. Als meer dan de helft al ‘aan’ staat, verandert de functie van de knop in “alles aanzetten”. Zie hier de code;

private void ClearSelections() {
	Button btnClear = (Button) findViewById(R.id.btnClear);
	int count = this.listView.getAdapter().getCount();
	int countchecked = 0;
	for (int i = 0; i < al.size(); i++) {
		if (listView.getCheckedItemPositions().get(i))
		countchecked++;
	}

	if (countchecked > (count / 2)) {
	if (countchecked == count) {
		for (int i = 0; i < count; i++) {
			this.listView.setItemChecked(i, false);
		}

	} else {
		for (int i = 0; i < count; i++) {
			this.listView.setItemChecked(i, true);
			}
		}
	} else {
		if (countchecked == 0) {
			for (int i = 0; i < count; i++) {
				this.listView.setItemChecked(i, true);
			}
		} else {
			Log.d("", "minder dan de helft gecheckt");
			for (int i = 0; i < count; i++) {
			this.listView.setItemChecked(i, false);
			}
		}
	}
	// Save the new selections
	SavePreferences();
}
You can leave a response, or trackback from your own site.

5 Responses to “FlitsWoorden – Een onverwacht succes?”

  1. Michiel schreef:

    Heey,

    Ik vroeg me af hoe je het voor elkaar gekregen hebt dat je door op het scherm te klikken naar het volgende woord gaat. Heb je een onzichtbare knop gemaakt ofzo?

  2. admin schreef:

    Hoi, Michiel.. een onzichtbare is niet eens nodig. De TextView waar je het woord in laat zien, kun je gewoon clickable maken door een onClickListener te implementeren :

    tvFlitswoord.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {

    // HIER DE CODE DIE UITGEVOERD WORDT BIJ EEN CLICK…

    if (!GameManager.disableUserInput){
    // Here’s a randomizer I use to random the words.
    // Might want to include an array to prevent a word from coming
    // back < 5 cycles. Random rand = new Random(); Log.d("Random", "" + rand.nextInt(wordlistarray.size())); randomwordnr = rand.nextInt(wordlistarray.size()); DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics( displaymetrics); // int ht = displaymetrics.heightPixels; int wt = (displaymetrics.widthPixels - 150); // Ádjust text width - Werkt nog niet optimaal; even bijlezen over tablets enzo. final int INITIAL_TEXTSIZE = 150; final int TEXTVIEW_WIDTH = wt; // I use the background image to // find the width, but you can // use a fixed value or whatever // other method you prefer. // final int TEXTVIEW_HEIGHT = ht; text = wordlistarray.get(randomwordnr); final String kerncontainingcurrentword = kernlistarray .get(randomwordnr); tvKern.setText(kerncontainingcurrentword); Log.d("", "" + PrefShowKern); tvFlitswoord.setGravity(Gravity.CENTER); tvFlitswoord.setText(text); int size = INITIAL_TEXTSIZE; tvFlitswoord.setTextSize(INITIAL_TEXTSIZE); while (tvFlitswoord.getPaint().measureText(text) > TEXTVIEW_WIDTH)
    tvFlitswoord.setTextSize(–size);

    Log.d(“FontSize”, “” + tvFlitswoord.getTextSize());

    if (timer.running){
    wordsRead++;
    }

    wordnr++;
    if (wordnr == wordlistarray.size()) {
    wordnr = 0;
    //END TODO
    }

    }
    }

    • admin schreef:

      Deze code kan vast veel beter.. maar het werkt.. en was mijn 2e app 😉

    • Michiel schreef:

      Bedankt! Grappig dat het antwoord soms veel makkelijker is dan je in het eerste begin zou denken. Ik had nooit bedacht dat de linearlayout ook clickable kon maken.

      • admin schreef:

        Niet de Layout zelf, maar de TextView waarin de woorden getoond worden, wel. Heb je de nieuwste app, FlitsSommen al gezien?

Leave a Reply