1 komentarz

Statusbar notifications – powiadomienia na pasku stanu urządzenia

Sierpień 1, 2011 Notification Podstawowe komponenty Tutoriale

Mechanizmy powiadomień (Notifications) są jednym z podstawowych komponentów systemu (obok Aktywności, Intencji oraz Dostarczycieli treści). Jest to zbiór elementów, które „zaczepiają” użytkownika za pomocą specjalnie do tego przygotowanych mechanizmów. Z większością z nich mamy do czynienia tak naprawdę w każdym urządzeniu mobilnym (niekoniecznie działającym pod kontrolą Androida), aczkolwiek dla dopełnienia formalności poniżej przedstawiam listę elementów, z których mogą korzystać aplikacje w naszym systemie:

  • diody – zarówno wbudowane w obudowę, jak i te pod trackballem
  • wibracje,
  • powiadomienia dźwiękowe,
  • pasek stanu telefonu.

I to właśnie ostatniemu elementowi z powyższej listy chciałbym poświęcić miejsce w dzisiejszym wpisie.

Pod tym adresem natomiast możemy znaleźć snippety pokazujące jak skorzystać z wymienionych wyżej mechanizmów powiadamiających.

Przykładowa aplikacja wykorzystująca notyfikacje

Zbudujemy teraz prostą aplikację wykorzystującą powiadomienia wyświetlane na pasku stanu urządzenia.

Przygotowania

Do zademonstrowania powiadomień wystarczy nam aplikacja z jednym przyciskiem, który będzie je uruchamiał.

public class MainActivity extends Activity {
	private Button btnStartNotification;

	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStartNotification = (Button) findViewById(R.id.btnStartNotification);
        btnStartNotification.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				startNotification();
			}
		});
	}
}

Kod aplikacji

Zaczniemy od przygotowania obiektów odpowiedzialnych za powiadomienia w systemie:

public class MainActivity extends Activity {
	private static final int MY_NOTIFICATION = 1;

	private Button btnStartNotification;
    private NotificationManager notificationManager;
    private Notification notification;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStartNotification = (Button) findViewById(R.id.btnStartNotification);
        btnStartNotification.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				startNotification();
			}
		});
        initNotificationManager();
        initNotification();
	}
}

Stała MY_NOTIFICATION będzie służyła do określenia które powiadomienie chcemy wyświetlić. Dzięki niej w przypadku wyświetlenia kolejnego powiadomienia system będzie wiedział czy ma wyświetlić nowe czy nadpisać aktualne.

Obiekt klasy Notification będzie naszym powiadomieniem, natomiast NotificationManager będzie przekazywał nasze powiadomienie do systemu w celu jego wyświetlenia.

Inicjalizacja powiadomień

Dokonamy teraz inicjalizacji naszych powiadomień:

public class MainActivity extends Activity {
	private static final int MY_NOTIFICATION = 1;

	private Button btnStartNotification;
    private NotificationManager notificationManager;
    private Notification notification;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStartNotification = (Button) findViewById(R.id.btnStartNotification);
        btnStartNotification.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				startNotification();
			}
		});
        initNotificationManager();
        initNotification();
	}

	private void initNotificationManager() {
		notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
	}

	private void initNotification() {
		int icon = R.drawable.icon;
		String tickerText = "My notification";
		long when = 0;
		notification = new Notification(icon, tickerText, when);
	}
}

Jak widać, NotificationManager jest jedną z usług systemowych, którą pobieramy dokładnie tak jak jest to przedstawione w 36 linijce kodu.

Inicjalizacja obiektu Notification zachodząca w metodzie initNotification() tworzy obiekt przekazując mu:

  • ikonę (adres do jej zasobu),
  • tytuł powiadomienia (wyświetlany przez krótką chwilę na pasku stanu)
  • czas, w którym powiadomienie ma być wyświetlone (0 – natychmiast).

Oczywiście moglibyśmy skorzystać z bezargumentowego konstruktora Notification. Wtedy wszystkie powyższe dane ustawialibyśmy poprzez przypisania do konkretnych pól klasy Notification (mających dostęp publiczny, np. notification.icon, notification.when itp.).

Wyświetlanie powiadomień

Pozostało nam już tylko zaimplementowanie metod wyświetlających nasze powiadomienie.

public class MainActivity extends Activity {
	private static final int MY_NOTIFICATION = 1;

	private Button btnStartNotification;
    private NotificationManager notificationManager;
    private Notification notification;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStartNotification = (Button) findViewById(R.id.btnStartNotification);
        btnStartNotification.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				startNotification();
			}
		});
        initNotificationManager();
        initNotification();
	}

	private void initNotificationManager() {
		notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
	}

	private void initNotification() {
		int icon = R.drawable.icon;
		String tickerText = "My notification";
		long when = 0;
		notification = new Notification(icon, tickerText, when);
	}

	private void startNotification() {
		setupNotification();
		notificationManager.notify(MY_NOTIFICATION, notification);
	}

	private void setupNotification() {
		setupNotificationCounter();
		setupNotificationFlags();
		setupNotificationEventInfo();
	}
}

