Android programozás #6 | Szenzorok

Három főbb érzékelőt támogat az android platform:

  1. Mozgásérzékelők
  2. Környezeti érzékelők
  3. Pozíció érzékelők

Néhány érzékelő hardver alapú és néhány szoftver alapú. Bármilyen is legyen az érzékelő, az android lehetővé teszi számunkra, hogy nyers adatokat nyerjünk az érzékelőkből és ezeket az alkalmazás használja. Erre az android biztosít számunkra néhány osztályt.

Az android SensorManager és Sensor osztályokat biztosít a számunkra, ami által szenzorokat használhatunk az alkalmazásunkban. Annak érdekében, hogy használhassuk a szenzorokat, az első dolog, amit meg kell, hogy tegyünk, hogy példányosítunk egy objektumot a SensorManager osztályból. Íme egy példa:

SensorManager sMgr;
sMgr = (SensorManager)this.getSystemService(SENSOR_SERVICE);

A következő lépés, hogy példányosítunk egy objektumot a Sensor osztályból a SensorManager osztály getDefaultSensor() metódusának meghívásával. Azaz:

Sensor light;
light = sMgr.getDefaultSensor(Sensor.TYPE_LIGHT);

Amint a szenzor deklarálva van, “nyilván kell tartani” a listener-t és felülírni a két metódust, ami a onAccuracyChanged és az onSensorChanged. A szintaxis a következő:

sMgr.registerListener(this, light,SensorManager.SENSOR_DELAY_NORMAL);
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

public void onSensorChanged(SensorEvent event) {
}

 

A szenzorokról még sok mindent lehet “tárgyalni”, ezt majd a későbbiekben folytatom.

Android programozás #5 | Resource-ok kezelése

Sok más elem van még, amiket egy jó android alkalmazás felépítéséhez használunk. Eltekintve az alkalmazás írásától, figyelnünk kell számos egyéberő forrásra, mint pl. a statikus tartalom, amit a kód használ, például a bittérképek, a színek, az elrendezés, az animációs utasítások, és így tovább. Ezek a források mindig elkülönülve zajlanak, különböző alkönyvtárakban a projekt res/ könyvtárában.

Az alábbi leírás elmagyarázza, hogyan tervezzünk meg az alkalmazásunk erőforrásait, hogyan adjuk meg az alternatív erőforrásokat és hogyan érhetjük el őket az alkalmazáson belül.

Erőforrások megtervezése Android Studio-ban

MyProject/
   app/
      manifest/
         AndroidManifest.xml
   java/
      MyActivity.java  
      res/
         drawable/  
            icon.png  
         layout/  
            activity_main.xml
            info.xml
         values/  
            strings.xml

 

Könyvtár és erőforrás típusok

anim/

XML fájlok, amik meghatározzák az animációk tulajdonságait. A res/anim/ könyvtárba mentődnek el és a R.anim osztályból érhetőek el.

color/

XML fájlok, amik meghatározzák a színek egy statikus listáját. A res/color/ könyvtárba mentődnek el és a R.color osztályból érhetőek el.

drawable/

Képfájlok, mint pl. .png, .jpg, .gif vagy XML fájlok, amik összeállnak bittérképekké, utasítás listákká, formákká, rajzolható animációkká. A res/drawable/ könyvtárba mentődnek el és a R.drawable osztályból érhetőek el.

layout/

XML fájlok, amik meghatározzák a felhasználói felület kinézetét. A res/layout/ könyvtárba mentődnek el és a R.layout osztályból érhetőek el.

menu/

XML fájlok, amik meghatározzák az alkalmazás menüjeit, mint pl. egy Beállítások menü. A res/menü/ könyvtárba mentődnek el és a R.menu osztályból érhetőek el.

raw/

Tetszőleges fájlok, amik nyers formában mentődnek el. Meg kell őket hívni a Resources.openRawResource() metódusban az erőforrás-azonosítóval, amit a R.raw.filename-mel tudjuk megnyitni.

values/

