8.4.2013
Programování pro operační systém Android (BI-AND) (c) Autor a garant: M. Havryluk, Spolupráce: M. Balík, O. Kroupa, M. Pelant
1
8. INTENT FILTERS A BRODACAST RECEIVER BI-AND
8.4.2013
8. Přednáška • PreferenceActivity • Intenty (pokračování)
• Intent-Filter • Broadcast Receiver
2
8.4.2013
PreferenceActivity • Framework umožňující definovat
obrazovku s nastavením aplikace pomocí XML uložené v res/xml/ • Propojení XML komponent přímo na
položky v SharedPreferences • Konzistentní vzhled napříč aplikacemi • Obtížněji se styluje
3
8.4.2013
PreferenceActivity • Nastavení je automaticky uloženo do defaultních
SharedPreferences společných pro všechny komponenty aplikace • Komponenta se skládá ze 2 částí: • XML layoutu • Třída dědící od PreferenceActivity (musí být definována v AndroidManifestu jako každá jiná activita)
4
8.4.2013
5
PreferenceActivity – XML • Každý preference layout je definovaný jako hierarchie začínající
elementem PreferenceScreen 1. 2.
4. ... 5.
• Je možné do sebe vnořit více obrazovek
PreferenceScreen,každá pak bude reprezentována jako položka, po jejímž výběru se zobrazí nová obrazovka s nastavením 1. 2. 3. 4. 5. 6. 7. 8.
...
... ...
8.4.2013
6
PreferenceActivity – XML elementy • V PreferenceScreen je dále možné přidávat šest
různých elementů: • CheckBoxPreference – jednoduchý Checkbox, který
vrací true/false • ListPreference – po výběru zobrazí RadioGroup, kde
uživatel může zvolit jednu položku • V android:entries se definují položky z res/values/arrays, z
kterých uživatel vybírá • V android:entryValues se k nim pak definují hodnoty, které se uloží; opět z res/values/arrays
8.4.2013
7
PreferenceActivity – XML elementy • EditTextPreference – po výběru zobrazí EditText • Vrací String • RingtonePreference – po výběru zobrazí radioGroup
s dostupnými vyzváněcími tóny • Vrací String s URI zvoleného tónu
• Preference – obecná položka, chová se v podstatě jako
Button • PreferenceCategory – kategorie pomocí které od
sebe můžeme položky oddělit
8.4.2013
8
PreferenceActivity – XML atributy • U každé Preference můžeme definovat tyto základní
parametry • android:title – titulek položky (zobrazuje se v 1. řádku) • android:summary – podrobnější popisek položky (2. řádek) • android:defaultValue – defaultní hodnota (použije se, pokud
zatím nebyla žádná hodnota uložena) • android:key – klíč, pod kterém se uloží hodnota do
SharedPreferences
8.4.2013
9
PreferenceActivity – XML atributy • Další možné parametry u každé položky • android:persistent – určuje, jestli se tato položka bude
ukládat do SharedPreferences (false = nebude) • android:enabled – určuje, jestli je tato položka aktivní • android:dependency – pokud se vyplní určená položka nebo se
změní její stav (enabled/disabled), daná preference půjde nebo nepůjde použít
8.4.2013
PreferenceActivity - XML 1. 2.
4. 5. 10. 18. 19. 20. 25. 26.
10
8.4.2013
11
PreferenceActivity - Java • Ve třídě dědící od PreferenceActivity přiřadíme
námi vytvořené XML zavoláním addPreferencesFromResource(id) • Konkrétní Preference získáme pomocí
findPreference(key); 1. public class Settings extends PreferenceActivity { 2. @Override 3. protected void onCreate(Bundle savedInstanceState) { 4. super.onCreate(savedInstanceState); 5. addPreferencesFromResource(R.xml.preferences); 6. 7. ListPreference listPreference = (ListPreference) findPreference("listPref"); 8. //Nastavime hodnoty u listPreference 9. listPreference.setEntries(new String[] { "polozka1", "polozka2" }); 10. listPreference.setEntryValues(new String[] { "1", "2" }); 11. } 12. }
8.4.2013
12
PreferenceActivity - Java • PreferenceActivity je provázána s default
SharedPreferences • Nastavení vlastního PrefFile jako default
SharedPreferences 1. PreferenceManager prefMgr = getPreferenceManager(); 2. prefMgr.setSharedPreferencesName("my_preferences"); 3. prefMgr.setSharedPreferencesMode(MODE_WORLD_READABLE); 4. 5. addPreferencesFromResource(R.xml.prefs);
8.4.2013
13
PreferenceActivity - Java • Pokud potřebujeme sledovat změny v nastavení,
implementujeme OnSharedPreferenceChangeListener 1. public class Settings extends PreferenceActivity 2. implements OnSharedPreferenceChangeListener { 3. @Override 4. protected void onCreate(Bundle savedInstanceState) { 5. super.onCreate(savedInstanceState); 6. addPreferencesFromResource(R.xml.preferences); 7. 8. // ziskame defaultni SharedPreferences, do kterych zapisuje PreferenceActivity 9. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); 10. // zaregistrujeme OnSharedPreferenceChangeListener 11. sp.registerOnSharedPreferenceChangeListener(this); 12. 13. } 14. 15. // Zavola se pri jakekoli zmene danych SharedPreferences 16. @Override 17. public void onSharedPreferenceChanged(SharedPreferences sp, String key) { 18. // Provedeni potrebnych ukonu, pokud uzivatel zmeni nejake nastaveni 19. } 20.}
8.4.2013
14
Intent • Zpráva s informacemi pro příjemce • Jakým způsobem se má naložit s daty ve zprávě
• Zpráva s informacemi pro systém • Kategorie komponenty a instrukce, jakým způsobem má být spuštěna
• Pro Intent lze nastavit šest hlavních parametrů: • Component Name • Action • Data • Category • Extras • Flags
15
8.4.2013
Intent Filters • Určují, pro jaký obsah se může daná komponenta použít
• V úvahu se berou tyto tři parametry Intentu: • Action • Data (URI i MIME type) • Category
Každá komponenta může mít definováno více Intent Filters
• Definují se v AndroidManifest.xml v tagu dané komponenty 1.
4. 5. 7. 9. 11. 12.
8.4.2013
16
Intent – Component Name • Název komponenty, která se má postarat o přijetý Intent • Skládá se z • Celého názvu cílové komponenty – např. cz.cvut.fit.ContactActivity • Názvu package – např. cz.cvut.fit • Název cílové komponenty a package nemusí být vždy
nutně stejný • Určení pomocí metod setComponent(),
setClass()nebo setClassName()
8.4.2013
17
Intent - Action • Název akce, jaká má být provedena • Podobné jako u protokolu HTTP a operací GET, POST,
PUT, DELETE atd. • V Android API je množství akcí daleko větší
• Je možné rovněž vytvářet vlastní akce
8.4.2013
18
Intent Filters – Action • Definuje akci, pro kterou se daná komponenta má spustit • Při definování vlastní akce se doporučuje zahrnout celé
jméno balíčku např. „cz.cvut.example.SHOW_COLOR“ Intent filtr v AndroidManifest.xml 1.
2. 4. ... 5.
Nastavení akce 1. intent.setAction(Intent.ACTION_SEND); 2. //nebo "android.intent.action.SEND“
8.4.2013
19
Intent – nejpoužívanější akce • Intent.ACTION_CALL
• Zahájí telefonní hovor • Vyžaduje oprávnění android.permission.CALL_PHONE • Intent.ACTION_DIAL
• Otevře telefonní aplikaci s předvyplněným číslem • Intent.ACTION_EDIT
• Slouží k editaci dat • Intent.ACTION_MAIN
• Spustí hlavní activitu aplikace • Intent.ACTION_VIEW
• Zobrazí data uživateli (zobrazení obrázku, přehrání hudby…) • Intent.ACTION_SEND • Odešle data
• Intent.ACTION_DELETE • Smaže daná data
8.4.2013
20
Intent – Data • Definuje, pro jaký typ dat se má komponenta použít • Tag
může specifikovat URI a/nebo MIME typ • URI je rozděleno do 4 částí, z nichž každá má svůj atribut v tagu
- scheme://host:port/path Intent filtr v AndroidManifest.xml 1. 2. ... 3. 6. ... 7.
Nastavení typu a URI 1. intent.setType("text/plain");
2. intent.setData(Uri.parse("file:///sdcard/folder/file.txt"));
8.4.2013
Intent – Category • (Dodatečná) informace o tom, jaká komponenta má
zpracovat Intent • Nejpoužívanější kategorie: • Intent.CATEGORY_PREFERENCE • Cílová activita je panel s nastavením • Intent.CATEGORY_DEFAULT • Přidávána defaultně při startActivity() • Cílová komponenta není určena
21
8.4.2013
22
Intent – nejpoužívanější kategorie • Intent.CATEGORY_BROWSABLE • Cílová activita je uplatněná jako prohlížeč dat předaných
odkazem • Intent.CATEGORY_HOME • Activita zobrazuje domovskou obrazovku (náhrada
defaultního launcheru) • Intent.CATEGORY_LAUNCHER
• Počáteční activita, která se spustí po vybrání z launcheru
23
8.4.2013
Intent Filtres – Category • Intent projde intent filtrem, pokud filtr obsahuje všechny v
intentu nastavené kategorie • Všechny intenty předané do startActivity() obsahují minimálně tuto kategorii: android.intent.category.DEFAULT Intent filtr v AndroidManifest.xml
Výjimka pro Explicit Intents a MAIN Action/Launcher Category
1. 2. ... 3. 4. 5. ... 6.
Přidání kategorie 1. intent.addCategory(Intent.CATEGORY_BROWSABLE); 2. intent.addCategory(Intent.CATEGORY_PREFERENCE);
8.4.2013
24
Intent – Extras a Flags • Extras • Předání dalších informací pomocí klíč/hodnota • Přenáší se zde další potřebné údaje v rámci systémových Intent • Viz. 7. přednáška
• Flags • Určuje, jakým způsobem se má spustit daná komponenta • Řazení na zásobník, animace, launchmode
• Viz. 3. přednáška
8.4.2013
25
Intent - Explicitní • Spouštějí přesně definovanou třídu (resp. komponentu) • Komponenta může být: • Activity • Service • Broadcast Receiver
• Většinou nejsou používány vývojáři jiných aplikací • Neznají přesné jméno komponenty • Název komponenty se může změnit
8.4.2013
Intent - Implicitní • Nemají přímo definovaný cíl • Pokud existuje více potenciálních
Activit pro daný Intent, může si uživatel zvolit, jakou chce spustit • Jednoduché rozšíření funkčnosti
programu • Většinou se používají ke spouštění
komponent jiných aplikací
26
8.4.2013
27
Intent - Implicitní • Název komponenty zůstává nevyplněn • Systém porovná obsah Intentu s Intent Filtres komponent
a vybere ty, které mohou daný Intent přijmout • Lze dopředu zjistit jaké komponenty mohou Intent
přijmout pomocí • PackageManager – metody queryIntentActivities(),
queryIntentServices(), queryIntentReceivers()
8.4.2013
Intent Filter – edux filtr
28
8.4.2013
29
Intent – výběr activity • Dialog výběru activit umožňuje
standardně nastavit 1 activitu jako defaultní • Pro vynucené zobrazení dialogu
použijeme Intent.createChooser(Intent,String);
• Vhodné při sdílení 1. 2. 3. 4.
Intent intent=new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "text, ktery chceme sdilet"); startActivityForResult(Intent.createChooser(intent, "Sdilej"), 0);
8.4.2013
30
Další informace o Intents • Registr Intents a přidružených aplikací
http://www.openintents.org • Další pravidla pro zachytávání Intents
http://developer.android.com/guide/topics/intents/i ntents-filters.html#ifs
8.4.2013
31
Broadcast • Doposud jsme Intenty používali ke spouštění nové
Activity, Service apod. • Intenty však mohou sloužit také jako posílání anonymních
zpráv mezi komponentami • Většinou reakce na určité změny v systému • Naprosto oddělený mechanismus od toho používaného např. při
startActivity()
• Po odeslání broadcastu se pošle daný Intent všem
BroadcastReceiverům zaregistrovaným na danou akci v Intentu
8.4.2013
32
Broadcast Receiver • Zachytávání Broadcastu při komunikaci jednotlivých
komponent v systému • Je potřeba implementovat pouze metodu onReceive() • Životní cyklus vázaný na danou komponentu. Jinak
skončí po přijetí zprávy (dokončení onReceive()) • Není vázaný na UI – nemůže vytvořit dialog, nastartovat
background thread apod.
33
8.4.2013
Broadcast Receiver - zaregistrování • Staticky v AndroidManifest.xml 1. 3. 4. 6. 7.
• Nebo dynamicky v kódu (např. pokud je potřeba pouze
když je activita viditelná) 1. 2. 3. 4. 5.
IntentFilter filter = new IntentFilter(TEST_BROADCAST); BroadcastReceiver myReceiver = new TestReceiver(); registerReceiver(myReceiver, filter); Provést např. v onResume() ... unregisterReceiver(myReceiver);
Provést např. v onPause()
8.4.2013
34
Broadcast Receiver • Startují se automaticky obdržením broadcastu • onReceive musí skončit do deseti sekund • Pro delší operace je zde vhodné spustit službu • BroadcastReceiver nedědí z Contextu, ten je předán
metodě onReceive 1. public class MyReceiver extends BroadcastReceiver { 2. 3. @Override 4. public void onReceive(Context context, Intent intent) { 5. int id = intent.getIntExtra("id", 0); 6. ... 7. } 8. }
35
8.4.2013
Broadcast – odeslání
Sticky Intents
• Broadcast můžeme odeslat dvěma způsoby • Normal Broadcast (Non-Ordered) • Pošle se pomocí Context.sendBroadcast • Je kompletně asynchronní – všechny BroadcastReceivery
obdrží tuto zprávu v nedefinovaném pořadí • Většinou jsou zpracovány postupně, kvůli zabránění
přílišnému vytížení systému • Není možného ho zrušit
8.4.2013
36
Broadcast – odeslání • Ordered Broadcast • Posílá se pomocí Context.sendOrderedBroadcast • V jeden okamžik zpracovává zprávu maximálně jeden
Broadcast Receiver • Pořadí se určí atributem android:priority v Intent filteru
daného receiveru • Po zpracování zprávy může každý Brodcast Receiver určit,
zda-li • Předá výsledek dalšímu Broadcast Receiveru v pořadí • Kompletně zruší daný broadcast a dál už se předávat nebude
37
8.4.2013
Broadcast – odeslání 1. 2. 3. 4. 5. 6. 7. 8. 9.
... public static final String TEST_BROADCAST= "cz.cvut.example.TEST_BROADCAST"; ... Intent i = new Intent(TEST_BROADCAST); i.putExtra("id", 3); sendBroadcast(i); • Obvykle se používá jméno balíčku, aby ... se zajistila jedinečnost
• Tímto řetězcem se musí zaregistrovat
všechny BroadcastReceivery, které mají reagovat na tuto zprávu
8.4.2013
38
Broadcast – nejpoužívanější • Intent.ACTION_BOOT_COMPLETED • Odešle se po nastartování systému • Vyžaduje oprávnění RECEIVE_BOOT_COMPLETED
• Intent.ACTION_MEDIA_BUTTON • Odešle se po stisknutí tlačítka pro ovládání přehrávače (např.
na sluchátkách) • V Intentu je v extra poli EXTRA_KEY_EVENT informace o
daném tlačítku • Intent.ACTION_CAMERA_BUTTON
• Odešle se po stisknutí tlačítka fotoaparátu
8.4.2013
39
Broadcast – nejpoužívanější • Intent.ACTION_MEDIA_EJECT • Pokud se uživatel rozhodne vyjmout externí úložiště (média) • Po obdržení této zprávy by aplikace měly ukončit IO z/do
externího úložiště • Intent.ACTION_BATTERY_LOW • Odešle se spolu s hláškou o nízkém stavu baterky • Intent.ACTION_SCREEN_ON a ACTION_SCREEN_OFF • Odešle se při zapnutí a vypnutí obrazovky • Intent.ACTION_MEDIA_MOUNTED a
ACTION_MEDIA_UNMOUNTED • Odešle se po vložení/vyjmutí externího úložiště (média)
8.4.2013
40
Broadcast - oprávnění • Pro vyžádání oprávnění při odesílání broadcastu předáme
nenullový parametr jedné z metod • sendBroadcast(intent, receiverPermission); • sendOrderedBroadcast(intent, receiverPermission);
• Daný broadcast přijmou pouze receivery, které mají
toto oprávnění definované v AndroidManifest.xml pomocí <uses-permission>
41
8.4.2013
Broadcast - oprávnění • Pro vyžádání oprávnění při přijímání definujeme toto oprávnění
při zaregistrování Broadcast Receiveru
• Dynamicky – registerReceiver(receiver, filter,
broadcastPermission, scheduler); Scheduler – vlákno, které • Staticky 1.
2. android:name=".MyReceiver" 3. android:permission="android.permission.INTERNET"> 4. ... 5.
• Broadcast Receiver přijme daný broadcast pouze z aplikací,
které mají toto oprávnění definované v AndroidManifest.xml pomocí <uses-permission>
8.4.2013
42
Další zdroje • http://www.openintents.org • http://developer.android.com/guide/topics/intents/intents-
filters.html#ifs • http://android-developers.blogspot.com/2012/02/share-
with-intents.html