Tag Archives: Android

OUYA, Android-konsoli

Kesälomalta paluu sorvin ääreen voi olla raskasta tai hauskaa… Kesälomalla hankittujen lelujen kanssa siitä onneksi saa hauskaa.

OUYA on Kickstarter-rahoituksen avulla luotu Android 4.1 -konsoli, jossa pyörivät kaikki normaalit Android-applikaatiot ilman suurempaa vaivaa. Konsoliin saa helposti ladattua SDK:n, jonka avulla ohjainta voi käyttää applikaatioissaan, mutta hiirellä ja näppäimistölläkin voi konsolia suoraan käyttää.

OUYA ei ole kovin tehokas konsoli eikä pelitarjonta ole vielä kovin laaja, tätä artikkelia kirjoitettaessa vain 384 peliä, mutta 99$ hintansa puolesta se on hyvä hankinta arcade pelien pelaamiseen olohuoneen sohvalla kavereiden kanssa.

Yrityksille OUYA tarjoaa halvan ja helpon ratkaisun tarjota interaktiivista sisältöä asiakasnäyttöihin. Valmiin applikaation kääntäminen ja asentaminen OUYA:lle on hyvin helppoa. Kehittäminen OUYA-konsolille ei ole yhtään sen vaikeampaa kuin mille tahansa muulle Android-laitteelle. Toki pieniä muutoksia joudutaan tekemään käyttöliittymään, jotta normaalisti kosketusnäytölle tarkoitettua applikaatiota voi käyttää peliohjaimella tai hiirellä. Kosketusnäytön korvaaminen hiirellä tai muulla ohjaimella johtaa helposti hyvin heikkoon käyttökokemukseen.

 

Asentaaksesi minkä tahansa applikaation OUYA:lle pitää sinun voida ladata applikaation .apk-tiedosto Internetistä. Mene OUYA:n kotinäkymän MAKE-valikkoon ja sisäänrakennetulla Internet-selaimella lataa APK-tiedosto. Tämän jälkeen palaa päävalikkoon, mene MANAGE-valikkoon, valitse SYSTEM ja siellä valitse ADVANCED. Tämä on jokaiselle Android-käyttäjälle tuttu asetukset-valikko Androidissa. Mene listassa alaspäin ja valitse Storage, jonka sisällä valitse Download. Täältä löydät juuri lataamasi APK-paketin ja asentaminen onnistuu ohjaimen O-napilla. Tämän jälkeen applikaatio löytyy samasta MAKE-valikosta kuin OUYA:n Internet-selain.

Samaan MAKE-valikkoon tulevat myös applikaatiot, jotka itse kehität ja asennat tietokoneen ADB:n avulla microUSB:n kautta.

Kehittäminen OUYA:lla

Kaikki OUYA-konsolit toimivat applikaatioiden kehittämiseen ilman maksuja tai muutoksia konsoliin. Jotta saat OUYA:n toimimaan normaalissa Android-kehitysympäristössäsi Macilla sinun täytyy vain lisätä kolmannen osapuolen USB Hex ID (0x2836) adb_usb.ini -tiedostoon .android-hakemistossa ja käynnistää ADB uudelleen. Tarkemmat ohjeet myös Windows-koneille on katsottavissa videona OUYA developers -sivustolta. Tämän jälkeen OUYA-konsolisi näkyy Eclipsessä ja ADB:ssä samalla tavalla kuin mikä tahansa muu Android-laite.

Seuraavaksi lataa OUYA Development kit (ODK) osoitteesta https://devs.ouya.tv/developers/odk, kopioi libs\-hakemistosta ouya-sdk.jar ja lisää se omaan Android-projektiisi. Tämän jälkeen ohjaimen komennot saa kiinni oman Activity -luokkasi onKeyDown() ja onGenericMotionEvent() -metodeista.

Tein tätä artikkelia varten yksinkertaisen applikaation, joka käyttää ODK:ta siirtelemään ImageView:tä FrameLayoutin sisällä.

Ota ohjain käyttöön Activity-luokan onCreate()-metodissa:

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	OuyaController.init(this);
}

Tunnista ohjaimen komennot:

@Override
public boolean onKeyDown(final int keyCode, KeyEvent event) {
	switch (keyCode) {
		case OuyaController.BUTTON_O:
			Log.d(TAG, "OUYA button O");
			break;
		case OuyaController.BUTTON_U:
			Log.d(TAG, "OUYA button U");
			break;
		case OuyaController.BUTTON_Y:
			Log.d(TAG, "OUYA button Y");
			break;
		case OuyaController.BUTTON_A:
			Log.d(TAG, "OUYA button A");
			break;
	}
	return true;
}
@Override
public boolean onGenericMotionEvent(final MotionEvent event) {
// Joystick
	if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
		float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
		float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
	}
	return true;
}

Tämän jälkeen voit tehdä ohjaimen antamilla komennoilla mitä itse haluat.
Koko koodin ja Eclipse projektin saat ladattua Githubista:
https://github.com/Androidkehitys/OUYA

Onnea pelikehitykseen! Palataan leikkimään telkkujen kanssa, kun Cromecast saapuu postissa.

Windows Phone -sovelluskehitys Androidin ja iPhonen rinnalla

Windows Phonen astuminen iOS:n ja Androidin rinnalle on saanut aikaan hieman hämmennystä joidenkin loppukäyttäjien ja sovellusten tilaajienkin mielissä. Siinä missä iOS (iPhone/iPad), Android ja jopa poistuva Symbian muistuttavat toisiaan yleisasultaan – kukin tietenkin erottautuen omilla pienillä eroavaisuuksillaan – Windows Phone on tietoisesti suuntautunut erilleen muista omalla Metro-suunnittelukielellään.

Ohje: maassa maan tavalla

Suunnitellessa uutta sovellusta mille tahansa alustalle, yleispätevänä ohjenuorana voitaneen antaa:

Kunkin tyyppisen mobiililaitteen käyttäjä haluaa systemaattisen käyttäjäkokemuksen ja käyttöjärjestelmälle tunnusomaisen sekä varsin yhdenmukaisen ulkoasun sovelluksille. Sovelluksen käyttöönotto on tällöin mahdollisimman luontevaa eikä vaadi syvällistä perehdytystä.