XML fájlok, amelyek magukba foglalják az egyszerű értékeket, úgymint a sztringeket, az egész számokat és a színeket. Például, itt van néhány fájlnév egyezmény az erőforrásoknak, amiket létrehozhatsz ebben a könyvtárban –

  • arrays.xml a tömbök erőforrásainak, és az R.array osztályból érthetőek el.
  • integers.xml az egész számok erőforrásainak és az R.integer osztályból érthetőek el.
  • bools.xml a logikai vagy erőforrásainak és az R.boolean osztályból érthetőek el.
  • colors.xml a szín értékeknek, és az R.color osztályból érthetőek el.
  • dimens.xml a dimenzió értékeknek, és az R.dimen osztályból érthetőek el.
  • strings.xml a sztring értékeknek, és az R.string osztályból érthetőek el.
  • styles.xml a stílusoknak, és az R.style osztályból érthetőek el.

xml/

Tetszőleges XML fájlok, amiket futtatás közben olvashatunk a Resources.getXML() metódus meghívásával. Különböző konfigurációs fájlokat menthetsz el itt, amiket futtatás közben használtál.

 

Alternatív erőforrások

Az alkalmazásunknak biztosítania kell az alternatív erőforrásokat, hogy támogatni tudjunk egyedi eszközkonfigurációkat. Például, tartalmaznia kell az alternatív rajzolható erőforrásokat különböző képernyő felbontáshoz és tartalmaznia kell az alternatív sztring erőforrásokat különböző nyelvekhez. Futtatás közben az Android érzékeli az aktuális eszközkonfigurálást és betölti a megfelelő erőforrásokat az alkalmazásunk számára.

Ahhoz, hogy meghatározzuk a konfigurációt – speciális alternatívák egy erőforrás készlet számára – kövessük az alábbi lépéseket:

  • Hozzunk létre egy új könyvtárat a res/ könyvtárban, az alábbi formában: <erőforrás_név>-<konfiguráció_jelző>. Itt az erőforrás_név az erőforrások bármelyike lesz a fenti felsorolásból, mint pl. layout, drawable, stb. A jelző meg fog határozni egy egyedi konfigurációt, ami ezeket a forrásokat használja. Utána tudunk nézni a hivatalos dokumentációban, az erőforrások különböző típusainak a jelzőinek egy teljes listájában.
  • Mentsd el a megfelelő alternatív erőforrásokat ebbe az új könyvtárba. Az erőforrások fájlokat pontosan ugyanúgy kell elnevezni, mint az alapértelmezett erőforrás fájlok, ahogy azt az alábbi példa is mutatja. Például, bár a képfájl név ugyanaz lesz, de a nagy felbontású képernyő számára, a felbontása nagy lesz.

Az alábbiakban láthatunk egy példát, amely meghatározza a képeket egy alapértelmezett képernyő számára és meghatározza az alternatív képeket a nagy felbontású képernyő számára.

MyProject/
   app/
      manifest/
         AndroidManifest.xml
   java/
      MyActivity.java   
         res/
            drawable/  
               icon.png
               background.png
         drawable-hdpi/  
            icon.png
            background.png  
         layout/  
            activity_main.xml
            info.xml
         values/  
            strings.xml

 

Az alábbi példa meghatározza a kinézetet egy alapértelmezett nyelv számára és meghatározza az alternatív kinézetet az arab nyelv számára.

MyProject/
   app/
      manifest/
         AndroidManifest.xml
   java/
      MyActivity.java   
      res/
         drawable/  
            icon.png
            background.png
         drawable-hdpi/  
            icon.png
            background.png  
         layout/  
            activity_main.xml
            info.xml
         layout-ar/
            main.xml
         values/  
            strings.xml

 

 

Android programozás #4 | Clicker tutorial

Az első tutorial alapján egy olyan alkalmazást hozunk létre, ahol két gomb és egy számláló látszik. A Click gombra kattintva a számláló elkezd növekedni, míg a Reset gombra kattintva visszaáll nullára.

clicker

 

1. Ehhez nyissuk meg az AndroidStudio-t

2. Hozzunk létre egy új projektet File/New/New Project…

  • Az alkalmazás neve (Application Name) legyen Clicker (vagy amit jónak látunk). A Company Domain igazándiból mindegy, hogy mi, ebből lesz a package neve. Next.
  • Phone & tablet legyen kipipálva, hisz erre a két platformra akarunk elsősorban alkalmazást írni. Next.
  • Activity-t adunk az alkalmazásunkhoz. Az EmptyActivity-t választjuk. Ehhez hasonlít a BlankActivity, ami az EmptyActivity-nek egy bővített “verziója”, mivel a jobb alsó sarokban találhatunk egy plusz jelet, illetve a jobb felső sarokban a három pontot, ami a menü-re utal. Next.
  • Az Activity neve marad MainActivity. Finish.

