ID.nl logo
Zelf mobiele apps bouwen (deel 6)
© PXimport
Huis

Zelf mobiele apps bouwen (deel 6)

In veel apps zal het nodig zijn om gegevens te bewaren. In dit hoofdstuk van de basiscursus Apps bouwen behandelen we daarom enkele methodes voor lokale opslag. Daarmee bedoelen we de opslag van gegevens op het toestel zelf.

Hier kun je deel 5 van de cursus vinden.

Code downloaden

In dit deel van de cursus Apps bouwen worden wat voorbeelden van stukjes code gegeven. Omdat overtikken van code erg foutgevoelig is, kun je die code ook downloaden en daarna bekijken of kopiëren. Zie het bestand code-appsbouwen-deel6.txt.

In de eerdere lessen hebben we voor het bewaren van gegevens binnen je app met variabelen gewerkt. Als de app wordt afgesloten, ben je al die gegevens kwijt, wat natuurlijk niet altijd gewenst is. Daarom zul je in een app regelmatig gegevens fysiek opslaan voor later gebruik. Voor lokale gegevensopslag zijn binnen Android meerdere mogelijkheden. Eenvoudig maar praktisch zijn de zogenoemde SharedPreferences, waarbij je gegevens in zogenoemde naam/waarde-paren (of key/value) kunt bewaren. De waarde kan daarbij bijvoorbeeld een boolean, getal of tekst zijn. Dat maakt het ideaal om inhoud van bepaalde variabelen te bewaren, zoals de highscore van een game. We laten zien hoe dat werkt en gebruiken we het als uitbreiding voor de dobbelsteen-app.

©PXimport

Kotlin Koans

Voordat je in het diepe springt, kan het geen kwaad nog wat bij te leren over Kotlin. Dat kan eventueel direct binnen IntelliJ IDEA of Android Studio dankzij een plug-in genaamd EduTools en de cursus Kotlin Koans die daarin is opgenomen. Dit zijn kleine problemen die je direct binnen de ontwikkelomgeving kunt oplossen. De opdrachten met uitleg helpen je om de syntax van de taal beter te begrijpen. Om de plug-in te installeren, ga je in IntelliJ IDEA of Android Studio naar File / Settings en kies je Plugins. Schakel de weergave bovenaan om naar Marketplace. Zoek de plug-in EduTools op en kies Install. Na het installeren kies je Restart IDE. Ga dan naar File / Learn and Teach / Browse Courses. Hier kun je uit de beschikbare cursussen kiezen. Onder Community Courses vind je Kotlin Koans. Als je een account maakt en inlogt, kun je je vorderingen online bij laten houden.

©PXimport

SharedPreferences

01 Waarden bewaren

Met SharedPreferences biedt Android een relatief eenvoudige manier om gegevens voor je app op te slaan onder een naam. We gaan het gebruiken als uitbreiding voor onze dobbelsteen-app. Op de achtergrond wordt hiervoor een bestand gebruikt. Er zijn eenvoudige methodes om gegevens op te vragen of te bewaren. Gegevens kun je overal in je eigen app raadplegen, maar zijn niet beschikbaar voor andere apps. Daarom kun je het veilig gebruiken voor bijvoorbeeld het opslaan van inloggegevens. We demonstreren SharedPreferences binnen onze dobbelsteen-app. We gaan hiermee het aantal worpen en de som bewaren, waarmee je dan zelf het gemiddelde van alle worpen kunt berekenen.

02 Initialisatie SharedPreferences

Gebruik je SharedPreferences binnen een activity, dan kun je bij de initialisatie getPreferences gebruiken. Wil je met meerdere bestanden gaan werken of de gegevens in meerdere activity’s gebruiken, dan gebruik je getSharedPreferences in combinatie met een naam. Die naam kun je zien als een bestandsnaam. Deze laatste optie gebruiken we in ons voorbeeld en als naam kiezen we worpen. Bij de initialisatie geef je naast de naam ook de modus op, zoals MODE_PRIVATE, waarmee je bepaalt dat het bestand niet met andere apps kan worden gedeeld. Dat kan als je dat al zou willen tegenwoordig overigens ook niet meer via SharedPreferences. We gaan werken binnen de eerder geschreven functie werpDobbelsteen(). Eerst initialiseren we daarin onze SharedPreferences, die we beschikbaar maken onder de variabele sharedPref:

