Zelf mobiele apps bouwen (deel 4)

Door: Gertjan Groen | 19 oktober 2021 12:36

How To

Zeker als je app al wat vordert, zul je die niet alleen op een virtueel toestel, maar ook op een echt toestel willen testen en gebruiken. We laten zien hoe je dat kunt doen in deel 4 van de workshop Zelf mobiele apps bouwen.

Klik hier om naar deel 3 te gaan

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-deel4.txt beschikbaar.

Om een Android-app op je eigen toestel te testen, zul je een verbinding met de pc moeten maken. Dat kan eventueel via wifi, maar in dit geval geven we de voorkeur aan een usb-verbinding. Het is hierbij in sommige gevallen nodig een speciale driver te installeren. Via deze link vind je een lijst met fabrikanten en een link naar deze drivers. Als je een Google-toestel hebt, kun je ook gewoon de SDK Manager gebruiken, die je opent via Tools / SDK Manager. Blader naar het tabblad SDK Tools, zet een vinkje bij Google USB Driver en kies Ok.

Heb je moeite om drivers voor jouw toestel te vinden, dan kun je ook de universele drivers van https://adb.clockworkmod.com installeren. Die werken voor vrijwel elk toestel. Waar deze drivers voor zorgen, is dat via Android Debug Bridge (ADB) kan worden gecommuniceerd met de smartphone. Zo kan bijvoorbeeld je app worden geïnstalleerd en wordt informatie ontvangen die nodig is voor het debuggen.

Op de website voor Android Studio kun je links naar drivers vinden.

Telefooninstellingen

Voordat je het toestel daadwerkelijk voor ontwikkeling kunt inzetten, is een aanpassing in de telefooninstellingen nodig. Open hiervoor de instellingen en blader naar Over de telefoon. Zoek naar Build-nummer en tik hier zeven keer op tot wordt aangegeven dat je ontwikkelaar bent. Ga dan één stapje terug en ga naar Systeem. Klap indien nodig Geavanceerd uit. Hier zie je Ontwikkelaarsopties tussen staan. Blader naar Stand-by en zet deze optie bij voorkeur aan. Het zorgt ervoor dat het scherm aan blijft tijdens het opladen en ook als het via usb met de pc is verbonden. Blader naar het kopje Foutopsporing en zet een vinkje bij USB-foutopsporing. Dat is nodig voor communicatie via ADB.

App starten op toestel

Sluit je toestel via een usb-kabel aan op de pc. Op je toestel verschijnt een venster genaamd USB-foutopsporing toestaan waarin je de toegang moet toestaan. Zet eerst een vinkje bij Altijd toestaan vanaf deze computer. Tik dan op Toestaan. Je hoeft dan voortaan geen toestemming meer te geven voor toegang vanaf deze pc.

We gaan terug naar Android Studio. Zoals we eerder voor virtuele toestellen deden, kun je via de werkbalk je fysieke toestel selecteren onder Running Devices of via het menu Run / Select Device (Alt+Shift+F11). Klik je op het groene icoontje (of Shift+F10), dan wordt de app gecompileerd, en op je eigen toestel geïnstalleerd en gestart. Vooral de eerste keer dan dat wat langer duren.

Starten op meerdere toestellen

Je ziet in het menu een optie Run on Multiple Devices. Daarmee kun je zoals verwacht de app op meerdere (fysieke of virtuele) toestellen tegelijkertijd starten. Vink in het venster de gewenste toestellen aan en klik op Run. Je kunt zoveel toestellen aansluiten als je handig vindt en de app op al die toestellen tegelijkertijd starten.

Een app kun je eventueel op meerdere toestellen tegelijkertijd starten.

Logcat gebruiken: Debuggen

Bij het ontwikkelen zul je vaak systeemberichten willen volgen of andere meldingen die voor het debuggen van je app van belang kunnen zijn. We laten zien hoe dat werkt bij Android.