Miután a Grade Build befejeződik, automatikusan az (res/layout/)activity_main.xml és a MainActivity.java (az Activity neve) nyílik meg.

3. Nyissuk meg az activity_main.xml-t. Design nézetben láthatjuk, hogy hogyan is néz ki az adott platformon az alkalmazásunk. Alapértelmezetten felül, a kék sávban az alkalmazásunk neve, és alatta egy TextView-ban a Hello World szöveg látszik. A Design nézet mellett létezik a Text nézet. A Text nézetben az xml nyelv segítségével alakíthatjuk az alkalmazásunk kinézetét, míg Design nézetben egyszerűbb módon, különböző ún. Widget-ek segítségével készíthetjük el az alkalmazás egy részét, amit a Palettáról (Palette) tudunk kiválasztani.

4. Két gombra (Button) lesz szükségünk (Click és Reset), illetve az alapértelmezett HelloWorld TextView-t használjuk fel számlálóként. Két gombot húzzunk be a felületünkre a palettáról. Az első gombra kattintva jobb oldalt megjelenik a Properties. Keressük meg a Text-et, és írjuk be, hogy Click. Ez fog látszódni a gombon. Ugyanezt megtehetjük az Text nézetben. A másik gombot (Reset) így csináljuk meg. Láthatjuk, hogy a 3 widget-nek több, különböző “tulajdonsága” van. Keressük meg azt a Button-t, aminek a neve még nem lett átírva, és írjuk át:

android:text="Reset"

A TextView-nál pedig a HelloWorld-öt írjuk át 0-ra. Menjünk vissza Design nézetbe, és a TextView Properties-nél keressük meg a TextSize-t, amit állítsunk 32dp-re, hogyan jobban látszódjon a számolás. Text nézetben, a TextView-nál a tutorial szerint átírjuk az id-t , de nálam nem volt id,így az alábbi sort illesztettem be:

android:id="@+id/textViewCount"

mivel a Click gomb és a TextView összetartozik, ezért a layout_below tulajdonságot átírjuk:

android:layout_below="@+id/textViewCount"

Az id pedig legyen:

android:id="@+id/buttonClick"

Összességében a Click gomb Text nézetben így néz ki:

<Button
    android:text="Click"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/textViewCount"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="48dp"
    android:id="@+id/buttonClick" />

A Reset gombnál kicsit másabb a helyzet:

android:text="Reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/buttonClick"
android:layout_alignLeft="@+id/buttonClick"
android:layout_alignStart="@+id/buttonClick"
android:layout_marginTop="32dp"
android:id="@+id/buttonReset"

Reset lesz a szöveg, ami megjelenik a gombon, és mivel a Reset gomb a Click gombbal tartozik össze, ezért az id kivételével a többi helyen a Click gombhoz “kapcsolódik”.

5. Nyissuk meg a MainActivity.java-t. Az Android Studio alapértelmezetten így hozza létre:

package nagy.anita.Clicker;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Ezt egészítsük ki az alábbi módon:

Az @Override elé írom az alábbiakat, amivel létrehozzuk az objektumainkat. Két darab Button típusú gombot, és egy TextView típusú szöveget, ami a számlálónk.

Button btnClick;
Button btnReset;

TextView txtCount;

A létrehozás során a Button pirosan “mutatkozik”. Ha rávisszük az egeret, azt írja, hogy cannot resolve symbol ‘Button’. Az alt+enter megnyomásával importálja a szükséges osztályt, amit megtehetünk manuálisan is, legfelülre begépeljük ezt:

import android.widget.Button;

A txtCount-nál hasonló hibával találkozunk, ekkor az android.widget.TextView osztály lesz importálva.

Az onCreate metódusunkba “kössük össze” az előbb létrehozott gombokat és a szöveget azokkal a gombokkal és szöveggel, amit az xml-ben hoztunk létre:

btnClick = (Button)findViewById(R.id.buttonClick);
btnReset = (Button)findViewById(R.id.buttonReset);

txtCount = (TextView)findViewById(R.id.textViewCount);

Írjuk meg, hogy mi történjen akkor, amikor rákattintunk a Click gombra (szintén az onCreate metóduson belül):

btnClick.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String countValue = txtCount.getText().toString();

        int  intCountValue = Integer.parseInt(countValue);
        intCountValue++;

        txtCount.setText(String.valueOf(intCountValue));
    }
});

A String countValue = txtCount.getText().toString(); sorban meghívjuk a számlálónkat, mint egy sztring típusú “objektumot”, amit a következő sorban átalakítunk integerré, majd ezt növeljük a következő sorban, végül ezt az értéket visszaadjuk a TextView-nak.

6. Mentsük el az alkalmazást, majd próbáljuk ki. Mivel nekem a futtatás során az Android Studio azt a hibát írta ki, hogy “Your CPU does not support NX”, ezért azt a megoldást találtam, hogy egy külső “meghajtón” próbálom ki az alkalmazást (amúgy is telefonra írom/írjuk elsősorban az alkalmazásokat, így jobb is, ha azon próbálgatom az alkalmazásokat). Ezt egy tutorial videó segítségével oldottam meg, amit itt lehet megnézni.

Természetesen a Reset gombunk még nem működik, mivel azzal még nem foglalkoztunk, de a Click gombot nyomkodva szépen növekszik a számlálónk egyesével.

7. A Reset gomb működéséhez írjunk még egy ClickOnListener-t:

btnReset.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        txtCount.setText(String.valueOf(0));
    }
});

Ez egy egyszerűbb Listener lesz, mivel itt csak annyi a dolgunk, hogy a számlálónkat 0-ra állítsuk.

8. Mentsük el ismét az alkalmazást és próbáljuk ki mind a két gombunkat.

 

Ez a tutorial egy kicsit átalakítva a későbbiekben jó lehet majd az alapanyagok mennyiségének beállításánál is.

Android programozás #3 | Alkalmazás felépítése

Egy Android alkalmazás egy vagy több alkalmazás komponensből épül fel:

  • Activity (a program egy “ablaka”)
  • Service (háttérben futó szolgáltatás)
  • Content Provider (adatok kezelése)
  • Broadcast Receiver (rendszerszintű eseményekre reagál)

Minden komponensnek különböző szerepe van az alkalmazáson belül. Bármelyik komponens önállóan aktiválódhat. Akár egy másik alkalmazás is aktiválhatja az egyes komponenseket.

Android alkalmazás komponensek.
Activity: egy-egy Activity leszármazott egy-egy képernyő a mobil eszköz kijelzőjén. Egyszerre mindig csak egy Activity látható, de egy alkalmazáshoz több képernyőkép tartozhat, amelyeket futás közben – események hatására – szabadon cserélhetünk. Minden programnak kell legyen egy belépési pontja, amely az az Activity leszármazott, amelyet először mutat meg a felhasználónak. Minden Activity az android.app.Activity osztályból származik le.
Service: sok alkalmazás igényli, hogy bezárt ablakkal is képes legyen futni a háttérben, ezt szolgáltatásként megteheti, egyszerűen kell egy Service osztályból leszármazott példány, így marad a programunknak olyan része, amely a felfüggesztett Activity esetén is fut (gondoljunk például egy média lejátszóra). Minden szolgáltatást addig futtat a platform, amíg azok be nem fejeződnek, s a futó alkalmazások képesek hozzákapcsolódni a szolgáltatásokhoz, így képesek vagyunk vezérelni a háttérben futó szolgáltatást. Az android.app.Service osztályból kell öröklődnie.
Content Provider: általában minden alkalmazás tárol adatokat két futás között, hiszen ha felfüggesztés helyett bezárnánk az alkalmazást, akkor elvesznének az addig összegyűjtött adatok. A Content provider (tartalom szolgáltató) komponens feladata egy megosztott adatforrás kezelése. A platformon lehetőségünk van állományokba vagy SQLite adatbázisba menteni adatokat, és ezt segíti a Content Provider, illetve lehetővé teszi, hogy két alkalmazás adatokat cseréljen egymással. A Content provider-en keresztül más alkalmazások hozzáférhetnek az adatokhoz, vagy akár módosíthatják is azokat pl.: CallLog alkalmazás, ami egy Content provider-t biztosít, és így elérhető a tartalom. Az android.content.ContentProvider osztályból származik le és kötelezően felül kell definiálni a szükséges API hívásokat.
Broadcast Receiver: a Broadcast receiver komponens a rendszer szintű eseményekre (broadcast) reagál. Például: kikapcsolt a képernyő, alacsony az akkumulátor töltöttsége, elkészült egy fotó, bejövő hívás, stb. Az alkalmazás is indíthat saját „broadcast”-ot, például ha jelezni akarja, hogy valamilyen művelettel végzett (pl. letöltődött a torrent). Nem rendelkeznek saját felülettel, inkább valamilyen figyelmeztetést írnak ki például a status bar-ra, vagy elindítanak egy másik komponenst (jeleznek például egy service-nek). Az android.content.BroadcastReceiver osztályból származik le; az esemény egy Intent (lásd. később) formájában érhető el.