Za wyświetlenie powiadomienia odpowiedzialna jest metoda obiektu NotificationManagernotify(int id, Notification notification). Nim jednak nasza notyfikacja zostanie wyświetlona, powinniśmy ją jeszcze skonfigurować.

Licznik powiadomień

Obiekt Notification posiada pole number, które po ustawieniu obok naszego powiadomienia będzie pokazywało liczbę (np. ilość nieprzeczytanych smsów). Kiedy wartość tego pola będzie ujemna lub równa 0, obok powiadomienia nie wyświetli się nic.

	private void setupNotification() {
		setupNotificationCounter();
		setupNotificationFlags();
		setupNotificationEventInfo();
	}

	private void setupNotificationCounter() {
		notification.number = 3;
	}

Powiadomienie bez licznika:

Z licznikiem:

Flagi powiadomień

Kolejnym ważnym elementem są flagi naszego powiadomienia. Odpowiadają one za kilka różnych ustawień. Oto niektóre z nich:

  • Notification.FLAG_AUTO_CANCEL – sprawia, że powiadomienie znika zaraz po kliknięciu,
  • Notification.FLAG_NO_CLEAR – powiadomienie nie zostanie usunięte po kliknięciu w przycisk Clear/Wyczyść,
  • Notification.FLAG_FOREGROUND_SERVICE – powiadomienie które przychodzi od aktualnie działającego serwisu,
  • Notification.FLAG_ONGOING_EVENT – powiadomienie przychodzące z ciągle jeszcze działającego źródła (oczekujące połączenie telefoniczne).
	private void setupNotification() {
		setupNotificationCounter();
		setupNotificationFlags();
		setupNotificationEventInfo();
	}

	private void setupNotificationCounter() {
		notification.number = 3;
	}

	private void setupNotificationFlags() {
		notification.flags |= Notification.FLAG_AUTO_CANCEL;
	}

Flagi ustawiamy za pomocą sumy logicznej (operator | ). W naszym przypadku wykorzystujemy tylko jedną z nich, sprawiającą, że powiadomienie zniknie zaraz po kliknięciu.

Ustawienia powiadomienia

Na końcu skonfigurujemy najbardziej typowe ustawienia naszego powiadomienia. Wśród nich będą:

  • Tytuł (wyświetlany po rozwinięciu paska stanu),
  • Treść powiadomienia,
  • Intencja uruchamiana po kliknięciu powiadomienia.
	private void setupNotification() {
		setupNotificationCounter();
		setupNotificationFlags();
		setupNotificationEventInfo();
	}

	private void setupNotificationCounter() {
		notification.number = 3;
	}

	private void setupNotificationFlags() {
		notification.flags |= Notification.FLAG_AUTO_CANCEL;
	}

	private void setupNotificationEventInfo() {
		String notificationTitle = "Notification title";
		String notificationText = "Notification text";
		Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.android4devs.pl"));
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
		notification.setLatestEventInfo(this, notificationTitle, notificationText, pendingIntent);
	}

Obiekt PendingIntent stworzony w 69 linijce kodu jest czymś w rodzaju odroczonej Intencji. Może być ona wykonana niezależnie od tego czy nasza aplikacja jest wciąż uruchomiona czy nie. Więcej informacji można znaleźć w dokumentacji tej klasy.

W tym momencie zakończyliśmy konfigurację naszego powiadomienia. Poniżej zrzuty ekranu prezentujące działanie powyższego kodu.

Screeny

Kompletny kod źródłowy

MainActivity.java

package pl.froger.hellonotifications;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	private static final int MY_NOTIFICATION = 1;

	private Button btnStartNotification;
    private NotificationManager notificationManager;
    private Notification notification;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStartNotification = (Button) findViewById(R.id.btnStartNotification);
        btnStartNotification.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				startNotification();
			}
		});
        initNotificationManager();
        initNotification();
	}

	private void initNotificationManager() {
		notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
	}

	private void initNotification() {
		int icon = R.drawable.icon;
		String tickerText = "My notification";
		long when = 0;
		notification = new Notification(icon, tickerText, when);
	}

	private void startNotification() {
		setupNotification();
		notificationManager.notify(MY_NOTIFICATION, notification);
	}

	private void setupNotification() {
		setupNotificationCounter();
		setupNotificationFlags();
		setupNotificationEventInfo();
	}

	private void setupNotificationCounter() {
		notification.number = 3;
	}

	private void setupNotificationFlags() {
		notification.flags |= Notification.FLAG_AUTO_CANCEL;
	}

	private void setupNotificationEventInfo() {
		String notificationTitle = "Notification title";
		String notificationText = "Notification text";
		Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.android4devs.pl"));
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
		notification.setLatestEventInfo(this, notificationTitle, notificationText, pendingIntent);
	}
}

Komentarze (1) Subskrybuj

 

Prześlij komentarz

Zaloguj się lub skorzystaj z profilu:

[rpxlogin redirect="http://www.android4devs.pl" prompt="" style="large"]

Możesz również zostawić komentarz bez rejestracji, korzystając z poniższego formularza:

Musisz być zalogowany aby móc pisać komentarze.