var sharedPref: SharedPreferences = getSharedPreferences("worpen", MODE_PRIVATE)

©PXimport

03 Waarden raadplegen

In de functie gaan we direct nadat we met de regel val dobbelsteenInt = (1..6).random() een willekeurig getal voor de worp hebben bepaald het huidige aantal worpen (aantal) ophalen. Hierbij geven we bij de aanroep aan dat 0 de standaardwaarde (‘default’) is. Dat is het geval als je nog geen worp hebt gedaan in de app. We tellen er daarna meteen één bij op, zodat we het nieuwe aantal worpen hebben:

var aantal = sharedPref.getInt("aantal", 0) + 1

Op dezelfde manier halen we de bewaarde som van alle worpen op in de variabele som met ook weer 0 als standaardwaarde. We tellen de dobbelsteenworp erbij op en krijgen hiermee de nieuwe som van alle worpen:

var som = sharedPref.getInt("som", 0) + dobbelsteenInt

We gaan de nieuwe waarden voor aantal en som meteen bewaren. Eerst moeten we daarvoor een zogeheten editor voor SharedPreferences definiëren:

val editor = sharedPref.edit()

Daarna schrijven we de twee waarden weg onder de namen aantal en som:

editor.putInt("aantal", aantal)

editor.putInt("som", som)

Als laatste ronden we af met:

editor.apply()

Vervolgens berekenen we zelf het gemiddelde over alle worpen als Double, waarna we met een trucje de waarde afronden op twee decimalen:

var gemiddelde = som.toDouble() / aantal

var gemiddeldeAfgerond = gemiddelde.toBigDecimal().setScale(2, RoundingMode.UP).toDouble()

Als laatste bereiden we alvast de melding voor die we straks via een Toast gaan geven:

var toastMsg: String = "Aantal worpen: " + aantal + " - gemiddelde: " + gemiddeldeAfgerond

Vervolgens laten we op het moment dat de worp wordt getoond ook de melding via Toast zien:

Handler(Looper.getMainLooper()).postDelayed({

textWorp.text = dobbelsteenInt.toString();

Toast.makeText(this, toastMsg, Toast.LENGTH_SHORT).show()

}, 500)

Opslag van SharedPreferences

Je vraagt je misschien af waar de SharedPreferences precies worden opgeslagen. Als de emulator is gestart, kun je via het menu View / Tool Windows naar Device File Explorer. Dat is het bestandssysteem van het (in dit geval virtuele) toestel. Blader naar de map data/data en zoek daarin de naam van jouw app op, bijvoorbeeld com.example.dobbelsteen. Hierin vind je de map shared_prefs met daarin het bestand worpen.xml.

©PXimport

04 Uiteindelijke functie

Is alles klaar, dan ziet de uiteindelijke functie werpDobbelsteen() eruit zoals hieronder.

private fun werpDobbelsteen() {

var sharedPref: SharedPreferences = getSharedPreferences("worpen", MODE_PRIVATE)

val textWorp: TextView = findViewById(R.id.text_worp)

textWorp.text = "..."

val dobbelsteenInt = (1..6).random()

var aantal = sharedPref.getInt("aantal", 0) + 1

var som = sharedPref.getInt("som", 0) + dobbelsteenInt

val editor = sharedPref.edit()

editor.putInt("aantal", aantal)

editor.putInt("som", som)

editor.apply()

var gemiddelde = som.toDouble() / aantal

val gemiddeldeAfgerond = gemiddelde.toBigDecimal().setScale(2, RoundingMode.UP).toDouble()

var toastMsg: String = "Aantal worpen: " + aantal + " - gemiddelde: " + gemiddeldeAfgerond

Handler(Looper.getMainLooper()).postDelayed({

textWorp.text = dobbelsteenInt.toString();

Toast.makeText(this, toastMsg, Toast.LENGTH_SHORT).show()

}, 500)

}

©PXimport

Emulator als onderdeel van Android Studio

