Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor oktatási segédanyag, mely a
Társadalmi Megújulás Operatív Program Határon átnyúló együttműködés a szakképzés és a felnőttképzés területén c. pályázati felhívás keretében megvalósított Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
2013.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 1
Tartalomjegyzék 1. Bevezető ............................................................................... 2. Telefon kezelése .................................................................. 2.1 Hálózati információk lekérdezése ......................................... 2.2 Hívások és vészhívások ...................................................... 2.3 SMS fogadása ................................................................... 2.4 Hívások regisztrálása .........................................................
2 3 3 3 3 4
3.
Strukturált adatok kezelése.................................................. 5 3.2 Adatbázis szűrése, megjelenítés ListView-ban ......................11 3.3 Miért javasolt az SQLiteOpenHelper használata? ...................11
4.
Hálózati kommunikáció........................................................12 4.1 Példa Wifi hálózatok keresésére..........................................12 4.2 Példa http kapcsolatra.......................................................14 4.3 Példa WebView alkalmazására............................................17 4.4 Feladatok a hálózati kommunikáció témaköréből ..................18
5.
Helymeghatározás ..............................................................19 5.1 Wifi helymeghatározás ......................................................19 5.2 Helymeghatározási feladat .................................................19 5.3 Helymeghatározás a mobil cellainformációk alapján ..............25 5.4 Több helymeghatározó adatainak összevetése......................25 6. Multimédiás eszközök ..........................................................26 6.1 Példaprogram saját kamerahasználatra ...............................26 6.2 Bővítse az előző példaprogramot a következő funkciókkal:.....31 6.3 Példa hangok lejátszására..................................................31 6.4 Példa hangfelvételek készítésére és lejátszására...................33 6.5 Feladatok multimédiás eszközökhöz ....................................35 7.
Szolgáltatások ....................................................................36 7.1 Példa Started Service alkalmazására ...................................36 7.2 Példa IntentService alkalmazásásra ....................................39 7.3 Feladatok szolgáltatásokra.................................................41
8.
Összetett feladatok .............................................................42 8.1 Zenelejátszó alkalmazás ....................................................42 8.2 Készítsen alkalmazást, amely a felhasználó által megadott időszakonként elmenti az aktuális GPS koordinátákat az idővel együtt egy állományba! ..........................................................42 8.3 Készítsen alkalmazást, amely időjárási adatokat – időpont, hely, felhőzet, hőmérséklet, csapadék - tárol és dolgoz fel! .................42 8.4 Készítsen gyorshívó alkalmazást!........................................43 8.5 Tárcsázó, üzenetküldő és hívásnapló program ......................43 8.6 Összetett kamera alkalmazás .............................................43 8.7 Kincskereső játék .............................................................43 8.8 Fitness program ...............................................................44 8.9 Kedvenc helyek ................................................................44
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 2
1. Bevezető Üdvözlünk mindenkit az Android alapú szoftverfejlesztés haladóknak című jegyzet gyakorlati feladatsorában! Bár az elmélettel talán már sikerült megbirkóznia mindenkinek, most jött el az ideje, hogy élesben is kipróbáljuk tudásunkat. A feladatsor felépítése a jegyzet tematikáját követi, hogy azok is hasznát vegyék, akik csak egy konkrét fejezet kapcsán szeretnék leellenőrizni tudásukat. A feladatok között példaprogramokat is találnak a kedves érdeklődők, amik részletes útmutatással szolgálhatnak egy típusprobléma megoldásában. Ahol pedig ez hiányzik, ott a legtöbb esetben rövid útmutatással, emlékeztetővel szeretnénk orientálni a feladattal próbálkozókat. Reméljük, sikerül mindenki érdeklődését felkelteni, vagy új ötletekhez inspirációt adni a problémák megoldása közben. Ehhez mindenkinek sok sikert kívánnak a szerzők!
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 3
2.
Telefon kezelése
2.1 Hálózati információk lekérdezése Készíts programot, ami kiírja a készülékben lévő SIM kártya számát, a jelenlegi hálózati szolgáltató nevét és hogy milyen állapotban van a SIM kártya jelenleg! A szükséges információk: referenciát kell kérni a TelephonyManager osztályra, majd meghívni a következő metódusokat: · getLine1Number(): stringként visszaadja a készülékben lévő első SIM kártya számát · getNetworkOperatorName(): a hálózati szolgáltató neve szöveges formában. · getSimState(): a SIM kártya jelenlegi állapota. 2.2 Hívások és vészhívások Van-e különbség a használt intent-ek tekintetében aközött, hogy hívást, vagy vészhívást kívánunk indítani? Ha van, mi az? Készíts programot, ami bekéri a tárcsázandó számot, majd gombnyomásra felhívja azt! Ehhez lehetőleg több gombot már ne kelljen megnyomni! A használt Intent hívására példa: Intent hivoIntent = new Intent(Intent.ACTION_CALL); hivoIntent.setData(Uri.parse("tel:+36301234567")); try { startActivity(hivoIntent); } catch (ActivityNotFoundException e) { //TODO: nem találtunk tárcsázóprogramot } Ne felejtsük el a jogosultságigénylést sem! 2.3 SMS fogadása Készíts olyan alkalmazást, ami egy bejövő üzenet részleteit (küldő, dátum, üzenet) megjeleníti! A teszteléshez használd a DDMS-t, vagy a távoli kliens SMS küldő szolgáltatását!
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 4
A felhasználható osztály az SmsManager, az android.telephony csomagból. A megoldáshoz regisztrálj saját BroadcastReceiver osztályt! 2.4 Hívások regisztrálása Készíts alkalmazást, ami a háttérben futva egy fájlba menti a beérkező hívások idejét és a hívó fél számát! Itt is saját BroadcastReceiver osztály regisztrálása lehet a megoldás kulcsa. Ehhez az onReceive() metódust kell megvalósítani. Ne felejtsd el a jogosultságokat! A szükséges intent-filter az android.intent.action.PHONE_STATE. A hívó száma a TelephonyManager.EXTRA_INCOMING_NUMBER-ben található.
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 5
3. Strukturált adatok kezelése 3.1
Példa adatbázis-kezelésre
A következő program létrehoz egy kapcsolatkezelő adatbázist, amely nevek és telefonszámok tárolását teszi lehetővé. A létrehozandó adatbázistábla mezői: · · ·
_id: egyedi kulcs, numerikus nev: a kapcsolat neve, szöveges telefonszam: a kapcsolat telefonszáma, szöveges adat
Elsőként a Contact.java fájlban elkészítjük egy kapcsolat osztályát, konstruktorokkal és lekérdező/beállító metódusokkal. Contact.java package com.example.sqliteexample; public class Contact { //Egy kapcsolat privát adatai int _id; String nev; String telefonszam; // Üres konstruktor public Contact(){ } // Konstruktor alapadatokkal public Contact(int id, String nev, String telefonszam){ this._id = id; this.nev = nev; this.telefonszam = telefonszam; } // Konstruktor id nélkül public Contact(String nev, String telefonszam){ this.nev = nev; this.telefonszam = telefonszam; } // ID lekérdezése public int getID(){ return this._id; Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 6
} // ID beállítása public void setID(int id){ this._id = id; } // Név lekérdezése public String getNev(){ return this.nev; } // Név beállítása public void setNev(String nev){ this.nev = nev; } // Telefonszám lekérdezése public String getTelefonSzam(){ return this.telefonszam; } // Telefonszám beállítása public void setTelefonSzam(String telefonszam){ this.telefonszam = telefonszam; } } A következő osztály fogja az adatbázis-műveleteket létrehozás, módosítás, lekérdezés, törlés, stb. DatabaseHandler.java package com.example.sqliteexample; import java.util.ArrayList; import java.util.List; import import import import import
android.content.Context; android.content.ContentValues; android.database.Cursor; android.database.sqlite.SQLiteOpenHelper; android.database.sqlite.SQLiteDatabase;
public class DatabaseHandler extends SQLiteOpenHelper {
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
végezni:
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 7
// Aktuális verzió száma private static final int ADATBAZIS_VERZIO = 1; // Adatbázis neve private static "kapcsolatok.db";
final
String
ADATBAZIS_NEVE
=
// Tábla neve private static final String TABLA_NEVE = "kapcsolat"; // A tábla oszlopainak a neve private static final String OSZLOP_ID = "id"; private static final String OSZLOP_NEV = "nev"; private static final String OSZLOP_TELEFONSZAM "telefonszam";
=
public DatabaseHandler(Context context) { super(context, ADATBAZIS_NEVE, null, ADATBAZIS_VERZIO); } // Tábla létrehozása @Override public void onCreate(SQLiteDatabase adatbazis) { String TABLA_LETREHOZASA = "CREATE TABLE " + TABLA_NEVE + "(" + OSZLOP_ID + " INTEGER PRIMARY KEY," + OSZLOP_NEV + " TEXT," + OSZLOP_TELEFONSZAM + " TEXT" + ")"; adatbazis.execSQL(TABLA_LETREHOZASA); } // Adatbázis frissítése @Override public void onUpgrade(SQLiteDatabase adatbazis, int oldVersion, int newVersion) { // Legegyszerűbb eldobni a régi táblát adatbazis.execSQL("DROP TABLE IF EXISTS " + TABLA_NEVE);
}
// Majd létrehozni az újat onCreate(adatbazis);
// Új kapcsolat felvétele (beszúrás) void ujKapcsolat(Contact kapcsolat) { SQLiteDatabase adatbazis = this.getWritableDatabase(); ContentValues ertek = new ContentValues(); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 8
ertek.put(OSZLOP_NEV, kapcsolat.getNev()); ertek.put(OSZLOP_TELEFONSZAM, kapcsolat.getTelefonSzam());
}
// Sor beszúrása adatbazis.insert(TABLA_NEVE, null, ertek); adatbazis.close();
// Kapcsolat lekérdezése Contact getKapcsolat(int id) { SQLiteDatabase adatbazis = this.getReadableDatabase(); Cursor kurzor = adatbazis.query(TABLA_NEVE, new String[] { OSZLOP_ID, OSZLOP_NEV, OSZLOP_TELEFONSZAM }, OSZLOP_ID + "=?", new String[] { String.valueOf(id) }, null, null, null, null); if (kurzor != null) kurzor.moveToFirst();
}
Contact kapcsolat = new Contact(Integer.parseInt(kurzor.getString(0)), kurzor.getString(1), kurzor.getString(2)); // Visszatérés a kapcsolattal return kapcsolat;
// Minden kapcsolat listába gyűjtése public List
getKapcsolatok() { List kapcsolatLista = new ArrayList(); // Lekérdezés minden mezővel String selectQuery = "SELECT * FROM " + TABLA_NEVE; SQLiteDatabase adatbazis = this.getReadableDatabase(); Cursor kurzor = adatbazis.rawQuery(selectQuery, null); // Ciklusban bejárjuk az összes személyt if (kurzor.moveToFirst()) { do { Contact kapcsolat = new Contact(); kapcsolat.setID(Integer.parseInt(kurzor.getString(0))); kapcsolat.setNev(kurzor.getString(1)); kapcsolat.setTelefonSzam(kurzor.getString(2)); // Kapcsolat hozzáadása a listához kapcsolatLista.add(kapcsolat); } while (kurzor.moveToNext()); } Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 9
}
// A személyek listájával visszatérünk. return kapcsolatLista;
// Egy kapcsolat frissítése (update) public int kapcsolatFrissit(Contact kapcsolat) { SQLiteDatabase adatbazis = this.getWritableDatabase(); ContentValues ertek = new ContentValues(); ertek.put(OSZLOP_NEV, kapcsolat.getNev()); ertek.put(OSZLOP_TELEFONSZAM, kapcsolat.getTelefonSzam()); // Sor frissítése return adatbazis.update(TABLA_NEVE, ertek, OSZLOP_ID + " = ?", new String[] { String.valueOf(kapcsolat.getID()) }); } // A kapcsolatok számának lekérdezése public int kapcsolatokSzama() { String lekerdezes = "SELECT * FROM " + TABLA_NEVE; SQLiteDatabase adatbazis = this.getReadableDatabase(); Cursor kurzor = adatbazis.rawQuery(lekerdezes, null); int szam = kurzor.getCount(); kurzor.close(); // Visszatérés a darabszámmal return szam; }
});
// Egy kapcsolat törlése public void kapcsolatTorol(Contact kapcsolat) { SQLiteDatabase adatbazis = this.getWritableDatabase(); adatbazis.delete(TABLA_NEVE, OSZLOP_ID + " = ?", new String[] { String.valueOf(kapcsolat.getID()) }
adatbazis.close();
} A fentieket kihasználó példa létrehoz egy új adatbázist, feltölti rá több módon a kapcsolatokat, módosítást, törlést végez, majd kiírja őket és a kapcsolatok számát is. Példa a felhasználásra
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 10
//Adatbázis létrehozása DatabaseHandler adatbazis = new DatabaseHandler(this); //Adatok feltöltése Contact sanyi = new Contact("Balogh "+3642599400"); adatbazis.ujKapcsolat(sanyi); adatbazis.ujKapcsolat(new Contact("Kovacs "+36301234567")); adatbazis.ujKapcsolat(new Contact("Balogh "+36201212121")); adatbazis.ujKapcsolat(new Contact("Kovacs "+36704543234")); Log.d("DB", "Kapcsolatok feltöltése kész.");
Sándor", Janos", Geza", Kazmer",
//Módosítás Contact elsoSzemely = adatbazis.getKapcsolat(1); elsoSzemely.setTelefonSzam("+3642599900"); adatbazis.kapcsolatFrissit(elsoSzemely); //Törlés adatbazis.kapcsolatTorol(elsoSzemely); // Minden kapcsolat listába töltése és kiírása List kapcsolatok = adatbazis.getKapcsolatok(); for (Contact kapcsolat : kapcsolatok) { String szemely = "ID: "+kapcsolat.getID()+", Nev: " + kapcsolat.getNev() + ", TelefonSzam: " + kapcsolat.getTelefonSzam(); Log.d("DB", szemely); } // Rekordok száma String kapcsolatokSzama = "A jelenleg:" + adatbazis.kapcsolatokSzama(); Log.d("DB", kapcsolatokSzama);
kapcsolatok
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
száma
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 11
3.2 Adatbázis szűrése, megjelenítés ListView-ban Készítsünk programot, ami mobiltelefonok típusát és árát adatbázisban tárolja! Egy number típusú EditText-be tudjuk beírni azt az összeget, amit telefonra szánunk, erre válaszul a program listázza ki azokat a készülékeket egy ListView-ban, amelyek ennél nem drágábbak! 3.2 SQLite3 kérdések · · ·
Milyen adattípusokat támogat az SQLite3? Hogyan tárolunk dátum típust? Milyen külső eszközzel tudunk csatlakozni hozzá?
3.3 Miért javasolt az SQLiteOpenHelper használata? Készítsünk egy autók adatait (rendszám, típus) tároló egytáblás adatbázist, írjunk hozzá Java osztályt is! SQLiteOpenHelper segítségével készítsünk újabb verziót belőle, ahol az autók adatai bővül az átlagfogyasztással! Támogassuk az új változatra áttérést onUpdate() metódussal!
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 12
4.
Hálózati kommunikáció
4.1 Példa Wifi hálózatok keresésére Készítsünk egy olyan alkalmazást, amely megjeleníti az elérhető hálózatok SSID-jét, a jelerősséget pedig ikonokkal jelöljük. A főprogramunk a következőképpen néz ki: package hu.nyf.wifilista; import java.util.ArrayList; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class WifiListActivity extends ListActivity { private WifiManager man; private ArrayList<WifiElem> lista= new ArrayList<WifiElem>(); //A lista elemben tároljuk majd a megtalált hálózatokat private ListView listv; private WifiAdapter adapter=null; private BroadcastReceiver wifiRec = new BroadcastReceiver (){ //A hálózatokban bekövetkező változásokat tudjuk kezelni a receiver-rel @Override public void onReceive(Context arg0, Intent arg1) { for(ScanResult r: man.getScanResults()){ WifiElem elem = new WifiElem(r.SSID,r.level); } adapter = new WifiAdapter(getApplicationContext(), lista); WifiListActivity.this.setListAdapter(adapter); }
}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.registerReceiver(WifiRec, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); //Regisztráljuk a BroadcastReceiver-ünket man=(WifiManager) this.getSystemService(Context.WIFI_SERVICE); man.startScan(); //Elindítjuk a hálózatok keresését listv = this.getListView(); if(adapter!= null){ this.setListAdapter(adapter); } } protected void onStop(){ super.onStop(); this.unregisterReceiver(WifiRec); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 13
}
}
A listába szereplő WifiElem objektumok a következőképpen lettek definiálva: package hu.nyf.wifilista; public class WifiElem { private String SSID; private int level; public WifiElem(String s, int l) { SSID=s; level=l; } public String getSSID() { return SSID; } public void setSSID(String sSID) { SSID = sSID; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } } A lista megjelenítéséhez szükséges adapter a következőképpen néz ki: package hu.nyf.wifilista; import java.util.ArrayList; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class WifiAdapter extends BaseAdapter{ private final List<WifiElem> lista; public WifiAdapter(final Context ArrayList<WifiElem> l) { super(); this.lista = l; } public void addElem(WifiElem w){ lista.add(w); } Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
cont,
final
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 14
@Override public int getCount() { return lista.size(); } @Override public Object getItem(int arg0) { return lista.get(arg0); } @Override public long getItemId(int arg0) { return arg0; } @Override public View getView(int pos, View cv, ViewGroup szulo) { final WifiElem elem=lista.get(pos); LayoutInflater inf=(LayoutInflater) szulo.getContext().getSystemService(Context.LAYOUT_INFLATER_ SERVICE); View elemView=inf.inflate(R.layout.sor, null); TextView cimke_ssid=(TextView) elemView.findViewById(R.id.textView_ssid); ImageView ikon = (ImageView) elemView.findViewById(R.id.imageView_wifiikon); cimke_ssid.setText(elem.getSSID()); int erosseg=elem.getLevel(); if(erosseg>-60){ ikon.setImageResource(R.drawable.wifi4); }else if(erosseg>-70){ ikon.setImageResource(R.drawable.wifi3); }else if(erosseg>-80){ ikon.setImageResource(R.drawable.wifi2); }else if(erosseg>-90){ ikon.setImageResource(R.drawable.wifi1); }else { ikon.setImageResource(R.drawable.wifi0); } return elemView; } } 4.2 Példa http kapcsolatra Készítsünk olyan alkalmazást, amely képes szöveget és képet letölteni a http protokollon keresztül egy távoli szerverről. …
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 15
//Szöveg letöltése gombnyomásra indul gomb_szoveg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String url=beviteli_url.getText().toString(); new Adatletolto().execute(url); } }); //Kép letöltése gombnyomásra indul gomb_kep.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //String url=beviteli_url.getText().toString(); new Kepletolto().execute(url); } }); } //A szöveg letöltése aszinkron műveletként hajtódik végre private class Adatletolto extends AsyncTask<String, String>{
Void,
//Mit hajtson végre az aszinkron metódus @Override protected String doInBackground(String... arg0) { try{ return letolt(arg0[0]); }catch(Exception e){ letoltottszoveg.setText("Nem sikerült letöltés."+e.toString()); } return null; } //Mi történjen az aszinkron művelet befejezése után protected void onPostExecute(String res){ letoltottszoveg.setText(res); } //A tényleges letöltés itt történik private String letolt(String bejovourl) throws IOException{ InputStream be=null; HttpURLConnection httpcon=null;; try{ URL url=new URL(bejovourl); httpcon=(HttpURLConnection) url.openConnection(); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
a
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 16
}
}
httpcon.setConnectTimeout(1000); httpcon.setReadTimeout(1500); httpcon.setRequestMethod("GET"); httpcon.connect(); int meret=httpcon.getContentLength(); be=httpcon.getInputStream(); byte[] buffer = new byte[meret]; be.read(buffer); return new String(buffer); }catch(Exception e){ return "Hiba a letöltés során!"; } finally{ httpcon.disconnect(); be.close(); }
//A képletöltésért felelős aszinkron metódus private class Kepletolto extends AsyncTask<String, Void, Bitmap>{ @Override protected Bitmap doInBackground(String... params) { InputStream be=null; HttpURLConnection httpcon=null; try{ URL url=new URL(params[0]); httpcon=(HttpURLConnection) url.openConnection(); httpcon.connect(); be=httpcon.getInputStream(); Bitmap letoltottkep=BitmapFactory.decodeStream(be); return letoltottkep; }catch(Exception e){ Log.d("HIBA", „Hiba a letöltéskor!” +e.toString()); } finally{ httpcon.disconnect(); } return null; } protected void onPostExecute(Bitmap res){ kep.setImageBitmap(res); } } }
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 17
4.3 Példa WebView alkalmazására Készítsünk olyan alkalmazást, amely egy WebView elem segítségével megjeleníti a megadott URL címen található weboldalt. A letöltés folyamatát egy ProgressBar segítségével jelenítsük meg package hu.nyf.webviewnezet; import android.os.Bundle; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class WebViewActivity extends Activity { WebView bongeszo; Button gomb_megnyit; EditText cim; ProgressBar letoltes; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); letoltes=(ProgressBar) this.findViewById(R.id.progressBar_letoltes); letoltes.setMax(100); cim=(EditText) this.findViewById(R.id.editText_cim); cim.setText("http://karpatiazenekar.hu"); gomb_megnyit=(Button) this.findViewById(R.id.button_megnyit); gomb_megnyit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String link=cim.getText().toString(); bongeszo.loadUrl(link); } }); bongeszo=(WebView) this.findViewById(R.id.webView_bongeszo); bongeszo.setInitialScale(50); bongeszo.setWebViewClient(new WebViewClient(){ @Override public void onScaleChanged(WebView view, float oldScale, float newScale) { super.onScaleChanged(view, oldScale, newScale); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { bongeszo.loadUrl(url); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 18
return true;
}
} }); bongeszo.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress){ letoltes.setProgress(progress); } }); WebSettings ws=bongeszo.getSettings(); ws.setJavaScriptEnabled(true); ws.setBuiltInZoomControls(true);
} 4.4 Feladatok a hálózati kommunikáció témaköréből Készítsen alkalmazásokat, következő feladatok megoldására: 1. Kérdezze le, hogy milyen mobil hálózati rendelkezésünkre, és melyek ezek jellemzői.
elemek
állnak
2. Listázza ki a telefon által elérhető öt legerősebb jelerősséggel rendelkező Wifi hálózatot. A megoldásnál lehetőleg használja a ListView elemet. 3. Hozzon létre két eszköz között WifiDirect kapcsolatot. A kapcsolat létrehozása után küldjön át az egyik eszközről a másikra adatállományokat. 4. Hozzon létre http vagy https kapcsolatot egy távoli szerverrel. Töltsön le különböző típusú állományokat a szerverről. 5. Válasszon ki magának egy RSS szolgáltatást, amely XML-ben küldi az adatokat. Kérje le az XML állományt a távoli szerverről, majd pedig dolgozza fel, és jelenítse meg a különböző adatokat az alkalmazás. 6. Alkosson web böngészőt a WebView eszköz segítségével.
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 19
5.
Helymeghatározás
5.1 Wifi helymeghatározás Készítsünk programot, ami közelítő pontossággal Wifi-n keresztül meghatározza a helyzetünket! 5.2 Helymeghatározási feladat Készítsünk programot, ami akár Wifi, akár GPS segítségével képes gombnyomásra meghatározni a helyzetünket! Amennyiben nincs egyik sem bekapcsolva, jelezze azt, és ugorjon fel egy dialógusablak, amiből elérhető a beállítás! GPSKovetes.java package com.example.gpstest; import import import import import import import import import import import
android.app.AlertDialog; android.app.Service; android.content.Context; android.content.DialogInterface; android.content.Intent; android.location.Location; android.location.LocationListener; android.location.LocationManager; android.os.Bundle; android.os.IBinder; android.provider.Settings;
public class GPSKovetes LocationListener {
extends
Service
Location pozicio; double szelesseg; double hosszusag; private final Context kornyezet; boolean pozicioLekerdezheto = false; boolean isNetworkEnabled = false; boolean isGPSEnabled = false; protected LocationManager lm; public GPSKovetes(Context context) { this.kornyezet = context; initLocation(); }
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
implements
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 20
public void initLocation() { lm = (LocationManager) kornyezet.getSystemService(LOCATION_SERVICE); //Lekérdezzük, hogy GPS, vagy Wifi elérhető-e isNetworkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); isGPSEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); pozíciót.
//Ha
bármelyik
elérhető,
le
lehet
kérdezni
a
if (isGPSEnabled || isNetworkEnabled) { this.pozicioLekerdezheto = true; //Ha tudjuk, megnézzük Wifiről a pozíciót if (isNetworkEnabled) {
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,6000, 10, this); if (lm != null) { pozicio = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (pozicio != null) { szelesseg = pozicio.getLatitude(); hosszusag = pozicio.getLongitude(); } } } //Ha tudjuk, megnézzük GPS-ről a pozíciót if (isGPSEnabled) { if (pozicio == null) { lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10, this); if (lm != null) { pozicio lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (pozicio != null) { szelesseg pozicio.getLatitude(); hosszusag pozicio.getLongitude(); } } } } } return pozicio; } Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
6000, = = =
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 21
public double getSzelesseg(){ if(pozicio != null){ szelesseg = pozicio.getLatitude(); } return szelesseg; } public double getHosszusag(){ if(pozicio != null){ hosszusag = pozicio.getLongitude(); } return hosszusag; } public boolean pozicioLekerdezheto() { return this.pozicioLekerdezheto; } //Ha egyik sincs bekapcsolva, akkor egy dialógusablak ugorjon fel. public void beallitoAblak(){ AlertDialog.Builder felugroAblak = new AlertDialog.Builder(kornyezet); felugroAblak.setTitle("Helymeghatározás"); felugroAblak.setMessage("Nincs bekapcsolva GPS, vagy Wifi. Kapcsoljuk be?"); felugroAblak.setPositiveButton("Igen", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int which) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); kornyezet.startActivity(intent); } }); felugroAblak.setNegativeButton("Nem", DialogInterface.OnClickListener() { public void onClick(DialogInterface which) { dialog.cancel(); } }); }
felugroAblak.show();
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
new dialog,
int
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 22
@Override public void onLocationChanged(Location pozicio) { } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void Bundle extras) { }
onStatusChanged(String
provider,
int
status,
@Override public IBinder onBind(Intent i) { return null; } } MainActivity.java package com.example.gpstest; import import import import
android.os.Bundle; android.app.Activity; android.view.View; android.widget.TextView;
public class MainActivity extends Activity { GPSKovetes pozicio; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); vezerles(); } public void vezerles(){ TextView tv1 = (TextView)findViewById(R.id.textView1); pozicio = new GPSKovetes(this);
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 23
if (pozicio.pozicioLekerdezheto()) tv1.setText("A be van kapcsolva"); else { tv1.setText("Nincs bekapcsolva"); pozicio.beallitoAblak(); } }
GPS/Wifi
public void pozicio(View nezet) { if (pozicio.pozicioLekerdezheto()) { String poz = "Szélesség: " + pozicio.getSzelesseg() + ", hosszúság: " + pozicio.getHosszusag(); TextView tv2 = (TextView)findViewById(R.id.textView2); tv2.setText(poz); } }
}
ManifestAndroid bejegyzés: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> Activity_main.xml Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 24
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_centerHorizontal="true" android:onClick="pozicio" android:text="Aktuális pozíció" /> Futtatás képei:
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 25
5.3 Helymeghatározás a mobil cellainformációk alapján Készítsünk programot, ami a mobil cellainformációk lekérdezésével közelítő pontossággal meghatározza a helyzetünket! A megoldáshoz használhatjuk a TelephonyManager referenciáját, a következő hasznos függvényekkel: · · · · · · · · ·
osztály
homeMobileCountryCode: az eszköz saját hálózatának ország kódja (MCC) homeMobileNetworkCode: a saját hálózat azonosítója (MNC) radiotype: Európai hálózat esetében „gsm” carrier: a szolgáltató neve cellTowers: az elérhető cellák információi cellId: a cella egyedi azonosítója (CID) locationAreaCode: a használt hálózat területkódja (LAC) mobileCountryCode: a használt hálózat országkódja (MCC) mobileNetworkCode: a használt hálózat azonosítója (MNC)
5.4 Több helymeghatározó adatainak összevetése Készítsünk programot, ami több provider lekérdezésének eredményét összeveti egymással, azaz kiírja, hogy mekkora eltérés van a méréseik között a szélességi és a hosszúsági fokok tekintetében!
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 26
6.
Multimédiás eszközök
6.1 Példaprogram saját kamerahasználatra A jegyzetben tárgyalt saját kamerahasználatot megvalósító program teljes forráskódja. KameraElonezet.java package com.example.mycamera; import java.io.IOException; import import import import import
android.content.Context; android.hardware.Camera; android.util.Log; android.view.SurfaceHolder; android.view.SurfaceView;
public class KameraElonezet SurfaceHolder.Callback { private SurfaceHolder holder; private Camera kamera;
extends
SurfaceView
implements
public KameraElonezet(Context context, Camera camera) { super(context); kamera = camera; //Saját SurfaceHolder készítése, //Jelezzük azt, hogy nálunk vannak a callback-hez használt //függvények holder = getHolder(); holder.addCallback(this); //elavult beállítás, de Android 3.0-nál korábbi rendszereknél //szükséges holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } //Létrejött a Surface, mondjuk meg, hová rajzolja a kamera az //előnézeti képet public void surfaceCreated(SurfaceHolder holder) { try { kamera.setPreviewDisplay(holder); kamera.startPreview(); } catch (IOException e) { Log.d("KAM", "Hiba az előnézet beállításakor."); } } Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 27
//Mi a teendő az előnézet bezárásakor? public void surfaceDestroyed(SurfaceHolder holder) { //TODO: előnézet bezárásakori feladatok elkészítése } //Az előnézet változása public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (holder.getSurface() == null){ //Nincs is Surface, kilépünk a metódusból return; } //A változtatások előtt állítsuk le az előnézetet. try { kamera.stopPreview(); } catch (Exception e){ //Lehet, hogy nem létezik a preview? } //Az új beállításokkal újraindítjuk. try { kamera.setPreviewDisplay(holder); kamera.startPreview(); } catch (Exception e){ Log.d("KAM", "Sajnos nem sikerült újraindítani az előnézetet."); } } } MainActivity.java package com.example.mycamera; import import import import import import import import import import import
java.io.File; java.io.FileNotFoundException; java.io.FileOutputStream; java.io.IOException; java.text.SimpleDateFormat; java.util.Date; android.os.Bundle; android.os.Environment; android.app.Activity; android.content.Context; android.content.pm.PackageManager;
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 28
import import import import import import
android.hardware.Camera; android.hardware.Camera.PictureCallback; android.util.Log; android.view.View; android.widget.Button; android.widget.FrameLayout;
public class MainActivity extends Activity { private Camera kamera; private KameraElonezet elonezet; private PictureCallback kep = new PictureCallback() {
{
@Override public void onPictureTaken(byte[] data, Camera camera)
try { //A kép neve IMG_időpont.jpg formátumú lesz. String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File pictureFile; //Az sdcard Pictures mappájába szeretnénk elmenteni. File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECT ORY_PICTURES); pictureFile = new File(dir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); FileOutputStream kimenet = new FileOutputStream(pictureFile); kimenet.write(data); kimenet.close(); } catch (FileNotFoundException e) { Log.d("CAM", "A file nem található: " + e.getMessage()); } catch (IOException e) { Log.d("CAM", "Filehozzáférési hiba: " + e.getMessage()); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 29
//Foglaljuk le a kamerát kamera = kameraFoglalás(); //Készítsünk előnézetet elonezet = new KameraElonezet(this, kamera); FrameLayout frameElonezet = (FrameLayout) findViewById(R.id.kamera_elonezet); frameElonezet.addView(elonezet); //Adjunk hozzá egy felvevő gombot és egy Listenert Button captureButton = (Button) findViewById(R.id.felvevo_gomb); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { //Kattintásra rögzítse a képet kamera.takePicture(null, null, kep); } } ); } //Van-e kamera az eszközünkben? private boolean vanKamera(Context kornyezet) { if (kornyezet.getPackageManager().hasSystemFeature(PackageManager.F EATURE_CAMERA) ){ //Van szerencsére return true; } else { //Sajnos nem érzékeltünk kamerát return false; } } public static Camera kameraFoglalás(){ Camera k = null; try { //Kísérlet a kamerapéldány megszerzésére k = Camera.open(); } //Kivétel esetében nincs eszköz, vagy foglalt. catch (Exception e){ //TODO: jelezzük a sikertelenséget } Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 30
//Visszaadjuk a megszerzett kamerát, vagy null-t, ha // nem sikerült. return k; } //El ne felejtsük elengedni a kamerát! @Override protected void onPause() { super.onPause(); if (kamera != null){ kamera.release(); kamera = null; }; }; } activity_main.xml <Button android:id="@+id/felvevo_gomb" android:text="Felvétel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" />
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 31
AndroidManifest.xml bővítése android:screenOrientation="landscape">
6.2 Bővítse az előző példaprogramot a következő funkciókkal: · · ·
legyen választható több kamera esetében, hogy melyikkel kívánunk rögzíteni! jelezze az alkalmazás a kép elkészültét dialógussal, vagy toastüzenettel: írja ki a rögzített képfájl nevét! jelezze hanglejátszással az exponálás megtörténtét!
6.3 Példa hangok lejátszására Készítsünk olyan alkalmazást, amely az alapértelmezett csengőhangot és az értesítési hangot játssza le a különböző hangcsatornákon. A hangcsatornák kiválasztásához használjuk RadioButton elemeket. package hu.nyf.csengohang; import android.media.AudioManager; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class CsengohangActivity extends Activity { RadioButton radio_alarm; RadioButton radio_music; RadioButton radio_notif; RadioButton radio_ring; RadioButton radio_sys; Boolean lejatszas; Ringtone ring; Ringtone ring2; Uri csengo; Uri ertesito; int mod; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 32
setContentView(R.layout.activity_csengohang); radio_alarm =(RadioButton) this.findViewById(R.id.radio_alarm); radio_music =(RadioButton) this.findViewById(R.id.radio_music); radio_notif =(RadioButton) this.findViewById(R.id.radio_notif); radio_ring =(RadioButton) this.findViewById(R.id.radio_ring); radio_sys =(RadioButton) this.findViewById(R.id.radio_system); radio_alarm.setSelected(true); lejatszas=true; csengo = RingtoneManager.getDefaultUri( RingtoneManager.TYPE_RINGTONE); ertesito = RingtoneManager.getDefaultUri( RingtoneManager.TYPE_NOTIFICATION); ring = RingtoneManager.getRingtone( getApplicationContext(), csengo); ring2 = RingtoneManager.getRingtone( getApplicationContext(), ertesito); Button gomb_csengo = (Button) this.findViewById(R.id.button_csengohang); gomb_csengo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { csengohangLejatszo(mod); } }); Button gomb_ertesit = (Button) this.findViewById(R.id.button_ertesito); gomb_ertesit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ertesitoLejatszo(mod); } });
} private void csengohangLejatszo(int v){ ring.setStreamType(v); if(lejatszas){ ring.play(); }else{ ring.stop(); } lejatszas=!lejatszas; } private void ertesitoLejatszo(int v){
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 33
ring2.setStreamType(v); ring2.play();
} public void kivalasztas(View view){ boolean checked = ((RadioButton) view).isChecked(); switch (view.getId()){ case R.id.radio_alarm: if(checked){ mod=AudioManager.STREAM_ALARM; } break; case R.id.radio_music: if(checked){ mod=AudioManager.STREAM_MUSIC; } break; case R.id.radio_notif: if(checked){ mod=AudioManager.STREAM_NOTIFICATION; } break; case R.id.radio_ring: if(checked){ mod=AudioManager.STREAM_RING; } break; case R.id.radio_system: if(checked){ mod=AudioManager.STREAM_SYSTEM; } break; } Log.d("SAJAT", "Kivalasztva: "+mod); } } 6.4 Példa hangfelvételek készítésére és lejátszására Készítsünk olyan alkalmazást, amely gombnyomásra a telefon mikrofonján keresztül felvesz hangokat, azokat mp4-es formátumban tárolja a memóriakártyára, majd pedig gombnyomásra visszajátssza a felvételt. package hu.nyf.felvevo;
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 34
import java.io.File; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class FelvevoActivity extends Activity { Button gomb; Button gomb_lejatszo; MediaRecorder felvevo; boolean allapot=true; MediaPlayer lejatszo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_felvevo); gomb_lejatszo = (Button)this.findViewById(R.id.button_lejatszo); gomb_lejatszo.setEnabled(false); try{ felvevo = new MediaRecorder(); felvevo.setAudioSource(MediaRecorder.AudioSource.MIC); felvevo.setOutputFormat( MediaRecorder.OutputFormat.MPEG_4); final String eleresiut=Environment.getExternalStorageDirectory() .getAbsolutePath()+"/felvetel.mp4"; File allomany = new File(eleresiut); if(allomany.exists()){ allomany.delete(); } allomany.createNewFile(); felvevo.setOutputFile(eleresiut); felvevo.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); felvevo.prepare(); gomb = (Button) this.findViewById(R.id.button_felvetel); gomb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(allapot){ gomb.setText(R.string.leallitas); felvevo.start(); }else{ felvevo.stop(); gomb.setText(R.string.inditas); gomb.setEnabled(false); gomb_lejatszo.setEnabled(true); Toast t= Toast.makeText(getApplicationContext(), R.string.siker, Toast.LENGTH_LONG); t.show(); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 35
} allapot=!allapot;
}
} }); gomb_lejatszo.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { try{ lejatszo= new MediaPlayer(); lejatszo.setAudioStreamType( AudioManager.STREAM_MUSIC); lejatszo.setDataSource(eleresiut); lejatszo.prepare(); lejatszo.start(); }catch(IOException ex){ Log.d("HIBA", "Hiba a lejátszás során!"); } } }); }catch(IOException ex){ Log.d("HIBA", "Hiba lépett fel a fájlműveletek során!”); }
} 6.5 Feladatok multimédiás eszközökhöz 1. Készítsen olyan alkalmazást, amely egy megadott alkönyvtárban tárolt hang állományokat kilistázza, majd klikkelésre a megadott állományt lejátssza a telefonon. 2. Készítsen zenelejátszó programot. A program tartalmazzon play, stop, és pause lehetőségeket. 3. Fejlessze tovább az előző programot úgy, hogy csúszka elem segítségével lehetőség legyen az állományon belül bárhova pozícionálni a lejátszást. 4. Készítsen olyan programot, amely képes hangfelvétel készítésére. Az elkészült felvételt játsszuk vissza torzított formában.
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 36
7.
Szolgáltatások
7.1 Példa Started Service alkalmazására Készítsünk olyan alkalmazást, amely gombnyomásra elindít és leállít egy Started Service szolgáltatást. A szolgáltatás jelenítse meg a szolgáltatás indítása óta eltelt időt pp:mm formátumban. A szolgáltatás felépítése a következő: package hu.nyf.stopperszolgaltatas; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class StopperService extends Service{ public volatile boolean fut=false; //volatile módosító jelentése, hogy a szálakból módosítható lesz
változó
különböző
//A végrehajtandó részt külön szálban indítjuk el private class StopperSzal extends Thread{ int ido=0; @Override public void run() { while(fut){ try{ sleep(1000); ido++; //Az eltelt időt Broadcast segítségével juttatjuk el a hívó alkalmazáshoz Intent esemeny=new Intent(); esemeny.setAction("StopperService.VALTOZO_IDO"); esemeny.addCategory(Intent.CATEGORY_DEFAULT); esemeny.putExtra("StopperService.IDO", ido); sendBroadcast(esemeny); }catch(Exception ex){ Log.d("HIBA", "Hiba keletkezett az esemény küldésekor”); } } } } Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 37
//Mivel ez Started Service, ezért ennek a visszatérési értéke null kell, hogy legyen @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onDestroy() { fut=false; super.onDestroy(); }
metódusnak
//A Started Service indításakor ez hajtódik végre @Override public int onStartCommand(Intent intent, int flags, startId) { if(!fut){ fut=true; new StopperSzal().start(); } return super.onStartCommand(intent, flags, startId); } }
a
int
A hívó alkalmazás felépítse a következő: package hu.nyf.stopperszolgaltatas; import android.os.Bundle; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class StopperActivity extends Activity { Context kont; private BroadcastReceiver valaszReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context arg0, Intent arg1) { TextView szamlalo = (TextView) findViewById(R.id.textView_masodperc); String p=""; String mp=""; int masodpercek = arg1.getIntExtra("StopperService.IDO",-1); int perc=masodpercek/60; masodpercek=masodpercek-perc*60; Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 38
if(perc<10){ p="0"+perc; }else{ p=""+perc; } if(masodpercek<10){ mp="0"+masodpercek; }else{ mp=""+masodpercek; } szamlalo.setText(p+":"+mp);
} }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_stopper); kont=this.getApplicationContext(); Button gomb_indit = (Button) this.findViewById(R.id.button_indit); gomb_indit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent indulas = new Intent(kont , StopperService.class); startService(indulas); } }); Button gomb_leallit = (Button) this.findViewById(R.id.button_leallit); gomb_leallit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent leallitas = new Intent(kont , StopperService.class); stopService(leallitas); } }); //Feliratkozás a Broadcast esemény fogadására IntentFilter szuro= new IntentFilter("StopperService.VALTOZO_IDO"); szuro.addCategory(Intent.CATEGORY_DEFAULT); this.registerReceiver(valaszReceiver, szuro); } }
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 39
7.2 Példa IntentService alkalmazásásra Készítsünk olyan alkalmazást, amely az IntentService alkalmazásával letölt és megjelenít egy grafikus állományt egy távoli szerverről. Az IntentService szolgáltatás a következőképpen épül fel: package hu.nyf.letoltesintentservice; import java.io.IOException; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class LetoltesSzolgaltatas extends IntentService{ public LetoltesSzolgaltatas() { super("LetoltesSzolgaltatas"); } @Override //Itt kell megadni, hogy mit csináljon a szolgáltatás protected void onHandleIntent(Intent arg0) { int allapot=0; Bitmap letoltottkep=null; InputStream be=null; try{ URL url=new URL(arg0.getStringExtra("URL")); be = url.openConnection().getInputStream(); letoltottkep=BitmapFactory.decodeStream(be); allapot=1; }catch(Exception ex){ Log.d("HIBA" , "Hiba a letöltés során! "); }finally{ if(be!=null){ try{ be.close(); }catch(IOException ex){ Log.d("HIBA", "Fájlkezelési hiba"); } } } Bundle extrak= arg0.getExtras(); if(extrak!=null){ Messenger uzeno = (Messenger) extrak.get("UZENO"); Message uzenet = Message.obtain(); Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 40
}
}
}
uzenet.obj=letoltottkep; uzenet.arg1=allapot; try{ uzeno.send(uzenet); }catch(Exception ex){ Log.d("HIBA", "Hiba az üzenet küldésekor!"); }
@Override public IBinder onBind(Intent intent) { return null; }
A hívó alkalmazás felépítése a következő: package hu.nyf.letoltesintentservice; import android.os.Bundle; /* Itt az import elemek szerepelnek, melyeket hely hiányában nem részletezünk */ public class LetoltesActivity extends Activity { Context kont; Button gomb; TextView cimke; Messenger uzeno; ImageView kep; //A
szolgáltatás által küldött Message elem kezelése történik meg private Handler kezelo = new Handler(){ @Override public void handleMessage(Message msg) { int kapottallapot= msg.arg1; if(kapottallapot==0){ cimke.setText("A letöltés sikertelen volt!"); }else{ cimke.setText("A letöltés sikeres volt!"); Bitmap kapottkep=(Bitmap) msg.obj; kep.setImageBitmap(kapottkep); } } };
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
itt
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 41
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_letoltes); kont=this.getApplicationContext(); // A fogadó rész inicializálása uzeno = new Messenger(kezelo); kep = (ImageView) this.findViewById(R.id.imageView_kep); cimke = (TextView) this.findViewById(R.id.textView_uzenet); gomb = (Button) this.findViewById(R.id.button_letoltes); gomb.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent hivas = new Intent(kont, LetoltesSzolgaltatas.class); hivas.putExtra("UZENO", uzeno); hivas.putExtra("URL", //Ide kerül a letöltendő kép URL-je ); startService(hivas); } }); } } 7.3 Feladatok szolgáltatásokra 1. Készítsen alkalmazást, amely több állomány letöltését teszi lehetővé egyszerre. 2. Készítsen alkalmazást, amely percenként eltárolja egy állományba a GPS koordinátákat. Készítsen olyan alkalmazást is, amellyel lekérdezhetjük az adatokat. 3. Készítsen alkalmazást, amely a telefon bekapcsolásával indul, és amely megszámolja a beérkező hívásokat. Készítsen olyan alkalmazást is, amellyel lekérdezhetjük az adatot. 4. Fejlessze tovább az előző fejezet feladatainál található lejátszó programot, hogy az Foreground szolgáltatásként fusson.
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 42
8.
Összetett feladatok
8.1 Zenelejátszó alkalmazás Az alkalmazásban lehessen kilistáztatni a háttértároló alkönyvtárait, ezek között váltani, és az alkönyvtárakban található zenei állományokat megjeleníteni. A kiválasztott zenei állományt játssza le a lejátszó. A lejátszó minimum három gombbal rendelkezzen: play, stop, pause. Plusz feladat: egyszerre akár több állomány is kiválasztható legyen, illetve ezekből lejátszási listát lehessen szerkeszteni. Ebben az esetben a kezelő felületet egészítsük ki két gombbal, amely az előző és a következő állományra viszi a felhasználót. Az alkalmazás lehetőleg a foreground szolgáltatást valósítsa meg. 8.2 Készítsen alkalmazást, amely a felhasználó által megadott időszakonként elmenti az aktuális GPS koordinátákat az idővel együtt egy állományba! Jelenítse meg térképen a koordinátákat, lehetőleg időpont szerinti sorrendben. ·
·
·
Plusz feladat: a koordinátákat ne a telefonba, hanem valami távoli szerverre mentse el a program, majd ugyanonnan kérje le azokat a megjelenítéshez. Plusz feladat: Jelenítse meg grafikusan, a pontok összekötésével a megtett utat. Jelenítse meg a légvonalbeli távolságokat, a megtett út hosszát és idejét, valamint az átlagsebességet. Plusz feladat: A Google Maps segítségével készítsen a megtett útról útvonaltervet.
8.3 Készítsen alkalmazást, amely időjárási adatokat – időpont, hely, felhőzet, hőmérséklet, csapadék - tárol és dolgoz fel! Az adatokat SQLite adatbázisba tárolja a telefonon. Az alkalmazás az adatbázisból kérje le az adatokat, majd azokat jelenítse meg a felhasználói felületen. A program tegye lehetővé az adatbázisban való keresést helyre és időpontra. A programból lehessen új adatokat felvinni az adatbázisba. ·
Plusz feladat: egy távoli számítógépen található adatbázist használjunk az adatok tárolására
·
Plusz feladat: egy távoli számítógépen található adatbázist használjunk az adatok tárolására. Amennyiben nincs internet
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 43
kapcsolatunk, akkor az új adatokat egy SQLite adatbázisba tároljuk el. Az internet kapcsolat létrejötte után kerüljenek feltöltésre a helyi adatok a távoli számítógépre. 8.4 Készítsen gyorshívó alkalmazást! A felhasználó előre adhasson meg telefonszámokat, melyet aztán az alkalmazásból egy klikkelésre hívhasson. A megadott kapcsolatok szerkeszthetőek és törölhetőek legyenek. · Plusz feladat: a megadott telefonszámokhoz csatoljon képeket is a megjelenítéskor. ·
Plusz feladat: a névjegyek közül lehessen kiválasztani a gyorshívás alkalmazásban szereplő kapcsolatot.
·
Plusz feladat: készítsen widgetet az alkalmazásból.
8.5 Tárcsázó, üzenetküldő és hívásnapló program Készítsen programot, amivel a felhasználó által megadott számokat fel lehet hívni, vagy üzenetet lehet rájuk küldeni! Ezen kívül a program a bejövő és a kimenő hívások adatait tárolja adatbázisban! A rögzítendő adatok a hívó/hívott telefonszám, hívásirány, dátum. A hívásnapló megnyitásakor lehessen szűrni a hívásirányra és a dátumra, az eredményeket ListView-ban jelenítsük meg! 8.6 Összetett kamera alkalmazás Készítsünk olyan alkalmazást, ami saját kamerakezelést valósít meg! Főbb funkciók: · · · · ·
Választható elő, vagy hátlapi kamera Exponáló gomb Az exponálási hang ki/bekapcsolható Mutatja az elkészült kép nevét és helyét Megmutatja az utolsó elkészült képet kicsiben a képernyő sarkában
8.7 Kincskereső játék A feladat egy olyan alkalmazás készítése, amely adatbázisban megadott koordináták választhatóan megadott sugarában (1,5,10 méter) jelez, ha a felhasználó a közelbe érkezik! Ekkor jelenítse meg az aktuális kincs képét és egy rövid gratuláló szöveget! A megoldáshoz készítsünk egy BroadcastReceiver-t, amelynek az onReceive() metódusában az intent extra kulcsának az értéke Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.
Android alapú szoftverfejlesztés haladóknak Gyakorlati feladatsor 44
LocationManager.KEY_PROXIMITY_ENTERING lesz, alapértelmezetten false értékkel. Ezután készítsünk egy függvényt, ami megkaphatja a földrajzi koordinátákat, a kör sugarát! A függvény valósítson meg egy saját LocationManager referenciát! Készítsünk egy PendingIntent objektumot, amely a közelségi esemény bekövetkezéskor váltódik ki! A fogadásához készüljünk fel egy ProximityIntentReceiver példánnyal! Ha már nincs szükségünk rá, ne felejtsük el leállítani! 8.8 Fitness program Készítsünk alkalmazást futás/kerékpározás támogatására! A program rögzítse adatbázisba a felhasználó nevét és életkorát! Új edzés indításakor rögzítsük GPS segítségével 8 másodpercenként az aktuális pozíciót és annak idejét! Legyenek listázhatók az edzések! További bővítési lehetőség zenelejátszással az edzés időtartama alatt egy, az SD kártyán megadott mappában található mp3 zenékkel. 8.9 Kedvenc helyek Készítsünk programot, ami egy adott GPS pozícióban lehetővé teszi a fényképezést és szöveg rögzítését! Opcionálisan kategóriákból is lehessen választani (étterem, mozi, turistalátványosság). Az adott hely legközelebbi megközelítésénél (Proximity) jelenítse meg az adatokat újra!
Az oktatási segédanyag a „Mobil alkalmazásfejlesztés az informatikai tudás innovatív alkalmazásával” című, TÁMOP-2.2.4-11/1-2012-0055 kódszámú projekt keretében valósult meg.