Tämä halu kumpuaa usein niin käyttäjien puolelta kuin myös käyttöjärjestelmien toimittajilta! Jotkut palvelujen kehittävät mieltävät ajattelevansa käyttäjän parasta pyrkimällä mahdollisimman yhdenmukaiseen käyttöliittymään laitteen käyttöjärjestelmästä riippumatta, mutta päätyvät tekemään käyttäjälle karhunpalveluksen. On poikkeustilanne, että ihmiset käyttävät samaa sovellusta eri käyttöjärjestelmillä, mutta varmaa, että he käyttävät sitä muiden saman käyttöjärjestelmän sovellusten lomassa.

Suunniteltaessa sovellusta usealle alustalle täysin samaa konseptia ei siis voi aina käyttää. Vaikka iPhone ja Android-sovellukset voivat muistuttaa toisiaan hämmentävän paljon, niillä on eronsa. WP:llä erot ovat muihin alustoihin verrattuna huomattavat.

Esimerkki

Alla käytännön vertailuesimerkki IMDB-sovelluksesta Applen iPhonelle ja Windows Phonelle.

Kuva 1. iPhone versio IMDB:n sovelluksesta.

Kuva 2. WP-versio IMDB-sovelluksesta.

Edellä esitetyt kuvat osoittavat selvästi, että iPhonen käyttäjät eivät pitäisi WP:n tyylisestä sovelluksesta puhelimessaan (mikäli se edes pääsisi Applen App Storeen), eivätkä vastaavasti Windows Phone -käyttäjät halua iPhone/Android-tyylistä sovellusta laitteilleen. Toisilleen vieraat esitystavat vaativat sovelluksen arkkitehdilta jo konseptin varhaisessa vaiheessa ydinidean hahmottamiskykyä ja näkemystä mitä kukin loppukäyttäjä haluaa siltä.

Microsoftin sivuilta löytyy (englanniksi) esimerkkejä erilaisista sovellustyypeistä Windows Phonella.

Päätelmä

Metro-tyyliohjeita noudattavat Windows Phone -sovellukset ovat niin toimintalogiikaltaan kuin ulkoasultaan selvästi erilaisia kuin iOS/Android-taustaiset sovellukset, vaikka tarjottava toiminnallisuus olisi sama.

Windows Phonen tarjoaman visuaalisesti rikkaan Panorama-näkymän avulla yritysten brändäys ja yleensäkin halutut teemat sovelluksissa voidaan saada muita alustoja vahvemmin esille (kuva 2). Tämä toki vaatii ylimääräisen graafisen aineiston luomista.

Vaikka Windows Phonella vältetään käyttöliittymäelementtien ylimääräisiä koristeita, kuten liukuvärejä, tekstuureita, varjostuksia ja kiiltoefektejä, sisältö pyritään vastaavasti tuomaan esiin niin, että lopputulos voi hyvin olla kauniimpi kuin muilla alustoilla.

 

 

Android-listat ja -adapterit

Näyttäessämme tietoa laitteen näytöllä joudumme usein turvautumaan listoihin. Emme usein tiedä kuinka monta riviä listassa on ja ne voivat ohjelman ajoaikana muuttua. Lähes jokaisessa ohjelmassa joutuu käyttämään jotain listaa, gridiä, galleriaa tai jotain muuta Androidin AdapterViewn toteuttavaa luokkaa.

Kaikki luokat jotka jatkavat AdapterViewtä on tarkoitettu näyttämään tietoa selkeissä riveissä (list), sarakkeissa (gallery) tai ruudussa (grid). AdapterView tarvitsee toimiakseen Adapterin, jolle on annettu tarvittavat objektit. Adapterin ei kuitenkaan tule itse hallinnoida objekteja vaan säilyttää vain viittaus niihin. Objektien säilyttäminen on tämän artikkelin asian ulkopuolella. Tässä artikkelissa käydään läpi kuinka Adapterit toimivat ja mikä on paras käytäntö niiden tekemisessä. Kiinnitämme myös huomiota listan ja sen myötä myös adapterin muistin kulutukseen, sillä esimerkiksi kuvien näyttäminen listassa aiheuttaa herkästi muistin ylittämisen ja ohjelman kaatumisen.

Kuinka tehdä Adapteri

Adapteria tehdessä suosittelen käyttämään yliluokkana ArrayAdapter<näytettävä objekti> luokkaa, joka toteuttaa jo lähes kaikki tarvitsemasi metodit. Sinun tarvitsee vain käsitellä, miten jokainen adapterille antamasi objekti näytetään getView()-metodissa.

Toimivan adapterin tekemiseen sinun täytyy jatkaa ArrayAdapteria ja toteuttaa tälle adapterille construktori ja haluamasi lainen getView()-metodi. Tässä esimerkki yksinkertaisesta adapterista, joka näyttää objektin tekstiä jokaisella adapteria käyttävän AdapterView:n alkiossa.

public class TestAdapter extends ArrayAdapter<YourObject> {
public TestAdapter(Context context, int textViewResourceId, List<YourObject> objects) {
    super(context, textViewResourceId, objects);
} 

// Luo AdapterViewn ilmentymän alkio tallennetusta objektista
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Adapteri uudelleen käyttää listassa olevia näkymiä uudelleen,
    // mutta listaa luotaessa nämä ovat null:ja ja tarvitsee alustaa.
    // Jos listan näkymä on jo asetettu ei sitä tarvitse enää uudelleen luoda
    // tehokkaassa adapterissa tämä luonti jätetään väliin, kun sitä ei tarvita.
    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.your_adapter_view_layout, null);
    }
    // tämän jäälkeen tarvitsee vain ottaa oikeasta adapterin alkiosta tarvittavat tiedot
    //  ja asettaa ne näkymään oikeille paikoille.
    YourObject item = getItem(position);
    // Huomaa että tekstikentän etsiminen vie turhaan tehoja ja aiheuttaa tarpeettomia viittauksia
    TextView text = (TextView)
    convertView.findViewById(R.id.adapter_item_textview);
    text.setText(YourObject.getText()); 

    return convertView; }
}

 

ViewHolder pattern: Lisää adapterin suorituskykyä

ViewHolder-malli tehostaa Adapterien käyttöä poistamalla tarpeen etsiä tarvittavat näkymä widgetit uudelleen getView()-metodissa. Mallin idea on luoda uudelleen käytettävä, Adapterin sisäinen, ViewHolder luokka, joka asetetaan uudelleenkäytettävän convertViewn sisälle tagiin. ViewHolder pitää sisällään referenssit oman convertViewnsä käytettyihin widgetteihin. Tämä poistaa widgettien etsimisen findViewById()-metodilla.