Android programozás #2 | Android Studio

Android alkalmazás készítéséhez szükségünk van az Android Studio-ra, amiben írhatjuk az alkalmazásunkat. Ezt ingyenesen le lehet tölteni innen. Szükség lesz még hozzá a JDK-ra is. Érdemes először a JDK-t telepíteni, majd az Android Studio-t.

A telepítések után elindítva az Android Studio-t az alábbi hibával kerültem szembe:

Error:CreateProcess error=216, This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need a x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher.

Különböző fórumokon azt a megoldást találtam, hogy a JDK-t telepítsem újra, az 1.8-as verziót ajánlották, illetve az Android Studio-n belül kellett megadni a JDK könyvtár elhelyezkedését, amit a File/Project Structure/SDK Location -nél lehetett beállítani.

Miután ezt a problémát sikerült megoldani, egy másik hibakódot írt ki az Android Studio.

Íme:

Error:Unable to start the daemon process.
This problem might be caused by incorrect configuration of the daemon.
For example, an unrecognized jvm option is used.
Please refer to the user guide chapter on the daemon at http://gradle.org/docs/1.12/userguide/gradle_daemon.html

Ennek a hibának a kiküszöbölésére azt az egyszerű megoldást találtam, hogy nem mindegy, mikor indítom el az Android Studio-t. Nem tetszik neki, ha bármi mást nyitok meg előtte, pl. a firefox-ot, DE még azt sem szereti, ha a háttérben fut az utorrent, sőt még a skype-ot is be kell zárni, mielőtt elindítanám az Android Studio-t.

Az okára nem jöttem rá, hogy miért ilyen “macerás” az Android Studio elindítása, a lényeg, hogy ki lehet/ki tudtam küszöbölni.

Android programozás #1 | A kezdet

Bevásárlós alkalmazást fogok készíteni, amit Androidos rendszerrel rendelkező eszközökön lehet majd futtatni. Az alkalmazás segítségével tárolhatjuk otthoni készletünk tartalmát, hogy miből mennyi van otthon a kamrában és a hűtőben. Ha valamiből fogyasztottunk, akkor azt a készletünkből elvehetjük, így vásárláskor láthatjuk, hogy melyik termék/alapanyag van otthon kifogyóban. Ugyanígy felvihetjük 1-1 bevásárlás során, hogy miből mennyit vettünk. Termékek/alapanyagok hozzáadását/elvételét gyorsíthatjuk QR kód/vonalkód beolvasásával. Megjegyzéseket tehetünk a család többi tagjának részére, ha látunk valahol valami jó akciót.

API kutatás/tesztelés #2 (Twitter:Tweetinvi)

A következő szociális oldal, melynek tanulmányozására sort kerítettem a Twitter lett, azon belül is a Tweetinvi nevű API. Az API megszerezhető a https://github.com/linvi/tweetinvi címről, vagy a Visual Studióban, a Nuget csomagkezelőn keresztül az Install-Package TweetinviAPI parancs futtatásával. A dokumentációt, és alapokat a https://github.com/linvi/tweetinvi/wiki címen érhetjük el. Ezek segítségével valósítottam meg a kis kód részletet, amellyel felhasználói adatokat tudtam lekérdezni.

Continue reading