Het debuggen, ofwel het opsporen van fouten, speelt een belangrijke rol bij het ontwikkelen. Hiervoor kun je in Android Studio het venster Logcat gebruiken. Onderaan zie je een optie om het venster te openen. Linksboven in dit venster kun je kiezen voor welk actieve apparaat meldingen moeten worden getoond. Iets naar rechts kies je vanaf welk niveau (zoals Verbose, Debug, Info of Error) je meldingen wilt zien. Hierbij is Verbose het laagste niveau, waarbij dus meldingen van elk niveau worden getoond. Je kunt via het zoekveld filteren op tekst of zelfs reguliere expressies (voor complexere zoekopdrachten) gebruiken dankzij de optie Regex.

Het onderdeel Logcat laat allerlei systeemmeldingen van je toestel zien.

Logcat automatisch weergeven

Wil je dat het Logcat-venster automatisch wordt getoond na het starten van de app, dan kun je de opties voor het starten van de app aanpassen via Run / Edit Configurations. Op het tabblad Miscellaneous vind je de optie voor het automatisch tonen (en eventueel leegmaken) van Logcat. Je kunt hier meer opties wijzigen. Op het tabblad General geef je achter Launch Options bijvoorbeeld aan dat een andere dan de standaard activity moet starten. Ook kun je zelf – met het plusteken – een configuratie maken. In de werkbalk kies je dan welke configuratie moet worden gebruikt in de plaats van de standaard configuratie app.

Je kunt speciale configuraties maken voor het starten van je app.

Loggen vanuit je app

In je apps zul je Logcat regelmatig gebruiken om bepaalde meldingen te geven. Hierbij gebruik je een van de volgende opdrachten:

- Log.e() voor een foutmelding (error);
- Log.w() voor een waarschuwing (warning);
- Log.i() voor een informatieve melding (information);
- Log.d() voor foutopsporing (debug);
- Log.v() voor aanvullende details (verbose).

Deze opdrachten vereisen twee teksten (strings) als parameter, namelijk een titel en een omschrijving. Voor bijvoorbeeld de informatieve melding dat onCreate() is aangeroepen kun je de onderstaande regel toevoegen in de app die we begonnen zijn in deel 3 onder setContentView():

Log.i("levenscyclus","onCreate aangeroepen!")

Nadat je deze regel toevoegt zal – afhankelijk van de instelling – automatisch of handmatig met Alt+Enter de bibliotheek daarvoor worden toegevoegd. Als je het gedeelte achter import uitvouwt via het plusteken, zie je dat via de onderstaande regel de bibliotheek wordt geïmporteerd:

import android.util.Log

Als je de app start, kun je Logcat in de gaten houden voor deze melding. Zorg dat het niveau Info of lager (Verbose, Debug) is geselecteerd om deze melding te kunnen zien. Gebruik eventueel het zoekveld om te filteren op levenscyclus. Aan de linkerkant in Logcat zie je een verticale knoppenbalk met extra opties. Je kunt hier bijvoorbeeld het logscherm leegmaken of instellen welke velden moeten worden getoond. Verder kun je met de optie Screen Capture een schermafbeelding maken van je toestel en met Screen Record een schermopname.

Handleiding voor Android Studio

Voor Android Studio kun je online hier een uitgebreide gebruikershandleiding vinden. Zo vind je bijvoorbeeld in het hoofdstuk Debug your app tips voor het opsporen van fouten, met onder Write and view logs aanwijzingen voor Logcat. Zo zijn er ook hoofdstukken over het schrijven, testen en publiceren van je app. Zoek je heel specifieke details over een bepaalde eigenschap van Android Studio, dan is dit een goede plek om te beginnen.

Dobbelsteen-app

We beginnen zo met het bouwen van een dobbelsteen-app, wat een goede demonstratie is voor de interactie tussen de gebruikersinterface en je code. We gebruiken daarvoor in de ontwikkelomgeving Android Studio de programmeertaal Kotlin: dit is veruit de populairste taal voor dit platform en sinds 2017 bovendien de officiële en aanbevolen taal. Het grootste voordeel van Kotlin ten opzichte van Java is dat je vaak minder regels code hoeft te schrijven. Het maakt je ook flexibeler naar de toekomst. Dankzij Kotlin Multiplatform kun je namelijk in één keer het fundament voor een Android- én iOS-app bouwen, omdat veel code gemeenschappelijk is.

