SZOFTVERFEJLESZTÉS ANDROID PLATFORMRA Dr. Iszály György Barna
TELEFON KEZELÉSE - EMULÁCIÓ •
A DDMS (Dalvik Debug Monitor Server) számos lehetőséget nyújt számunkra • bejövő hívások szimulálása • érkező SMS üzenetek emulálása
•
Eclipse DDMS perspektívájában találjuk a DDMS menüpontot
•
Emulator Control
•
Másik lehetőség a már ismert Telnet kliense elérés
•
telnet localhost 5554 • gsm call
• sms send
SZOLGÁLTATÁSI INFORMÁCIÓK •
Az android.telephony csomag része a TelephonyManager osztály
•
Feladata az eszközön elérhető telefonos szolgáltatásokkal kapcsolatos információk biztosítása • a SIM kártya telefonszáma, • A hálózati operátor kódja, • Roamingadatok, stb.
•
Le kell kérni a rendszertől a szolgáltatás referenciáját: TelephonyManager tm = (TelephonyManager) getSystemService(android.content.Context.TELEPHONY_SERVICE);
LEGFONTOSABB INFORMÁCIÓS METÓDUSAI •
getLine1Number() - stringként visszaadja az első SIM kártya számát.
•
getNetworkOperator() - megadja az aktuális beregisztrált szolgáltató (MNC, mobile network code) és ország (MCC, mobile country code) kódját, string formátumban.
•
getNetworkOperatorName() – visszaadja a hálózati szolgáltató nevét
•
getSimState(): a SIM kártya jelenlegi állapota. • SIM_STATE_READY - a kártya hívásindításra és fogadásra kész. • SIM_STATE_NETWORK_LOCKE - a kártya zárolt, hálózati PIN szükséges a feloldásához. • SIM_STATE_ABSENT - nincs elérhető kártya a készülékben. • SIM_STATE_PIN_REQUIRED - PIN kód megadására várunk, addig csak segélyhívások érhetők el. • SIM_STATE_PUK_REQUIRED: ugyanaz, mint a PIN_REQUIRED, de PUK kódra vonatkozóan. • SIM_STATE_UNKNOWN - a kártya állapota ismeretlen (pl. állapotváltások között)
LEGFONTOSABB INFORMÁCIÓS METÓDUSAI •
getPhoneType() - Az eszköz milyen típusú mobil hanghívások átvitelére alkalmas. • PHONE_TYPE_GSM - jellemzően Európában használt átviteli mód. • PHONE_TYPE_CDMA - tipikusan az Egyesült Államokban, vagy Kanadában használt átvitel. • PHONE_TYPE_SIP - hangátvitel jellemzően internetes hálózaton • PHONE_TYPE_NONE: hiányzó modul. Táblagépeken előfordulhat.
•
isNetworkRoaming() – igaz, ha jelenleg roamingol a kártya
•
Jogosultság - android.permission.READ_PHONE_STATE
FELIRATKOZÁS MOBILHÁLÓZATI ESEMÉNYEKRE private PhoneStateListener sajatPhoneListener = new PhoneStateListener() { public void onCallStateChanged(int state, String incomingNumber) {
// incomingNumber a bejövő hívó száma try { if (state == TelephonyManager.CALL_STATE_RINGING ) // Bejövő hívás } catch (Exception e) { Log.i("Kivétel", "PhoneStateListener() e = " + e); }
} } //Telephony Manager szolgáltatás igénybe vétele TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); //Feliratkozás változás-figyelésre tm.listen(sajatPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
FELIRATKOZÁS MOBILHÁLÓZATI ESEMÉNYEKRE •
További állapotok: • CALL_STATE_OFFHOOK: legalább egy hívás folyamatban, vagy tartásban van. • CALL_STATE_IDLE: nincs hívási aktivitás
•
Mobilnet állapotai: • onDataConnectionStateChanged(int state) – ezt a callback függvényt kell alkalmazni • LISTEN_DATA_CONNECTION_STATE – ezt kell megadni a listen() függvénynek
•
A lehetséges TelephonyManager állapotok
•
DATA_CONNECTING - mobilnet kapcsolat felépítése folyamatban van.
•
DATA_CONNECTED - a mobilnet felépült.
•
DATA_SUSPENDED - a mobilnet kapcsolat felfüggesztésre került, például egy bejövő hanghívás miatt.
•
DATA_DISCONNECTED - a mobilnet nem érhető el.
TELEFONHÍVÁS KEZDEMÉNYEZÉSE •
Alapértelmezetten szükséges hozzá a android.permission.CALL_PHONE jogosultság
•
A android.permission.CALL_PRIVILEGED joggal az alkalmazásunk képes bármilyen szám, akár segélyhívó közvetlen hívására is anélkül, hogy a felhasználónak a hívást a tárcsázó alkalmazáson keresztül előzetesen még jóvá kellene hagynia. 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 }
TELEFONHÍVÁS KEZDEMÉNYEZÉSE •
Amennyiben ismerjük a kapcsolatlistán található hívandó személy ID-jét, akkor a következő is alkalmazható Uri.parse("content://contacts/people/" + SZEMÉLY_ID)
•
Vészhívást csak az ACTION_DIAL-on keresztül kezdeményezhetünk! Itt a hívást a tárcsázó programon belül nekünk kell kezdeményeznünk.
•
ACTION_CALL_BUTTON – ez az intent a tárcsázó gomb megnyomásával egyenértékű. Nem ad át a tárcsázó programnak hívandó számot.
ÜZENETEK KEZELÉSE – SMS KÜLDÉSE •
Jogosultság - android.permission.SEND_SMS
Intent smsKuldIntent = new Intent(); smsKuldIntent.setAction(Intent.ACTION_SENDTO); smsKuldIntent.setData(Uri.parse("tel:+36301234567")); smsKuldIntent.putExtra("sms_body", "Szia! Ez egy tesztüzenet"); try{ startActivity(smsKuldIntent); } catch (ActivityNotFoundException e) { //TODO: Nincs alapértelmezett SMS küldő alkalmazás }
ÜZENETEK KEZELÉSE – SMS FOGADÁSA •
SMS érkezésekor broadcast üzenet generálódik – saját BroadcastReceiver osztályt kell létrehoznunk
•
Az üzenet metaadatai az Intemt extráiban jelenik meg „pdus” kulcs alatt
•
Metaadatok lekérdezése - android.telephony.SmsMessage.createFromPdu()
•
Jogosultság - android.permission.RECEIVE_SMS
SMS FOGADÁSA SAJÁT BROADCASTRECEIVER public class IncomingSMSReceiver extends BroadcastReceiver { private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED"; public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(SMS_RECEIVED)){ SmsManager sms = SmsManager.getDefault(); Bundle csomag = intent.getExtras(); if (csomag != null){ Object[] pdus = (Object[])csomag.get("pdus"); SmsMessage uzenet = null; for (int i = 0; i < pdus.length;i++){ uzenet=SmsMessage.createFromPdu((byte[])pdus[i]); String torzs = uzenet.getMessageBody(); String felado = uzenet.getOriginatingAddress(); }}}}}
ÜZENETEK KEZELÉSE – MMS KÜLDÉSE •
Jogosultság - android.permission.SEND_SMS
•
A címzett telefonszáma extra, amit az „address” kulcs határoz meg.
•
Az üzenet szintén extra, „sms_body” kulcs rejti.
•
Az intent adat a csatolt fájl útvonala lesz, Uri.parse-ban megadva.
•
setType() határozza meg a csatolás típusát.
•
Az intent adatfolyamát az EXTRA_STREAM-ben is meg kell határozni (csatolt fájl útvonala).
PÉLDA MMS KÜLDÉSÉRE File csatoltFajl = new File("útvonal\képfájl_neve.jpg"); Uri csatolasUtvonala = Uri.parse(csatoltFajl.toString()); Intent mmsKuldIntent = new Intent(); mmsKuldIntent.setAction(Intent.ACTION_SEND); mmsKuldIntent.putExtra("address", "+3630123456"); mmsKuldIntent.putExtra("sms_body", "Szia! Csatoltam egy jó képet!"); mmsKuldIntent.setData(csatolasUtvonala); mmsKuldIntent.setType("image/jpg"); mmsKuldIntent.putExtra(Intent.EXTRA_STREAM, csatolasUtvonala); try{ startActivity(mmsKuldIntent); } catch (ActivityNotFoundException e) { //TODO: Nincs alapértelmezett MMS küldő program }
TELEFONHÍVÁSOK KEZELÉSE A HÁTTÉRBEN •
Saját BroadcastReceiver osztály szükséges hozzá
•
Jogosultság - az android.permission.PHONE_STATE
•
Szükséges intent-filter - android.intent.action.PHONE_STATE.
•
Az intent extrái között kapjuk meg a hívással kapcsolatos információkat: • TelephonyManager.EXTRA_STATE - jelzi az új állapotot • TelephonyManager.EXTRA_STATE_RINGING - jelzi a csörgést • TelephonyManager.EXTRA_INCOMING_NUMBER – a hívó száma • EXTRA_STATE_OFFHOOK – ez jelzi, hogy a hívás felépült a két fél között. • EXTRA_STATE_IDLE –az az állapot, amikor a hívás elutasításra kerül.
PÉLDA BEJÖVŐ HÍVÁSOK KEZELÉSÉRE public void onReceive(Context context, Intent intent) { String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){ // Csörög a telefon, a bejövő szám a // TelephonyManager.EXTRA_INCOMING_NUMBER-ben van }else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ // A hívás fogadva }else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){ // A hívás eldobva, vagy elutasítva } }
PÉLDA BEJÖVŐ HÍVÁSOK KEZELÉSÉRE A Manifest állományban regisztrálni kell a receivert
KIMENŐ HÍVÁSOK KEZELÉSE •
Hívott szám helye az intent extra részében – TelephonyManager.EXTRA_PHONE_NUMBER
•
Megcélzott esemény - android.intent.action.NEW_OUTGOING_CALL
•
Jogosultság - android.permission.PROCESS_OUTGOING_CALLS
public void onReceive(Context context, Intent intent) { String state =intent.getStringExtra(TelephonyManager.EXTRA_STATE); if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){ // Kicsöng a telefon, a hívott szám a // TelephonyManager.EXTRA_PHONE_NUMBER-ben van } }
KIMENŐ HÍVÁSOK KEZELÉSE A manifest állományban a következő bejegyzés szükséges