Myös jos tekstikentille tarvitsee lisätä kuuntelijoita riittää että ne tehdään vain kerran ViewHolderia luotaessa. Adapterisi toteuttaa ViewHolder mallin esimerkiksi näin:

// Luo AdapterViewn ilmentymän alkio tallennetusta objektista
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.your_adapter_view_layout, parent, false);

        // Luo ja lisää ViewHolder omalle näkymälleen tagiksi
        convertView.setTag(new ViewHolder(convertView));
    }
    ViewHolder viewHolder = (ViewHolder) convertView.getTag();
    YourObject item = getItem(position);

    viewHolder.text.setText(item.getText());
    viewHolder.image.setImageDrawable(item.getImageDrawable());

    return convertView;
}

private static class ViewHolder {
    final TextView text;
    final ImageView image;

    public ViewHolder(View convertView) {
        text = (TextView) convertView.findViewById(R.id.adapter_item_textview);
        image = (ImageView) convertView.findViewById(R.id.adapter_item_imageview);
    }
}

Monimutkaisemmissa riveissä ViewHoldering käyttäminen helpottaa ja tehostaa listan käyttämistä, koska vaikka oikean näkymän etsiminen convertView:stä kestää vain muutamia millisekuntteja, jos sen tekee esimerkiksi kymmenen kertaa voi lista nykiä selvästi kovassa käytössä.

Vinkki:

Listat ovat hyviä näyttämään tietoa, mutta vältä tiedon muokkauksen mahdollistamista listojen tai muiden AdapterView:n sisällä, esimerkiksi EditText widgeteillä. Tallentaminen ja oikean tiedon näyttäminen, kun listan näkymiä uudelleenkäytetään tulee todella vaikeaksi.

Rahaa applikaatioilla

Hauskojen ja hyödyllisten applikaatioiden tuottaminen Androidille ei tarvitse olla pyyteetöntä työtä. Applikaatioilla voi myös pieni kehittäjä tehdä rahaa. Androidilla on kolme yleistä talousmallia, joilla voit tienata applikaatiollasi.

1) Maksulliset applikaatiot

Applikaatiolle voi asettaa hinnan, kun sen laittaa markettiin myyntiin. Ongelma on että suurin osa applikaatioista on saatavilla myös ilmaiseksi. Asiakaskuntaa voi kasvattaa tarjoamalla esimerkiksi rajoitetun version applikaatiosta ilmaiseksi.

2) Applikaation sisäiset ostokset

Harvalla yksittäisellä koodaajalla on mahdollisuutta perustaa omaa kauppaa, mistä applikaation käyttäjä voi ostaa applikaatioon uutta sisältöä. Mikrotransaktiot toimivat hyvin peleissä kuten League of Legends. Android market tukee applikaation sisäistä maksamista ja lisää tietoa löytyy Android developer -sivustolta. Google ottaa 30% maksusta.

3) Mainokset applikaatiossa

Google tarjoaa valmiita paketteja mainosten lisäämiseen applikaation AdMob yrityksen kautta. Tässä artikkelissa käsitellään, kuinka mainoksia saa lisättyä omaan applikaatioonsa. Tässä artikkelissa neuvotaan, kuinka voit lisätä mainoksia omaan Android-applikaatioosi.

Mitä tarvitset?

Valmis applikaatio marketissa. Tarvitset AdMob:lle applikaation nimen ja linkin apk-pakettiin, mieluiten muodossa market://details?id=<app.package.name>

AdMob käyttäjätunnus:

Aloita täältä: Google Mobile Ads

Tässä kohtaa ainoa hämmennystä aiheuttava kohta yksityiselle Android-kehittäjälle voi olla Business name -kohta. Kaikki nämä tiedot voi vaihtaa koska tahansa. Jos et osaa täyttää jotain kohtaa ja se on pakollinen voit laittaa siihen väliaikaisen tiedon, tämä on myös AdMobin oma suositus. Verotiedot voi jättää tässä vaiheessa tyhjäksi, mutta muista ilmoittaa verottajalle AdMoblta saamasi tulot.

Tämän jälkeen voit lisätä applikaation “Sites & Apps” valikosta. Applikaation tietoja täyttäessäsi voit lisätä keksityt tiedot aluksi, jos haluat vain ladata ja testata SDK:n lisäämistä applikaatioosi. Voit myöhemmin päivittää nämä tiedot, kun olet lisännyt applikaatiosi markettiin.

Tuottojen maksu:

Mainoksista saamiesi tuottojen maksuun suositellaan PayPalia Yhdysvaltojen ulkopuolella. Tulot on mahdollista saada myös suoraan tilillesi, mutta pankkisi saattaa periä ylimääräisiä kuluja kansainvälisistä tilisiirroista. Huomaa myös että tulot maksetaan dollareina ja pankkisi voi periä ylimääräisiä kuluja euroiksi muuttamisesta.

AdMob maksaa jokaisesta kerrasta, kun applikaatiosi mainoksia painetaan. Maksu vaihtelee monesta asiasta riippuen, mutta on joitakin senttejä per painallus.

AdMob SDK applikaatioosi

Tarvittavan SDK:n löydät täältä: http://code.google.com/mobile/ads/docs/
Samasta linkistä löytää tarvittavat ohjeet mainosten lisäämiseen. Käymme tässä läpi pääkohdat.

1) Lisää SDK applikaatioosi

2) Lisää Manifestiin

2.1) Mainos aktiviteetti:

<activity android:name="com.google.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>

2.2)

Lisää permissionit:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

3) Lisää AdView layoutiisi

<com.google.ads.AdView android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adUnitId="YOUR_ADMOB_AD_UNIT_ID"
ads:adSize="BANNER"
ads:testDevices="TEST_EMULATOR,e78b974e6ab65648b52951e69edcb571"
ads:loadAdOnCreate="true"/>

TestDevices-atributtiin lisätään laitteen device ID ja tämän avulla saat testimainoksia laitteellesi. Poista tämä markettiin menevästä versiosta.

Tämä mainos ladataan heti, kun aktiviteettisi luodaan.
Voit itse ladata uuden sisällön mainosnäkymään:

AdView adView = (AdView) findViewById(R.id.adView);
adView.loadAd(new AdRequest());