Bij het werken aan deze app hebben we de emulator niet in een apart venster getoond, maar als onderdeel van de gebruikersinterface van Android Studio. Dat werkt zeker op een wat groter scherm een stuk prettiger. Wil je dat zelf ook zo instellen? Ga dan naar File / Settings en blader naar Tools / Emulator. Zet een vinkje bij Launch in a tool window.

©PXimport

Klassen en objecten

Voor complexere gegevens zijn variabelen wat te beperkt en zul je al snel met objecten en klassen (classes in het Engels) willen werken. De termen spelen een belangrijke rol binnen Android. Enige basiskennis is dan ook nodig als je met Room gaat werken (wat verderop in de paragraaf ‘Databases’ aan de orde komt.

05 Sjabloon voor objecten

Bij het (object-georiënteerd) programmeren en zo ook bij Android kom je de begrippen klasse (of class) en object tegen. Een klasse kun je zien als een sjabloon waarmee je objecten kunt maken. Een klasse bevat eigenschappen in de vorm van ‘gewone’ variabelen. Voor een persoon zijn dat bijvoorbeeld een naam, geslacht en leeftijd. Een klasse kan ook functies of methodes bevatten: handelingen die kunnen worden uitgevoerd. Voor een persoon kun je denken aan eten, drinken, lopen of slapen. Een specifieke persoon kun je zien als object of instantie van deze klasse. Aan de hand van enkele voorbeelden zullen we dit verduidelijken.

06 Klasse en object maken

Voor de voorbeelden gebruiken we weer IntelliJ IDEA. We voeren onderstaande regels in binnen de functie main(). Hierin beschrijven we eerst de class Persoon() met daarin de eigenschappen naam, geslacht en leeftijd:

class Persoon() {

var naam = ""

var geslacht = ""

var leeftijd = 0

}

Daarna maken we een object op basis van deze klasse:

var Collega = Persoon()

Hierna kun je de eigenschappen van het object eenvoudig veranderen, bijvoorbeeld:

Collega.naam = "Jan"

Collega.geslacht = "m"

Collega.leeftijd = 35

println(Collega.naam) // Jan

Je kunt ook andere objecten maken met weer andere eigenschappen op basis van dezelfde klasse:

var Receptioniste = Persoon()

Receptioniste.naam = "Lisa"

Receptioniste.geslacht = "v"

Receptioniste.leeftijd = 39

©PXimport

07 Functies in je klasse

Een klasse bevat vaak ook functies. Als voorbeeld voegen we een functie stelVoor() toe die een String retourneert met een beschrijving van de persoon:

class Persoon() {

var naam = ""

var geslacht = ""

var leeftijd = 0

fun stelVoor() : String {

return "Hallo, ik heet " + naam + " en ik ben " + leeftijd + " jaar oud."

}

}

Daarna kun je de functie stelVoor() gebruiken voor je object en het resultaat bijvoorbeeld printen:

var Collega = Persoon()

Collega.naam = "Jan"

Collega.geslacht = "m"

Collega.leeftijd = 35

println(Collega.stelVoor()) // Hallo, ik heet Jan en ik ben 35 jaar oud.

08 Getters en setters

In veel programmeertalen kom je zogenoemde getters en setters tegen. Een getter is in feite een methode om de waarde van een eigenschap te lezen, terwijl je met een setter een waarde toekent. Binnen Kotlin worden ze automatisch gemaakt, maar je kunt ze wel beïnvloeden. Als voorbeeld maken we een aangepaste setter voor de eigenschap leeftijd.

class Persoon() {

var naam = ""

var geslacht = ""

var leeftijd = 0

set(value) {

field = value

if (value >= 18 ) volwassen = true

}

var volwassen = false

}

Als de leeftijd wordt aangepast, wordt eerst met field = value de waarde toegekend. Daarna stellen we de boolean volwassen in, zodat deze de juiste waarde krijgt, afhankelijk van de leeftijd. In het onderstaande voorbeeld zie je hoe deze eigenschap volwassen automatisch wordt bijgewerkt als de leeftijd wordt aangepast:

var Collega = Persoon()

Collega.naam = "Jan"

Collega.leeftijd = 17

println(Collega.volwassen) // false

Collega.leeftijd = 25

println(Collega.volwassen) // true

Bibliotheken voor objecten en JSON

Binnen Android zul je niet alleen vaak met klassen en objecten werken, maar ook – zeker bij het gebruik van API’s op internet – de taal JSON tegenkomen. Er zijn diverse handige bibliotheken waarmee je JSON kunt converteren naar objecten en omgekeerd. Bekende voorbeelden zijn Moshi, Gson en Jackson.

©PXimport

Databases

De SharedPreferences uit het begin van dit artikel zijn handig, maar vrij beperkt. Veel flexibeler ben je met SQLite, waarmee we in de rest van het artikel gaan werken, in combinatie met Room. SQLite is een zogenoemde relationele database. Zo’n database is opgebouwd uit tabellen die een onderlinge relatie met elkaar (kunnen) hebben. Voor het doorzoeken van de tabellen gebruik je opdrachten geschreven in de taal SQL. Room kun je als een abstractie-laag voor deze database zien.

In je code hoef je niet meer met SQL-opdrachten te werken om gegevens in je database te verwerken. Je maakt in feite gebruik van objecten. Omdat Room de voorkeursmethode voor het werken met SQLite is, krijgt het ook aandacht in deze cursus.

©PXimport

09 Takenlijst bijhouden

We gaan een database gebruiken voor het bijhouden van een takenlijst. Een tabel in Excel dient als voorbeeld (zie afbeelding). Hierin zie je de kolommen id, titel en belangrijk. Elke rij bevat een taak met een unieke id. Die zul je in Excel misschien niet altijd gebruiken, maar is in een database gangbaar om te zorgen dat elke rij uniek is en gemakkelijk aanwijsbaar. Voor het veld belangrijk gebruiken we hier een boolean om aan te geven of de taak belangrijk is. Met de Excel-tabel als voorbeeld is de transitie naar SQLite eenvoudig.

©PXimport

10 SQLite

In de volgende deel van de cursus gaan we met Room aan de slag, dat op de achtergrond gebruikmaakt van SQLite. Daarom beginnen we met een uitleg van SQLite. Stel dat je van onze takenlijst een SQLite-database wilt maken, dan kan dat met de volgende opdracht:

CREATE TABLE taak (

id INTEGER PRIMARY KEY,

titel TEXT NOT NULL,

belangrijk INTEGER NOT NULL

);

Bovenstaande wordt ook wel een database-schema genoemd. Hierbij dient de id voor het identificeren van elke rij, wat we aangeven met PRIMARY KEY. Merk op dat we voor de kolom belangrijk geen boolean maar een integer gebruiken, omdat SQLite geen booleans ondersteunt. Je kunt gewoon 0 voor false of 1 voor true gebruiken. Wil je gegevens ophalen uit de database, dan gebruik je een zogenoemde SELECT. Zo’n verzoek wordt ook wel een query genoemd. Wil je bijvoorbeeld de id en titel van alle taken ophalen, dan kan dat met onderstaande query:

SELECT id, titel FROM taken;

Je kunt met een wildcard ook in één keer alle taken ophalen:

SELECT * FROM taken;

Wil je een selectie maken en bijvoorbeeld alleen de belangrijke taken ophalen, dan kun je de SELECT uitbreiden met extra condities via een WHERE, wat zodoende als een soort filter werkt:

SELECT * FROM taken WHERE belangrijk=1

Op vergelijkbare wijze zijn er opdrachten om bijvoorbeeld rijen toe te voegen, bij te werken of te verwijderen. Omdat we bij de kolom id de optie PRIMARY KEY hebben gebruikt, zal SQLite er zelf voor zorgen dat (als je een rij toevoegt) een unieke id wordt toegekend door de huidige hoogste waarde met één op te hogen. In je app voor Android kun je prima met SQLite werken, maar je hebt dan wel relatief veel code nodig. Room maakt het eenvoudiger en geeft ook andere voordelen.

11 Relaties tussen tabellen

SQLite en varianten worden zoals gezegd ook wel relationele databases genoemd. Dat komt omdat er meestal meerdere tabellen zijn die met elkaar samen (kunnen) hangen. Je zou onze tabel bijvoorbeeld uit kunnen breiden met een kolom perid en vervolgens een tweede tabel maken met de naam persoon en de kolommen perid en naam. Via perid maak je dan een relatie tussen die twee tabellen. Je kunt dit gebruiken om bijvoorbeeld taken aan een bepaalde persoon toe te wijzen. De afbeelding laat dat voorbeeld in Excel zien. Je zou hierna een query kunnen schrijven om bijvoorbeeld alle taken voor een bepaalde persoon op te halen.

©PXimport

▼ Volgende artikel
❄️ Plaknacht op komst? Zo houd je het hoofd (en de slaapkamer) koel
© ID.nl
Gezond leven

❄️ Plaknacht op komst? Zo houd je het hoofd (en de slaapkamer) koel

Overdag is de warme nog wel uit te houden – lekker in de schaduw met een koel drankje of een ijsje. Maar hitte die 's nachts blijft hangen, da's een ander verhaal. Daardoor verandert je slaapkamer al snel in een broeikas. Heb je geen airco in huis maar wil je niet de hele nacht woelen, zweten en wakker liggen? Met deze slimme tips overleef je zelfs de ergste plaknacht!

Zo overleef je een plaknacht: ☀️ Wat je overdag alvast kunt doen: Houd zon en hitte buiten Kies licht en ademend beddengoed Niet binnen koken 🌘 Wat je 's nachts kunt doen: Laat het goed doorwaaien Drink voldoende en neem een lauwe douche Koelen zonder ventilator Koelen mét ventilator Hang een nat laken op

Lees ook, voor de volgende plaknachten: Houd je huis koel: de voor- en nadelen van airco in huis

☀️ Wat je overdag alvast kunt doen:

1: Houd zon en hitte buiten

Doe overdag de gordijnen dicht, zeker in kamers waar de zon vol op staat. Ook zonwering helpt om de warmte te weren. Geen dikke gordijnen of screens? Dan kan warmtewerende raamfolie een uitkomst zijn. Dat kaatst het zonlicht terug en voorkomt dat je slaapkamer verandert in een oven.

2: Kies licht en ademend beddengoed

Donkere stoffen houden warmte vast, lichte kleuren weerkaatsen juist. Kies daarom voor lichtgekleurde lakens van katoen of linnen. Die stoffen ademen beter en voelen minder klam aan als het warm is.

3: Kook niet binnen

Koken met oven of fornuis maakt het in huis alleen maar warmer. Eet dus licht en koud: een salade, wat fruit of brood met iets fris. Moet het warm zijn? Gebruik een airfryer of grillplaat buiten op het balkon of in de tuin. Of gooi gewoon de barbecue aan!

Lees ook: Dit zijn dé BBQ-trends voor 2025

🌘 Wat je 's nachts kunt doen

4: Laat het goed doorwaaien

Zodra het buiten afkoelt, zet je ramen en deuren tegen elkaar open. Zo ontstaat er luchtcirculatie en komt er koelere buitenlucht binnen. Sluit alles weer zodra het buiten warmer wordt of de zon opkomt. Zo blijft de koelere lucht langer hangen.

5: Drinken en douchen

Drink voldoende water, ook vlak voor het slapengaan. Dat helpt je lichaam afkoelen van binnenuit. Een lauwe douche doet ook wonderen. Te koud douchen werkt juist averechts: je lichaam gaat dan extra warmte produceren om te compenseren.

6: Koelen zonder ventilator

Geen ventilator in huis? Zet een paar kommen met ijskoud water in je slaapkamer. Dat helpt de luchtvochtigheid én de temperatuur te verlagen. Let wel op: niet naast je bed of bij stopcontacten. Een omgestoten bak water is geen pretje om 3 uur 's nachts.

7: Koelen mét ventilator

Heb je wel een ventilator? Zet er dan een schaal met ijswater of ijsblokjes voor. Zo blaast hij niet alleen warme lucht in het rond, maar verspreidt hij echte koelte. Zorg ook hier voor een veilige opstelling – water en elektriciteit blijven een slechte combinatie. Wat ook werkt, is een aantal (plastic) flessen voor 80 procent vullen met water en in de vriezer leggen. Haal deze edruit en zet ze voor je gaat slapen voor de draaiende ventilator.

©yulia_seraya

8: Hang een nat laken op

Hang een vochtig laken voor een open raam. De lucht die binnenkomt wordt daardoor vanzelf wat koeler. Zeker bij droge, hete lucht uit het zuiden kan dat net het verschil maken tussen woelen en slapen.

Waarom deze tips echt werken Al deze tips maken slim gebruik van basisprincipes uit de natuurkunde: warme lucht stijgt op, lichte kleuren weerkaatsen warmte in plaats van het te absorberen en ventilatie versnelt verdamping van zweet – het natuurlijke koelsysteem van je lichaam. Door 's avonds alles af te sluiten en pas weer te openen als het buiten afkoelt, houd je de warmte buiten en de rust binnen.


▼ Volgende artikel
Van muis tot monitor: zo koppel je bluetooth-apparaten aan je pc
© Marut - stock.adobe.com
Huis

Van muis tot monitor: zo koppel je bluetooth-apparaten aan je pc

De meeste apparaten die je aansluit op je computer, kun je koppelen via bluetooth. Daarvoor moet deze technologie wel ingebouwd zijn in de pc, of je moet gebruikmaken van een usb-bluetooth-adapter. Op twee manieren kun je de pc koppelen met bluetooth-apparaten.

In dit artikel laten we zien op welke wijzen je bluetooth-apparaten aan je pc kunt koppelen:

  • Via Windows Instellingen
  • Via de taakbalk
  • Via een snelkoppeling naar het Instellingen-venster

Lees ook: 2,4 GHz vs. bluetooth: welke beter is voor accessoires

Muis, toetsenbord, speakers, headset, ...

Er zijn talloze accessoires om aan je pc te koppelen

Stap 1: Via Instellingen

Eerst moet je het externe apparaat instellen, waardoor het zichtbaar wordt als het binnen bereik komt van de pc. Typ in het Windows-zoekveld het woord bluetooth, zodat je Bluetooth- en andere apparaatinstellingen kunt openen. Verifieer boven in dit scherm dat bluetooth aanstaat.

Klik nu op de knop Apparaat toevoegen. In het volgende venster selecteer je Bluetooth. Hierdoor zou in het volgende venster ieder apparaat moeten verschijnen waarvan bluetooth is ingeschakeld. Als het hier niet te zien is, moet je de handleiding van het apparaat controleren of de website van de fabrikant.

Selecteer het apparaat dat je wilt koppelen en volg alle instructies. Wanneer het proces voltooid is, klik je op Gereed. Als het goed is, wordt dit apparaat nu weergegeven als Gekoppeld. Om niet iedere keer naar het venster Instellingen te hoeven gaan, bestaan er enkele shortcuts.

In de bluetooth-instellingen zie je welke apparaten al gekoppeld zijn.

Stap 2: Via de taakbalk

Je kunt ook gebruikmaken van de taakbalk. Aan de rechterkant van de taakbalk vind je het bluetooth-pictogram. Mogelijk zit het onder de verborgen pictogrammen. Door op het pijltje te klikken, vouw je het menu open. Als je op dit pictogram klikt, zie je ook de verbonden apparaten. En via de knop Meer instellingen kom je bij de lijst van alle apparaten die je kunt verbinden.

In Windows 11 zijn deze instellingen samengevoegd in de Snelle instellingen, rechts van de taakbalk.

Stap 3: Snelkoppeling

Je kunt ook een eigen snelkoppeling maken om snel naar het Windows Instellingen-venster met de bluetooth-instellingen te gaan. Klik met rechts op het bureaublad en selecteer in het contextmenu de opdracht Nieuw / Snelkoppeling. Hierdoor opent een pop-up Snelkoppeling maken.

Op de plaats waar je de locatie van het item moet opgeven, typ of plak je %windir%\explorer.exe ms-settings:bluetooth. Klik op Volgende om de snelkoppeling een naam te geven, bijvoorbeeld Bluetooth. Bevestig met een klik op Voltooien. Hierdoor staat de snelkoppeling op het bureaublad. Om die koppeling snel beschikbaar te maken, kun je nog met rechts op deze snelkoppeling klikken en dan Aan start vastmaken kiezen.

Je kunt een snelkoppeling maken om snel naar de bluetooth-instellingen te schakelen.

Watch on YouTube