Slide 1

Slide 1 text

Android School Warsztat 03 Adam Jodłowski

Slide 2

Slide 2 text

2 Intencje rozgłaszane ● intencje, stanowiące podstawowy mechanizm IPC, mogą być wysyłane w trybie PTP lub broadcast ● broadcasty dzielimy na zwykłe Context.sendBroadcast(...); i uporządkowane Context.sendOrderedBroadcast(...); ● zwykłe broadcasty są asynchroniczne, nie możemy przewidzieć czasu ani kolejności ich dotarcia do odbiorców ● broadcasty uporządkowane powodują powstanie łańcucha wywołań i obsługiwane są przez odbiorców w kolejności

Slide 3

Slide 3 text

3 Broadcast receivers ● komponenty przetwarzające intencje rozgłaszane w systemie ● aktywowane są w momencie rozgłoszenia intencji i deaktywowane po wyjściu z metody onReceive(Context, Intent) działającej w wątku interfejsu użytkownika ● możemy zarejestrować je na dwa sposoby, w kodzie aplikacji: BroadcastReceiver br = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // obsługa rozgloszonej intencji // abortBroadcast(); // skonsumowanie broadcastu } }; registerReceiver(br, new IntentFilter("android.provider.Telephony.SMS_RECEIVED")); unregisterReceiver(br); // nie zapomnij o wyrejestrowaniu!

Slide 4

Slide 4 text

4 Broadcast receivers ● rejestracja za pomocą manifestu: ● osobna klasa odbiorcy implementuje logikę przetwarzania: public class SmsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // przetworzenie broadcastu } }

Slide 5

Slide 5 text

5 Napisz aplikację odbierającą przychodzące wiadomości SMS, rejestrując odbiorcę w sposób programowy. Nie zapomnij o odpowiednim zezwoleniu.

Slide 6

Slide 6 text

6 Podpowiedź: parsowanie wiadomości SMS Bundle data = intent.getExtras(); if (data != null) { String message = ""; String sender = null; Object pdus[] = (Object[]) data.get("pdus"); for (Object pdu : pdus) { SmsMessage part = SmsMessage.createFromPdu((byte[]) pdu); message += part.getDisplayMessageBody(); if (sender == null) { sender = part.getDisplayOriginatingAddress(); } } }

Slide 7

Slide 7 text

7 Pending intent ● reprezentacja intencji w postaci tokenu do użycia w przyszłości przez inny proces, w imieniu naszej aplikacji, z naszymi uprawnieniami ● specyfikujemy akcję i jej parametry jak zawsze w przypadku intencji, ale faktyczne zlecenie jej wykonania następuje na skutek działania innej aplikacji, która otrzymała nasz pending intent

Slide 8

Slide 8 text

8 Powiadomienia systemowe ● realizowane są przez usługę NotificationManager, ich podstawowe parametry obejmują ikonę powiadomienia tytuł treść dodatkowy tekst przewijany intencję uruchamianą po kliknięciu sygnały dźwiękowe, świetlne i wibracje ● każde powiadomienie rozróżniane jest przez numer ID

Slide 9

Slide 9 text

9 Tworzenie powiadomień (old school) ● powiadomienia realizowane są przez usługę NotificationManager int NOTIFICATION_ID = 1; NotificationManager notifier = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification n = new Notification(); n.icon = android.R.drawable.stat_notify_error; n.tickerText = "Tekst przewijany"; n.when = System.currentTimeMillis(); n.flags |= Notification.FLAG_AUTO_CANCEL; Intent intent = new Intent(MyActivity.this, MyActivity.class); PendingIntent pending = PendingIntent.getActivity(MyActivity.this, 0, intent, 0); n.setLatestEventInfo(MyActivity.this, "Tytul", "Tresc", pending); notifier.notify(NOTIFICATION_ID, n); ● dodatkowe parametry powiadomień n.vibrate = new long[] { 300, 200, 300, 200 }; n.flags |= Notification.FLAG_SHOW_LIGHTS; n.ledARGB = Color.YELLOW; n.ledOnMS = 500; n.ledOffMS = 5000; n.sound = Uri.parse("file:///sdcard/notif.mp3"); n.number = 3; n.defaults |= Notification.DEFAULT_SOUND;

Slide 10

Slide 10 text