4) ???

(Olet valmis, markkinoi applikaatiotasi sosiaalisessa mediassa)

5) Profit

Testaus Androidilla

Testaus yleisesti

Testaus, tuo ohjelmistokehityksen välttämätön paha. Testausta ei koskaan voi suorittaa täysin kattavasti, eikä ole ohjelmistoa, jossa ei olisi yhtään virhettä, paitsi ehkä Nasalla. Testauksella kuitenkin kasvatetaan merkittävästi ohjelmiston laatua ja viimeistään työelämässä tämä osa-alue on hyvä hallita.

Testaus, niin kuin kaikki muukin välttämätön epämukavuus on hyvä suorittaa kehityksen ohella, kuin sen jälkeen. On paljon helpompaa testata se mitä on juuri tehnyt, kuin kaikki mitä on tehty kehitysvaiheen aikana. Testaus kehityksen yhdeydessä  tekee koodista myös helpommin testattavaa. Jälkikäteen testattaessa voi hyvinkin olla mahdotonta tehdä testejä ilman koodin muuttamista.

Tässä artikkelissa käymme läpi Androidin testivälineitä ja -käytäntöjä.

Testit on hyvä suunnitella yksinkertaisiksi, toistettaviksi ja mahdollisimman vähän aikaa vieviksi. Hyvä ratkaisu tähän on testikoodi, jotka voi sitten vain ajaa tarvittaessa. Jokaista loppukoodin luokkaa kohden on hyvä tehdä oma testiluokkansa, joka testaa luokan julkiset metodit “riittävällä” testijoukolla. Hyvä nyrkkisääntö on, ettei testimetodeita ole koskaan liikaa, eikä yhden metodin kannata kaikkea tehdä.

Yksikkötestaus JUnitilla

Eclipseen tulee Android SDK:n mukana valmis wizard Android JUnit testiprojektien luomiseen. Yksityiskohtainen ohje JUnit testien tekemiseen ja ajamiseen löytyy developer.android.com sivustolta: Hello, Testing. Käymme muutaman yksityiskohdan läpi, oman testikoodin ja testisalkun avulla. Testisalkku on kokoelma testiluokkia, jotka suoritetaan peräkkäin. Jokaisen testiluokan voi suorittaa myös erikseen.

Android developers sivuston esimerkissä on huonosti mainittu, että testi projektiin pitää muistaa lisätä linkki testattavaan projektiin. Voit lisätä tämän projektin asetuksista (properties), “Java build path” valikosta, “projects”-välilehdestä. Tai testiprojektia luotaessa heti toisessa valikossa, joten muista painaa “next” äläkä “finnish”. Developer sivuston esimerkki on myös hiukan vanhemmasta Android SDK:sta, mutta sisältö on sama, vain luonti wizard on yksinkertaistunut.

- Testisalkku:

package fi.androidkehitys.esimerkkiapp.test; import junit.framework.Test; import junit.framework.TestSuite; public class AllTests { /** * Testisalkku, missä kaikki testiluokat lisätään. * @return Test */ public static Test suite() { TestSuite suite = new TestSuite(AllTests.class.getName()); suite.addTestSuite(EsimerkkiTesti.class); return suite; } }

Testisalkun voi ajaa suoraan “run as” ja “Android JUnit test”.

- Testiluokka:

package fi.androidkehitys.esimerkkiapp.test;

import fi.androidkehitys.applikaatio.MyActivity;
import java.util.List;
import android.test.ActivityInstrumentationTestCase2;

public class RSSTest extends ActivityInstrumentationTestCase2<MyActivity> {

