$30 off During Our Annual Pro Sale. View Details »

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. Android School
    Warsztat 03
    Adam Jodłowski

    View Slide

  2. 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

    View Slide

  3. 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!

    View Slide

  4. 4
    Broadcast receivers

    rejestracja za pomocą manifestu:


    android:name="android.provider.Telephony.SMS_RECEIVED" />



    osobna klasa odbiorcy implementuje logikę przetwarzania:
    public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    // przetworzenie broadcastu
    }
    }

    View Slide

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

    View Slide

  6. 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();
    }
    }
    }

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

  9. 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;

    View Slide

  10. 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.

    View Slide

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

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

  14. 14
    Przetestuj mechanizm preferencji.

    View Slide

  15. 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);

    View Slide

  16. 16
    Widok XML preferencji

    preferencje możemy dowolnie konfigurować dzięki plikom XML



    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" />


    android:title="Podaj imie"
    android:summary="Podaj imie"
    android:defaultValue=""
    android:inputType="text" />



    zagnieżdżenie preferencji polega na umieszczeniu PreferenceScreen w istniejącym już
    PreferenceScreen, analogicznie jak w przypadku menu podręcznego

    View Slide

  17. 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, ""));
    }
    }

    View Slide

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

    View Slide

  19. 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.

    View Slide