In deel 5 van deze cursus (in het volgende nummer van PCM) gaan we de ontwikkelomgeving IntelliJ IDEA gebruiken voor ontwikkeling in Kotlin, dat sterk overeenkomt met Android Studio. En we duiken dan sowieso wat verder de diepte in met een introductie van de programmeertaal Kotlin

Maar nu is het tijd voor onze eerste eenvoudige, maar functionele app. We gaan een dobbelsteen-app maken. Via een klik op een button kun je een worp doen, waarna het resultaat op het scherm wordt getoond. We gebruiken Android Studio en starten een nieuw project via de optie Create New Project in de openingsdialoog. Je kunt ook de menuoptie File / New / New Project gebruiken. Kies als template een Empty Activity. We noemen de app Dobbelsteen, selecteren de programmeertaal Kotlin en kiezen bij Minimal SDK API-level 23. We beginnen met de gebruikersinterface. Open daarvoor in het Projectvenster het lay-outbestand activity_main.xml.

Begin weer met een nieuw project in Android Studio.

Lay-out converteren

Er zijn meer manieren om een lay-out op te bouwen. Standaard wordt tegenwoordig een zogenoemde ConstraintLayout gekozen, dat je ook ziet in het venster Component Tree en in het xml-bestand onder Code. Hiermee kun je flexibeler vrij complexe lay-outs maken. We gaan er later in de cursus mee aan de slag.

Voor onze dobbelsteen-app kiezen we een andere vorm: de LinearLayout. Daarbij worden componenten in feite gewoon achter elkaar gezet. Dat kan zowel horizontaal als verticaal. Goed om te weten is dat je nergens aan vastzit als je een app begint op basis van een template. Er wordt gewoon wat code vooraf ingevuld, maar je kunt alles naar voorkeur aanpassen. Zo kun je ook de standaard ConstraintLayout eenvoudig omzetten naar een LinearLayout: klik daarvoor in de Component Tree rechts op ConstraintLayout, kies Convert view, selecteer LinearLayout en kies Apply. Hiermee heb je de lay-out naar een LinearLayout omgezet.

De lay-out kun je in enkele stappen converteren naar een andere vorm.

Attributen voor LinearLayout

We gaan een paar attributen voor de LinearLayout aanpassen. Klik daarvoor in de Component Tree op LinearLayout en open Attributes. Blader naar Orientation en verander deze naar vertical. Hiermee zorg je dat componenten verticaal en niet horizontaal onder elkaar worden gezet. Bij layout_width kies je match_parent. Daarmee zorg je ervoor dat alle beschikbare ruimte wordt benut – in dit geval (omdat er geen onderliggend element is) de volledige schermbreedte. Bij layout_height selecteer je wrap_content. De hoogte wordt dan aangepast aan de totale hoogte van de componenten die erin zijn opgenomen, ofwel de content. Deze verandering zie je overigens ook meteen plaatsvinden in je scherm.

Klap vervolgens layout_gravity uit en zet een vinkje bij center_vertical, zodat de componenten binnen deze lay-out (gezamenlijk) verticaal worden gecentreerd. Op dit moment hebben we alleen een component TextView die je nu naar het midden van het scherm ziet verschuiven. Controleer eventueel onder Code hoe dat in het xml-bestand wordt weergegeven (zie afbeelding).

Het eindresultaat van de code voor onze LinearLayout met verticale oriëntatie.

Tekst opmaken

We willen straks in de TextView-component de waarde weergeven die met de dobbelsteen is gegooid. Deze tekst willen we beter leesbaar maken. Selecteer de component (dat gaat omdat het zo klein is het makkelijkst via de Component Tree). Zorg dat het venster Attributes is geopend. Het attribuut id geven we de waarde text_worp. Via die naam kunnen we in onze code naar de component verwijzen. Het attribuut text veranderen we naar 0, de voorlopige dobbelsteenworp. Verander layout_width en layout_height naar 130dp. De component wordt dan groter, maar de tekst nog niet. Verander daarvoor ten slotte het attribuut autoSizeTextType naar uniform. Zo zorg je ervoor dat de tekst schaalt met de grootte van de component. Kies bij textAlignment voor center, zodat tekst binnen die ruimte wordt gecentreerd. Je kunt het vakje eventueel nog groter maken, wat ook in de weergave kan via de hoeken van de component.