    public RSSTest() {
        super("fi.androidkehitys.applikaatio", MyActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
    }

    /**
    * Testi metodi.
    *
    */
    public void testPotenssiMetodiOne() {
        assertTrue(“Metodi parametrillä 1 palautti väärän arvon”, potenssiMetodi(1) == 1);
    }
    public void testPotenssiMetodiTwo() {
        assertTrue(“Metodi parametrillä 2 palautti väärän arvon”, potenssiMetodi(2) == 4);
    }

    @Override
    protected void tearDown() throws Exception {
        getActivity().finish();
        super.tearDown();
    }
}

Testiluokan kaikki julkiset metodit ovat testi tapauksia ja suoritetaan testauksessa. Tässä testiluokassa ei tarvitsisi käyttää aktiviteettiä vaan tehdä yksinkertainen TestCase-luokan ilmentymä, mutta usein Android-metodit voivat tarvita kontekstin tai pääsyn resursseihin, joten yleisin yleisimmissä testitapauksissa tarvitset aktiviteetin parametrien käyttöön.

Aktiviteettien testaus on hiukan ongelmallisempaa yksikkötesteissä, koska view-komponenttejä ei saa käsitellä UI-säikeen ulkopuolella. Ratkaisu tähän on seuraavassa kappaleessa esiteltävä black box testaus ja Robotium framework.

Black box testaus Robotiumilla

Black box testauksella tarkoitetaan testausta, missä ei tarvitse pääsyä koodiin, vaan painellaan laatikon nappuloita. Robotiumille riittää päästä käsiksi applikaation .apk pakettiin. Black box testauksella pystyy tekemään monimutkaisiakin käyttötapaustestejä, mutta yksinkertaisuus on yleensä parempi tavoite sillä monimutkaiset testit alkavat kaatua pienilläkin muutoksilla.

Android tarjoaa rasitustestaukseen oman Monkey Runner:in, joka simuloi satunnaisia, mutta toistettavia painalluksia applikaation näyttöön. Tällä on kuitenkin mahdotonta testata jotain tiettyä tarkasti määriteltyä ominaisuutta applikaatiossa.

Robotium on voimakas työkalu Andoridin black box testaukseen. Sen käyttö ei vaadi kattavaa tietoa applikaation koodista ja käyttö on hyvin suoraviivaista. Robotiumilla voi ActivityInstrumentationTestCase2-luokkaan luoda Solo-olion, joka käyttää ja testaa käyttöliittymäelementtejä.

@Override
protected void setUp() throws Exception {
    super.setUp();
    solo = new Solo(getInstrumentation(), getActivity());
}

public void testLogin() {
    solo.clickOnButton("Kirjaudu sisään");
    assertTrue(solo.waitForText("Kirjautuminen epäonnistui", 1, 120000));
}

@Override
protected void tearDown() throws Exception {
    try {
        solo.finalize();
    } catch (Throwable e) {
        e.printStackTrace();
    }
    getActivity().finish();
    super.tearDown();
}

Kun Solo:lle on annettu Instrumentaatio ja aloitus-aktiviteetti voi navigoinnin applikaatiossa hoitaa kokonaan Solo:lla. Voit myös mennä toisiin aktiviteetteihin ilman ongelmia, jos testitapaus tätä vaatii.

Lisää JavaDoc Robotiumiin

Robotiumin käyttö helpottuu huomattavasti, kun lisäät JavaDocin Robotiumin lähdekoodiin. Sekä lähdekoodin, että JavaDocin voit ladata täältä (uusimmat tiedostot listan alapäässä). Eclipsessä testiprojektin asetuksissa (properties), Java Build Path, Libraries ja lisättyäsi Robotium Solo .jar tiedosto avaa se vasemmassa laidassa olevasta nuolesta, valitse Javadoc location ja paina edit. Tämän jälkeen valitse ulkoinen tiedosto ja etsi Robotium javadoc .jar ja lisää se archive pathiin. Nyt näet Robotiumin JavaDocit Eclipsessä.

Widgetit Androidissa

Widgetit näyttävät applikaation kaikkein oleellisimman tiedon nopeasti ja yksinkertaisesti työpöydällä. Widgettejä voi myös käyttää käynnistämään applikaatioita tai taustaprosesseja, kuten mediasoittimen.

Tässä artikkelissa toteutamme mahdollisimman yksinkertaisen widgetin, jotta saamme idean mitä kaikkea sen toimintaan saamiseen tarvitaan. Toteutamme widgetin, jossa on tekstikenttä ja nappula, nappulaa painamalla kasvatamme tekstikentässä olevaa numeroa yhdellä. Erityisesti kiinnitämme huomiota widgetin tilan päivittämiseen sekä manuaalisesti, että automaattisesti.

Esimerkki koodi: https://github.com/Androidkehitys/Androidkehitys-Widget

Widget layout

Widgetin layout toteutetaan samalla tavalla, kuin minkä tahansa aktiviteetin layout. On kuitenkin otettava huomioon, että widgetti luodaan RemoteViews-luokan ilmentymänä ja layoutissa voi näin ollen käyttää vain seuraavia layout-elementtejä:

Layoutit

Widgetit

AppWidgetProviderInfo Metadata

Tämä XML-tiedosto määrittää widgetille tarpeelliset tiedot, kuten korkeuden ja leveyden, päivitysvälin, esikatselun, layoutin, asetukset-aktiviteetin sekä widgetin koon muuttamisen vaaka ja/tai pystysuunnassa (Android 3.1).

Androidin kotinäkymä koostuu ruudukosta, jossa jokainen ruutu on kooltaan 74dp * 74dp. Widgetin tulee jättää 2dp:tä tilaa leveydessä ja korkeudessa, jotta vältetään mahdolliset virheet ajonaikaisessa koon määrityksessä kun dp:t muutetaan pikseleiksi. Käytä kaavaa (solujen määrä * 74) – 2 widgetin koon määrittelemiseen.

Päivitysväli määrittää ajan, jonka välein Android päivittää widgetin tiedot. Tämä päivitys herättää laitteen lepotilasta ja suorittaa onUpdate()-metodin AppWidgetProvider-luokassa. Ei myöskään ole takuita tapahtuuko päivitys ajallaan. Suositeltavampaa on toteuttaa widgetti niin että se päivittää vain silloin, kun sen on pakko, eikä useammin.

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth="146dp"
  android:minHeight="72dp"
  android:updatePeriodMillis="86400000"
  android:initialLayout="@layout/widget_layout"
  >
  </appwidget-provider>

Widget Manifestissä ja painallukseen reagointi

Manifestissä widget määritellään <receiver> elementin sisälle. Tässä elementissä määrittelet oman toteutuksesi AppWidgetProvider luokan ilmentymästä ja määrittelet ne Intent lähetykset (broadcast), jotka AppWidgetProvider hyväksyy. Nämä lähetykset suoritetaan onReceive() -metodissa.

<receiver android:name=".ExampleWidgetProvider">
  <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
  </intent-filter>
  <meta-data android:name="android.appwidget.provider"
   android:resource="@xml/appwidget_provider" />
</receiver>

AppWidgetProvideria voi myös kutsua PendingIntent:llä, kuten tässä esimerkissä napin painalluksiin reagointi on toteutettu:

Intent intent = new Intent(context, ExampleWidgetProvider.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.start_button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);

AppWidgetProvider

Kokonaisuudessaan omaan toteutukseesi AppWidgetProvideristä tarvitset vain onUpdate()- ja onReceive()-metodit. Voit myös tehdä tämän esimerkin mukaisesti paketin sisällä näkyvän staattisen metodin, joka päivittää widgetin grafiikat esimerkiksi konfiguraatioaktiviteetistä.

Ice Cream Sandwich julkaistu

Google ja Samsung pitivät tänä aamuna yhteisen julkistustilaisuuden jossa päivänvalon näkivät Googlen uusi Android 4.0 -käyttöjärjestelmä (Ice Cream Sandwich) sekä Samsungin kehittämä uusi Google Nexus puhelin.

Uuden Android-käyttöjärjestelmän suurimmat uudistukset keskittyvät lähinnä parempaan käyttökokemukseen. Seuraavassa lista tärkeimmistä käyttäjille näkyvistä uudistuksista:

Parannettu UI

Kuten aikaisempien versioiden kanssa, myös Ice Cream Sandwich tuo uuden käyttöliittymäteeman ja värimaailman. Lisäksi uusi kirjasintyyppi parantaa tekstin selkeyttä ja luettavuutta suurempia näyttöjen kanssa.

Aloitusnäytön kansiot

Android 4.0:ssa käyttäjät voivat ryhmitellä applikaatioita ja pikakuvakkeita näppärästi omiin kansioihin. Ryhmittely onnistuu helposti raahaamalla kuvakkeita toistensa päälle

Widgettien koot muutettavissa

Yksi, ainakin allekirjoittaneelle, mieluisa uudistus on mahdollisuus muuttaa widgettien kokoja. Kokomuutokset ovat toki olleet mahdollisia Android 3.x-laitteissa, mutta nyt myös muutkin kuin tablet-käyttäjät pystyvät käyttämään koko näyttöalan fiksusti hyödyksi.

Lukitusnäytön uudistus

Myös lukitusnäyttö on saanut uudistuksia, uudessa näytössä on mahdollista tehdä asioita ilman että lukitusta tarvitsee avata. Esimerkiksi käyttäjä voi avata Kamera-applikaation ja ottaa kuvia tai hallinnoida soitettavaa musiikkia.

Datakäytön kontrollointi

Ehkäpä suurin Ice Cream Sandwich:sta löytyvä innovaatio on datakäytön kontrollointityökalu. Käyttäjä voi liittymäsopimuksesta riippuen asettaa erilaisia muistutuksia ja rajoituksia datakäytölle jolloin käyttäjän pitäisi säästyä ikäviltä laskuyllätyksiltä.

Muita uudistuksia

Näiden uudistusten lisäksi Android 4.0:ssa on paljon muita uudistuksia. Mainitsemisen arvoisia asioita ovat uudistetut Kamera- ja Galleria-applikaatiot. Galleria-applikaatioon on lisätty myös muutamia kuvankäsittelyominaisuuksia. Näiden lisäksi kalenteria on parannettu, sekä käyttöjärjestelmästä löytyy nyt myös saneluominaisuus.

Kehittäjiä kiinnostavat uudistukset

Kehittäjien kannalta katsottuna Android 4.0:n tuoma suurin uudistus on että Android 3.0:ssa julkistetut uudet ominaisuudet kuten Action Bar, Fragment-luokka, parannettu tuki suurille näytöille ja HTTP Live Streaming ovat nyt käytettävissä sekä puhelimissa että tableteissa. Tämän lisäksi Ice Cream Sandwich tuo toki oman osuutensa uusien ominaisuuksien listaan:

Social API

Social API tarjoaa yhteisen rajapinnan käyttäjän tietojen ja sosiaalisen kanssakäymisen hallintaan. Social API:n avulla voidaan hallinnoida helposti käyttäjän kontakteja, profiilitietoja, status-päivityksiä ja valokuvia.

Calendar API

Uudistetun Kalenteri-applikaation ja Calendar API:n avulla käyttäjän kalenterin lukeminen ja uusien kalenterimerkintöjen lisääminen helpottuu.

Android Beam

Android Beam on NFC:en perustuva ominaisuus joka mahdollistaa tietojen helpon siirtämisen NFC-laitteiden välillä. Beamin avulla on mahdollista siirtää esimerkiksi kontaktitietoja, kuvia ja videoita sekä liittyä keskusteluun tai videopuheluun.

Multimediauudistukset

Android 4.0 tarjoaa uuden low-level tuen streamauksen hallintaan. Uudistus mahdollistaa paremman mediadatan hallinnan, esimerkiksi applikaatio voi itse hakea datan, purkaa kryptauksen ja sen jälkeen ohjata datan käyttöjärjestelmälle näytettäväksi.

Toinen mukava multimediaan liittyvä uudistus on audio remote control API, joka mahdollistaa musiikkisoittimien ohjauksen lukitusnäkymästä niin että käyttäjän voi hallinoida soitettavaa musiikkia avaamatta puhelimen lukitusta.

Näiden lisäksi Ice Cream Sandwich:iin on lisätty WebP ja VP8 tuki, sekä tuki Matroskalle, jossa sisältö on joka Vorbis- ja VP8-formaatissa.

UI-uudistukset

4.0:ssa on mukana uusi GridLayout-luokka, jolla on mahdollista luoda matalampia UI-hierarkioita, mikä puolestaan tarkoittaa nopeampaa käyttökokemusta. Toinen varsin mukava uudistus on että kaikkien Android 4.0 laitteiden tulee tukea kiihdytettyä 2D-piirtämistä, mikä myös parantaa käyttöliittymän piirtonopeutta ja parantaa käytön sulavuutta.

Näiden lisäksi Android 4.0:ssa on muutamia muita kehittäjille suunnattuja uudistuksia. Tärkeimpänä kredentiaalien tallennukseen luotu keychain API, johon voidaan tallentaa sertifikaatteja. Sekä VPN client API, jolla voidaan luoda salattuja yhteyksiä sekä prosessoida sekä laitteelle tulevia että lähteviä paketteja.

Ajatuksia julkistuksesta

Päälimmäinen ajatus julkistuksesta näin kehittäjänä kannalta katsottuna on pieni pettymys. Julkistus ei varsinaisesti sisältänyt mullistavia uudistuksia, lähinnä vain paljon pieniä korjauksia ja parannuksia. Nämä korjaukset ja parannukset ovat toki tervetulleita ja Android 4.0 jatkaa siinä mielessä samalla iteratiivisella linjalla kuin edelliset versiot. Eli kuten ennenkin, uudessa versiossa on korjattu vanhoista versioista löytyneitä vikoja ja niiden lisäksi on otettu mukaan vähän uutta.

Luultavasti suurin kehittäjille näkyvä uudistus on ADT:n (Android Development Tools) versio 14 ja siihen liittyvä Eclipse plugin. Nopean kokeilun perusteella suosittelen nopeaa päivittämistä, sillä kuten aina ennenkin, uusi versio en edeltäjäänsä huomattavasti parempi. Esimerkiksi uudessa versiossa LogCat-lokia voidaan filtteröidä applikaation nimen perusteella, jolloin pelailu prosessi id:ten kanssa jää pois.

Tarkempia tietoja Android 4.0:n uudistuksistä löytyy seuraavasta osoitteesta:
http://developer.android.com/sdk/android-4.0-highlights.html

Lista ADT 14:n uudistuksista löytyy osoitteista:
http://developer.android.com/sdk/tools-notes.html
ja
http://developer.android.com/sdk/eclipse-adt.html

Liikkuva 2D-grafiikka Androidilla

Ensimmäinen asia, mitä lähes jokainen aloitteleva ohjelmoija haluaa tehdä on oma peli. Tämän toteuttamiseen tarvitaan lähes välttämättä liikkuvien grafiikkojen piirtämistä. Tässä artikkelissa esitetään Androidin 2D-grafiikkojen piirtäminen kankaalle. Käymme myös läpi hiukan yksinkertaista säikeiden käyttöä ja säieturvallisuutta.

Androidille 2D-grafiikkojen piirtämiseen tarvitaan näkymä, jolle voi piirtää. Toteutamme tässä esimerkissä oman versiomme SurfaceView:stä, jolle piirtäminen tapahtuu käytännössä antamalla SurfaceView:lle kankaan onDraw()-metodissa.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    starList = new ArrayList<StarFallActivity.Star>();

