Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android School 03

Android School 03

Broadcast receivers, odbieranie i parsowanie SMS, mechanizmy powiadomień systemowych. Koncepcja intencji odroczonych (pending intents). Zarządzanie ustawieniami aplikacji przez shared preferences, użycie PreferenceActivity z deklaracjami w formie XML.

Adam Jodłowski

April 05, 2013
Tweet

More Decks by Adam Jodłowski

Other Decks in Programming

Transcript

  1. 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
  2. 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!
  3. 4 Broadcast receivers • rejestracja za pomocą manifestu: <receiver android:name=".SmsReceiver">

    <intent-filter android:priority="100"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> • osobna klasa odbiorcy implementuje logikę przetwarzania: public class SmsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // przetworzenie broadcastu } }
  4. 5 Napisz aplikację odbierającą przychodzące wiadomości SMS, rejestrując odbiorcę w

    sposób programowy. Nie zapomnij o odpowiednim zezwoleniu.
  5. 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(); } } }
  6. 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
  7. 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
  8. 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;
  9. 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.
  10. 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
  11. 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
  12. 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);
  13. 16 Widok XML preferencji • preferencje możemy dowolnie konfigurować dzięki

    plikom XML <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="Pierwsza kategoria"> <ListPreference android:key="colors" android:title="Kolory" android:summary="Wybierz kolor" android:entries="@array/colors_entries" android:entryValues="@array/colors_entry_values" android:dialogTitle="Wybierz kolor" android:defaultValue="0" /> </PreferenceCategory> <PreferenceCategory android:title="Druga kategoria"> <EditTextPreference android:key="name" android:title="Podaj imie" android:summary="Podaj imie" android:defaultValue="" android:inputType="text" /> </PreferenceCategory> </PreferenceScreen> • zagnieżdżenie preferencji polega na umieszczeniu PreferenceScreen w istniejącym już PreferenceScreen, analogicznie jak w przypadku menu podręcznego
  14. 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, "")); } }
  15. 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.