De tekst voor de dobbelsteenworp wat netter opgemaakt.

Button toevoegen

We gaan nu een button toevoegen voor de werking van de dobbelsteen. Sleep daarvoor vanuit het venster Palette een button naar je lay-out en zet die op of onder de TextView-component, zodat deze eronder wordt gezet (dankzij de verticale oriëntatie). Laat de component niet te ver naar onderen los, want daar zit je buiten de lay-out. Klik dan op de button om attributen aan te kunnen passen.

Vul in het veld id de waarde button_werp in. Je krijgt na deze aanpassing een pop-upvenster te zien waarin wordt gevraagd of dit ook in de code moet worden doorgevoerd. Kies in zo’n geval Refactor, al is het hier (nog) niet van toepassing omdat we de waarde niet in code hebben gebruikt. Bij layout_width kies je wrap_content. Daarmee zorg je dat de breedte van de button wordt aangepast aan de tekst die erin staat. Die tekst verander je bij text in Werp dobbelsteen en je ziet dat de button meteen wat breder wordt. Zet voor zowel de TextView als Button bij het attribuut layout_gravity de optie center_horizontal aan. Dat kan in één keer als je eerst beide componenten selecteert (door Ctrl ingedrukt te houden, terwijl je op de linkermuisknop drukt) en daarna het attribuut verandert. Met deze optie zorg je ervoor dat componenten ook horizontaal mooi worden gecentreerd.

Onze lay-out met een tekst en button voor het werpen van de dobbelsteen.

Tekst als resource

De tekst van de button hebben we via het attribuut text opgegeven, maar het is gebruikelijk om deze en andere teksten voor je app (ook wel strings genoemd) in een apart bestand als zogenoemde resource op te nemen. Dat helpt je ook als je de app later bijvoorbeeld meertalig gaat maken. Er is een handig trucje om dat voor onze button te doen: open de gebruikersinterface (activity_main.xml), ga naar Code en klik bij de button op de tekst Werp dobbelsteen. Druk dan op Alt+Enter of klik op het lampje vóór deze regel en kies Extract string resource. Vul een naam in voor deze resource, bijvoorbeeld werpbutton_label, verifieer de tekst en klik op Ok. De aanpassing zie je terug in het bestand strings.xml. Open deze via je Projectvenster onder res/values. Je ziet nu de extra regel:

<string name="werpbutton_label">Werp dobbelsteen</string>

Wil je in het vervolg de tekst voor de button veranderen, dan kun je dat doen via het bestand strings.xml. Merk op dat in dit bestand ook de naam van de app te vinden is.

Teksten kun je beter als resource definiëren, waar een handig trucje voor is.

Test je lay-out

Je ziet dat het netjes afwerken van een LinearLayout toch tijd en aandacht vraagt. Het is slim om al tijdens het ontwerpen te controleren hoe het er bij andere schermgroottes of -oriëntaties uitziet. In de werkbalk boven je ontwerp kun je bijvoorbeeld een andere oriëntatie kiezen (portret of landschap) of de schermgrootte veranderen naar tablet, smartwatch of televisie, met de bijbehorende resolutie. Natuurlijk is het ook slim de app te starten in de emulator of op je eigen toestel. Hoewel de app nog niets doet, zie je wel al de gebruikersinterface.

Dobbelsteen programmeren

De gebruikersinterface is vooral grafisch erg eenvoudig, maar toereikend. Nu kunnen we de code schrijven om deze dobbelsteen werkend te krijgen! We hebben al een id toegekend aan zowel de button (button_werp) als het tekstveld (text_worp). We willen bepaalde code uitvoeren, zodra op de button is getikt. Eerst maken we de button beschikbaar als variabele. Open daarvoor MainActivity.kt en zet binnen onCreate() en onder setContentView() de volgende regel:

val buttonWerp: Button = findViewById(R.id.button_werp)