    setContentView(new StarSurface(this));
}

class StarSurface extends SurfaceView implements SurfaceHolder.Callback {
    private GameThread gameThread;
    private GraphicThread graphicThread;

public StarSurface(Context context) {
    super(context);
    getHolder().addCallback(this);
    gameThread = new GameThread(this);
    graphicThread = new GraphicThread(getHolder(), this);
}

@Override
public void onDraw(Canvas canvas) {
    canvas.drawColor(Color.BLACK);
    synchronized (starList) {
        for(Star star : starList) {
            canvas.drawBitmap(star.getImage(), star.getX(), star.getY(), null);
        }
    }
}
...

Pidämme kirjaa rajoittamattomasta määrästä putoavia objekteja ja piirrämme ne kankaalle niiden sisällään pitämän sijainnin muukaan onDraw()-metodissa. Resursseissa olevan kuvan piirtäminen valmiista kuvaresurssista ei vaadi, kuin resurssin bittikartaksi muuttamisen ja X- ja Y-koordinaatit, mihin kuva pintanäkymässä tulee.

BitmapFactory.decodeResource(getResources(), R.drawable.icon);

Säikeet ja säieturvallisuus

Pidämme objektien liikuttamisen ja ruudunpäivityksen erillisissä säikeissä ja laitamme säikeet odottamaan, kun niitä ei tarvita. Säikeiden käytössä täytyy myös ottaa huomioon samanaikaisten operaatioiden turvallisuus. Koska pidämme liikuvat objektit yhdessä listassa täytyy lista asettaa synkronoiduksi, niin että siihen voi kohdistua vain yksi operaatio kerrallaan. Tämä täytyy tehdä jokaisessa paikassa, missä listaa käsitellään. Esimerkiksi pelin osia liikuttelevassa säikeessä:

synchronized (starList) {
    for (Iterator<Star> iterator = starList.iterator(); iterator.hasNext();) {
        Star star = iterator.next();
        star.move();
        if(star.getY() >= maxHeight) {
            iterator.remove();
        }
    }
}

Koska poistamme listasta putoavan tähden, jos se menee ruudun ulkopuolelle joudumme käyttämään iteraattoria, koska listasta poistaminen sen läpikäynnin aikana ei suoraan ole mahdollista.

Säikeissä tarvitsee pääasiassa vain metodit säikeen käynnissä olon asettamiseen ja run()-metodin oma toteutus, missä säikeen suoritusaikainen toiminta tapahtuu. Sijettä ei tule tappaa stop()-metodilla, sillä se voi jättää ohjelmistosi outoon tilaan. Tämän sijasta tulisi käyttää run()-metodissa while lausetta joka toistuu niin kauan, kuin säikeen sisäinen while ehto muuttuu epätodeksi ja run()-metodi pääsee suorittamaan loppuun. Säikeet joiden run()-metodi on päässyt suoriutumaan kokonaan tapetaan automaattisesti järjestelmän toimesta.

Jos et halua säikeesi vievän kaikkea prosessointitehoa aseta säie jokaisen while luupin lopuksi odottamaan jonkin aikaa. Piirtopintaa ei esimerkiksi kannata päivittää useampaa, kuin 60 kertaa sekunnissa ja tämäkin on yleensä liikaa. Säikeen voi myös pakottaa käynnistymään kutsumalla sille notify()-metodia.

Lataa esimerkki tästä.
Voit nyt tehdä esimerkiksi oman versiosi kitarasankarista ja pudottaa ruudun yläpäästä kuvia ja tarkastella osuuko käyttäjä niihin ennen, kuin ne putoavat ulos ruudulta.

Android Manifest

Android-manifest voi aluksi näyttää vaikealta ymmärtää, mutta ilman sitä ei koodia voi suorittaa. Tässä artikkelissa opetetaan Android-manifestin perus käyttö ja käydään läpi vaativammat käyttömahdollisuudet.

Manifestin rakenne Androidin dokumentaatiosta:

<?xml version="1.0" encoding="utf-8"?>

<manifest>
<uses-permission />
 <permission />
 <permission-tree />
 <permission-group />
 <instrumentation />
 <uses-sdk />
 <uses-configuration />
 <uses-feature />
 <supports-screens />
 <compatible-screens />
 <supports-gl-texture />
 <application>
 <activity>
 <intent-filter>
 <action />
 <category />
 <data />
 </intent-filter>
 <meta-data />
 </activity>
 <activity-alias>
 <intent-filter> . . . </intent-filter>
<meta-data />
 </activity-alias>
 <service>
 <intent-filter> . . . </intent-filter>
 <meta-data/>
 </service>
 <receiver>
 <intent-filter> . . . </intent-filter>
 <meta-data />
 </receiver>
 <provider>
 <grant-uri-permission />
 <meta-data />
 </provider>
 <uses-library />
 </application>

</manifest>

Nämä on osattava

Käytetään esimerkkinä SQL-tietokanta artikkelissa annettua koodia ja sen AndroidManifest.xml:ää.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="androidkehitys.fi.database"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name="DatabaseActivity" android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<activity android:name="EnterProductActivity"></activity>

</application>
</manifest>

Manifestissä ei elementtien sisään tule muuta, kuin toisia elementtejä. Arvon kirjottaminen elementin sisään ei toimi ja aiheuttaa virheen. Kaikki arvot mitä manifestissä annetaan tulee antaa elementtien parametreissä.

<manifest>-elementin attribuuteiksi tulee applikaation oletuspaketti, versionumeroja nimi. Elementin sisälle asetetaan minimi versio Android käyttöjärjestelmästä. Esimerkiksi tässä tapauksessa käytetty API versio 7 on “Android 2.1 – update 1”.

Manifest-elementin sisälle tulee myös <application>-elementti, jossa määritellään applikaation ikoni ja nimi.

Applikaatio elementtien sisällä tehdään jokaiselle aktiviteetille, jonka käyttäjä voi käynnistää, <activity>-elementti. Mikäli aktiviteetti on samassa paketissa, kuin manifest-elementissä määritelty oletuspaketti, riittää asettaa aktiviteetin nimeksi kyseisen luokan nimi. Mikäli aktiviteetti on jossain toisessa paketissa tulee sinun määrittää koko paketin polku.

Aktiviteetti-elementin sisälle voi määritellä <intent-filter>-elementin, joka määrää erityistilanteita, missä aktiviteetti käynnistetään. Ensimmäinen aktiviteetti, mikä applikaatiossasi käynnistetään täytyy määrittää oikeilla intent-filtereillä:

<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

Aktiviteetit, jotka eivät saa intenttejä applikaation ulkopuolelta ei tarvitse muuta, kuin nimetä manifestissä. Mikäli aktiviteettiä ei julisteta manifestissa sen käynnistäminen kaataa applikaation ja aiheuttaa ActivityNotFoundExceptionin;

Vaativampaa käyttöä varten hyvä tietää

Tässä käydään nopeasti läpi manifestin vaikeammin käytettäviä ja ymmärrettäviä ominaisuuksia. Näitä ei välttämättä tarvitse tietää yksinkertaisia applikaatioita tehtäessä, mutta ennemmin tai myöhemmin ne tulevat vastaan androidkehityksessä.

Tietyt osat Android-järjestelmästä vaativat käyttäjän lupaa ja ne täytyy määritellä manifestissä. Esimerkkinä tällaisista luvista on esimerkiksi internet-yhteyden käyttö:

<uses-permission android:name="android.permission.INTERNET" />

Intenttien vastaanottamisen määrittely manifestissä taas mahdollistaa reagoinnin tapahtumiin, vaikka applikaatio ei olisikaan käynnissä. Tällaisia tapauksia voi esimerkiksi olla NFC-sirujen lukeminen tai push-notificaatioiden vastaanottaminen.

<service>-elementti määrittelee applikaation tarjoaman palvelun muille laitteen applikaatioille. Näin määritellyt palvelut pysyvät päällä, vaikka käyttäjä vaihtaisi toiseen applikaatioon. Tällaisten palveluiden tulisi suorittaa yksi tehtävä ja sitten sulkea itsensä, sillä muuten näitä palveluita ei tapeta koskaan.

Jos haluat applikaatiosi reagoivan järjestelmän tai muiden applikaatioiden lähettämiin intentteihin, kuten push-notifikaatioihin on sinun määriteltävä <receiver>-elementti ja sen sisältö manifestissä applikaatio-elementin sisällä.

<provider>-elementin sisällä määritellään applikaation tarjoama sisältö. ContentProvider tarjoaa pääsyn applikaation hallinoimaan tietoon, myös muista applikaatioista.

Manifestin vaativampaan käyttöön palataan, kun sitä tarvitaan käytännön esimerkeissä.

Nine-patch Androidissa

Graafinen käyttöliittymä vaatii paljon kuvaresursseja, ja mikäli on tarkoitus tukea erilaisia Android-laitteita, joudutaan tekemään samoista kuvista eriresoluutioiset versiot. Työ vähenee huomattavasti, jos kuvat venyvät sopivaan kokoon.

Nine-patch tarjoaa mahdollisuuden venyttää kuvia järkevästi, eli se venyttää vain määriteltyjä osia kuvasta. Muu osa kuvasta pysyy sellaisena, kuin se on kuvassa, eikä veny. Venyviä alueita voi kuvassa olla useita ja niiden kokojen suhteet pysyvät aina samoina.

Nine-patch-kuvaan on myös mahdollista määritellä alue, johon sisältö tulee. Tämä on erityisen käytännöllistä tehtäessä grafiikoita säiliöihin, kuten nappeihin. Kun napin kuvasta tekee pienen ja asettaa sen kasvamaan sisällön mukaan ja kun sisältö on määritelty napin keskelle, grafiikka tulee automaattisesti oikean kokoiseksi.

Kuinka tehdä 9-patch kuvia

Nine-patch kuvat ovat normaaleja png-kuvia, joissa on yhden kuvapisteen paksuinen reuna joka on joko täysin läpinäkyvä tai valkoinen. Tälle reunalle piirretään yhden kuvapisteen levyistä mustaa viivaa ja kahden eri sivuilla olevan viivan määrittämä leikkaava alue rajaa venyvän ja sisällön täyttävän alueen. Android laitteella nämä kuvat on talletettava muotoon “.9.png”, jotta Android tietää kuvien olevan nine-patchejä.

Vasemmalla ja ylhäällä olevat mustat viivat rajaavat venyvän alueen. Oikealla ja alhaalla olevat viivat taas rajaavat kuvan sisällön alueen.

Kuvat voi tehdä millä tahansa kuvankäsittelyohjelmalla, mutta helpoin tapa on käyttää Android SDK:n mukana tulevaa työkalua “draw9patch”. Ohjelma löytyy “tools” kansiosta.

Ohjelma lisää kuvaan yhden kuvapisteen kokoiset reunat ja antaa muokata kuvaa vain näiden reunojen alueelta. Ohjelma myös näyttää oikeassa laidassa miltä kuva näyttää eri tavoilla venytettynä.

Avattuasi ohjelman voit raahata haluamasi kuvan ohjelmaan. Tämän jälkeen näet kuvan venytyksen tuloksen oikealla ja kuvan muokattavana vasemmalla. Kuvassa kannattaa valita tasaisia – usein vain yhden pikselin mittaisia – alueita venyväksi, koska tällöin kuvan väritys ei muutu. On myös tapauksia, missä on järkevää venyttää väritystä niin että isommilla ko’oilla väritys muuttuu tasaisesti.

Voit asettaa kuvassa editorissa venyvän alueen näkyväksi “show patches” valinnalla. Venyvät alueet ovat violetit alueet, jossa vihreät viivat kohtaavat. Samalla tavalla saat sisällön alueen näkyviin “show content” valinnalla.

Huomaa miten kuvassa olevat yksityiskohdat pysyvät tarkkoina, vaikka muu kuva venyy täyttämään koko näytön.

Viime viikon animaatioartikkelissa on käytetty tässä esimerkkinä olevaa nine-patch kuvaa. Nine-patch kuvien käyttö onnistuu applikaatiossa täysin samalla tavalla kuin normaalien kuvien. Android itse hoitaa kuvan koon ja sisällön asettelun.

Esimerkkikuva ilman nine-patchiä.

Esimerkkikuva nine-patchin jälkeen.