10 Tworzenie powiadomień (new school) ● nowy sposób tworzenia bogatych powiadomień używając SupportLibrary int NOTIFICATION_ID = 1; Intent resultIntent = new Intent(MyActivity.this, MyActivity.class); PendingIntent resultPendingIntent = PendingIntent.getActivity(MyActivity.this, 0, resultIntent, 0); NotificationCompat.Builder builder = new NotificationCompat.Builder(MyActivity.this) .setSmallIcon(android.R.drawable.stat_sys_warning) .setTicker("Tekst przewijany") .setContentTitle("Tytul") .setContentText("Tresc") .setContentIntent(resultPendingIntent) .addAction(android.R.drawable.stat_notify_sdcard_usb, "Akcja", resultPendingIntent); NotificationManager notifier = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notifier.notify(NOTIFICATION_ID, builder.build()); ● powiadomienia mogą być rozwijane za pomocą gestów, zawierać duże obrazki, wiele linii tekstu itp.

Slide 11

Slide 11 text

11 Przetestuj mechanizm powiadomień na skutek rozesłania intencji lub wykonania określonej akcji w aplikacji.

Slide 12

Slide 12 text

12 Preferencje systemowe ● mechanizmy klasy android.content.SharedPreferences pozwalają na składowanie na urządzeniu prostych danych w postaci klucz- wartość ● aplikacja może mieć wiele zestawów preferencji identyfikowanych po nazwie, przydzielonych do konkretnych aktywności: SharedPreferences sp = getPreferences(MODE_PRIVATE); ● bądź całej aplikacji: SharedPreferences sp = getSharedPreferences("prefs", MODE_PRIVATE); ● w obu przypadkach zwracany jest uchwyt do jednej instancji obiektu, co pozwala na natychmiastową rejestrację zmian w różnych komponentach aplikacji

Slide 13

Slide 13 text

13 Manipulacja preferencjami ● pobieranie danych long updateTimestamp = sp.getLong("updated", -1); sp.contains(); sp.getAll(); // Map sp.getBoolean(); sp.getFloat(); sp.getInt(); sp.getString(); ● możemy zarejestrować nasłuch na zmiany sp.registerOnSharedPreferenceChangeListener(...); ● edycja preferencji odbywa się za pomocą edytora SharedPreferences.Editor e = sp.edit(); e.putString("username", "scott"); e.putBoolean("isadmin", false); e.commit(); // boolean

Slide 14

Slide 14 text

14 Przetestuj mechanizm preferencji.

Slide 15

Slide 15 text

15 PreferenceActivity ● możemy wykorzystać framework automatycznie zarządzający preferencjami użytkownika (aktualne, zalecane API oparte jest o PreferenceFragment) ● do tego celu tworzymy aktywność rozszerzającą PreferenceActivity i ustawiamy jej zawartość (w metodzie onCreate()) odwołując się do widoku XML addPreferencesFromResource(R.xml.preferences); ● takie preferencje są określane jako domyślne SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(co ntext);

Slide 16

Slide 16 text

16 Widok XML preferencji ● preferencje możemy dowolnie konfigurować dzięki plikom XML ● zagnieżdżenie preferencji polega na umieszczeniu PreferenceScreen w istniejącym już PreferenceScreen, analogicznie jak w przypadku menu podręcznego

Slide 17

Slide 17 text

17 Reakcja na zmiany na ekranie preferencji ● zalecane jest wyświetlanie wartości preferencji od razu po ich wybraniu public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } @Override protected void onResume() { super.onResume(); getPreferenceScreen().getSharedPreferences() .registerOnSharedPreferenceChangeListener(this); } @Override protected void onPause() { super.onPause(); getPreferenceScreen().getSharedPreferences() .unregisterOnSharedPreferenceChangeListener(this); } @Override public void onSharedPreferenceChanged(SharedPreferences sp, String key) { Preference pref = findPreference(key); pref.setSummary(sp.getString(key, "")); } }

Slide 18

Slide 18 text

18 Stwórz aktywność z użyciem PreferenceActivity, przetestuj jej działanie, zapoznaj się z dokumentacją dotyczącą preferencji.

Slide 19

Slide 19 text

19 Zadanie domowe: Zapoznaj się z pozostałymi broadcastami systemowymi. Stwórz aplikację przechwytującą wybrane zdarzenie i wyświetlającą powiadomienie systemowe. Wykorzystaj preferencje do modyfikacji działania programu.