De benodigde bibliotheken worden weer automatisch geïmporteerd als je dat hebt ingesteld zoals besproken in deel 3 van deze cursus. We gaan nu een functie toevoegen die moet worden aangeroepen als er op de button wordt getikt. Zet deze binnen de MainActivity-class, maar onder het blok onCreate(). Voor nu laten we alleen een zogenoemde toast zien.

private fun werpDobbelsteen() {

Toast.makeText(this, "Je hebt een worp gedaan!", Toast.LENGTH_SHORT).show()

}

Een toast is een korte meldingsbalk. Er zijn drie parameters nodig: een zogenoemde Context (zie kader ‘Gebruik van Context binnen Android’), de tekst voor de melding en de periode waarin de melding zichtbaar blijft. Als laatste wordt de methode show() aangeroepen om de melding daadwerkelijk te laten zien.

Gebruik van Context binnen Android

De term Context kom je vaak tegen bij het ontwikkelen van Android-apps. De Context is een object waarin de huidige toestand van de activity (Activity Context genoemd) of – minder gangbaar – de app zelf (Application Context) wordt doorgegeven. In meerdere situaties moet je deze Context doorgeven. De aangeroepen functie kan het nodig hebben voor bijvoorbeeld toegang tot resources zoals lay-outs, strings of een database. Vaak wordt zoals in ons voorbeeld gewoon this gebruikt, wat in feite een referentie is naar de huidige activity.

Reageren op buttonklik

Om te zorgen dat de functie werpDobbelsteen() wordt aangeroepen zodra op de button wordt getikt, gebruiken we een methode die setOnClickListener() heet. Direct onder de declaratie van de button kun je deze methode toevoegen. Daarin noemen we ook de functie die bij een buttonklik moet worden aangeroepen:

buttonWerp.setOnClickListener { werpDobbelsteen() }

De hele MainActivity-class ziet er nu als volgt uit:

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

val buttonWerp: Button = findViewById(R.id.button_werp)

buttonWerp.setOnClickListener { werpDobbelsteen() }

}

private fun werpDobbelsteen() {

Toast.makeText(this, "Je hebt een worp gedaan!", Toast.LENGTH_SHORT).show()

}

}

Wat nog ontbreekt, is het genereren van een willekeurig getal (1 t/m 6) en het weergeven van de worp via de TextView. We maken daar eerst een referentie en laten met drie stippen zien dat de dobbelsteen wordt gegooid:

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

Vervolgens berekenen we een willekeurig getal van 1 t/m 6:

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

Ten slotte laten we het resultaat na een korte vertraging van 500 ms zien:

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

textWorp.text = dobbelsteenInt.toString();

}, 500)

Mogelijk wordt bij die laatste opdracht een keuze voor bibliotheken voorgelegd bij het (automatisch) importeren. De bibliotheken die je nodig hebt zijn android.os.Handler en android.os.Looper. Merk op dat we een integer hebben gegenereerd, waar we met de methode toString() een string van maken. Als je de app start, zul je zien dat bij elke tik op de button een nieuw willekeurig getal van 1 tot en met 6 wordt gegenereerd.

De definitieve versie van de eenvoudige, maar functionele dobbelsteen-app.

Recente bestanden en favorieten

Regelmatig zul je in meerdere bestanden kleine wijzigingen maken. Wil je terug naar een ander bestand? Dan is de sneltoets Ctrl+E erg handig. Daarmee open je een dialoogvenster met een overzicht van recent geopende bestanden. Ook heel praktisch is dat je bestanden als favoriet kunt markeren. Ga daarvoor naar Projectvenster, klik rechts op een bestand, kies Add to Favorites en selecteer de favorietenlijst of maak een nieuwe lijst. Vanuit het tabje Favorites kun je dan je favorieten openen.

0 Reactie(s) op: Zelf mobiele apps bouwen (deel 4)

  • Om te reageren moet je ingelogd zijn. Nog geen account? Registreer je dan en praat mee!
  • Er zijn nog geen reacties op dit artikel.

Wanneer je een reactie plaatst ga je akoord
met onze voorwaarden voor reacties.