Powiadomienia

Powiadomienie (notification) jest wiadomością, którą wysyłamy z bieżącej aplikacji. Ta wiadomość jest wyświetlana przez system Android poza interfejsem użytkownika aplikacji, z której została wysłana. Po wysłaniu, powiadomienie najpierw wyświetla się jako mała ikona w obszarze powiadomień. Użytkownik będzie mógł zobaczyć szczegóły dotyczące tego powiadomienia przez rozwinięcie szuflady powiadomień.

Aplikacja, która wykorzystuje system powiadomień musi mieć ustawiony dostęp do tej funkcji. Dostęp przydzielany jest w pliku manifestu

Wskazówka:


<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

Powiadomienia (notyfikacje) występują w różnych formach ? jako ikona na pasku statusu, szczegółowa wiadomość w panelu notyfikacji, czy odznaka na ikonie aplikacji.

NotificationCompat

NotificationCompat to klasa dostarczająca metod do pracy z powiadomieniami. Pozwala wygodnie definiować elementy powiadomienia. Podstawowe powiadomienie wymaga przygotowania trzech elementów:

Wskazówka:


val nota = NotificationCompat.Builder(this,idKanalu)
    .setContentTitle("UWAGA!")
    .setContentText("Przyszła nowa wiadomość")
    .setSmallIcon(android.R.drawable.ic_dialog_info)
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .build()

Istnieje możliwość użycia grupy opcji dodatkowych, które nie są wymagane.

NotificationManager

NotificationManager klasa pośrednicząca przy wysyłaniu powiadomienia. Przed wyświetleniem powiadomienia pobierana jest referencja (odwołanie) do klasy za pomocą funkcji getSystemService ( String ). Przed wyświetleniem powiadomienia należy przypisać indeks powiadomienia.

Wskazówka:


val notificationManager=
    getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val id = 1
notificationManager.notify(id,nota)

Rola kanałów

W systemie Android 8.0 (poziom API 26) i nowszych wszystkie powiadomienia muszą być powiązane z kanałem, w przeciwnym razie powiadomienia nie będą wyświetlane.

Więcej o tworzeniu kanałów czytaj

Kanał powiadomień należy tworzyć przed użyciem dowolnego powiadomienia, które z tym kanałem będą powiązane. Przykład podstawowych instrukcji tworzących kanał.

Wskazówka:


//Rób kanał dla API 26+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val nazwa = "Kanał powiadomień"
    val przeznaczenie = "Testowy kanał powiadomień"
    val waznoscZnaczenia = NotificationManager.IMPORTANCE_DEFAULT
    val channel = NotificationChannel(idKanalu, nazwa, waznoscZnaczenia).apply {
        description = przeznaczenie
    }
   // rejestruj kanał w systemie
    val notificationManager: NotificationManager =
        getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.createNotificationChannel(channel)
}

Układ głównej aktywności

Układ tworzonej aktywności jest bardzo prosty. Składa się z kilku kontrolek typu Button umieszczonych jedna pod drugą. Patrz zrzut ekranu

Android Studio tworzenie powiadomień

Kolejne klawisze będą służyć do wysłania czterech wersji powiadomień

Jak utworzyć kanał powiadomień?

Piszemy funkcję tworzącą prosty kanał powiadomień dla naszej aplikacji. Korzystamy z informacji podanych powyżej. Przykładowy kod wygląda jak poniżej.

Wskazówka:


private fun robKanal() {
    //Rób kanał dla API 26+
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val nazwa = "Kanał powiadomień"
        val przeznaczenie = "Testowy kanał powiadomień"
        val waznoscZnaczenia = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(idKanalu, nazwa, waznoscZnaczenia).apply {
            description = przeznaczenie
        }
// rejestruj kanał w systemie

        val notificationManager: NotificationManager =
            getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

W kodzie głównej klasy projektu dodajemy identyfikator kanału, a w metodzie onCreate() wywołujemy funkcję tworzącą kanał

Wskazówka:


class MainActivity : AppCompatActivity() {
    //unikalny idetyfikator kanału
    val idKanalu="kanal_1"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        robKanal()
    }

Powiadomienia proste

Przypisanie ikony ułatwia standardowy zasób ikon systemu Androida

Android Studio ikona powiadomienia

Możesz skorzystać z narzędzia New/Image Asset, które pozwala zaimportować do projektu dowolne pliki graficzne. Dla ikon najlepsze są pliki z grafiką wektorową.

Android Studio NotificationCompat.Builder

Przykładowy kod funkcji prostego powiadomienia

Wskazówka:


fun PowiadomienieProste(){
    val nota = NotificationCompat.Builder(this,idKanalu)
        .setContentTitle("UWAGA!")
        .setContentText("Przyszła nowa wiadomość")
        .setSmallIcon(android.R.drawable.ic_dialog_info)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .build()
    val notificationManager=
        getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    val id = 1
    notificationManager.notify(id,nota)
}

Utworzoną funkcję wywołujemy w zdarzeniu kliknięcia w pierwszej kontrolce typu Button

Wskazówka:


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    robKanal()
    val bt1=findViewById<Button>(R.id.button1)
    bt1.setOnClickListener {
        PowiadomienieProste()
    }
}

Po wybraniu klawisza w górnym pasku pojawi się ikona powiadomienia. Patrz poniższy obraz

Android Studio simple NotificationCompat.Builder

Kliknij na ikonie i rozciągnij w dół. System wyświetli listę ostatnich powiadomień.

Android Studio Notification

Powiadomienia z akcją

Ten rodzaj powiadomień umożliwia wykonanie dodatkowych funkcji niekoniecznie związanych z bieżącą aplikacją. Powiadomienie z akcją oprócz tytułu, treści zawiera przycisk akcji. W tym przykładzie przy pomocy powiadomienia uruchomimy inną aplikację, którą będzie Google Maps.

Kolejno zostaną wykonane takie kroki

Kod funkcji tworzącej powiadomienie z akcją. Akcja to otwarcie aplikacji Google Maps, której intencję przygotowano z godnie zasadami podanymi w temacie Uruchomienie innej aplikacji

Wskazówka:


fun powiadomienie_z_Akcja(){
    val celMapaGoogle= Uri.parse("geo:50.0135833,20.9174879")
    val intencja= Intent(Intent.ACTION_VIEW, celMapaGoogle)
    intencja.setPackage("com.google.android.apps.maps")
    val pIntent=PendingIntent.getActivity(this,
        0, intencja,PendingIntent.FLAG_UPDATE_CURRENT)
    val akcja=NotificationCompat.Action.Builder(
        android.R.drawable.sym_action_chat,
        "Otwórz", pIntent)
        .build();
    val nota = NotificationCompat.Builder(this,idKanalu)
        .setContentTitle("UWAGA!")
        .setContentText("W podanej lokalizacji doszło do niesamowitego wydarzenia:)")
        .setSmallIcon(R.drawable.ic_powiadomienie_akcja)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .addAction(akcja)
        .build()
    val notificationManager=
        getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    val id = 2
    notificationManager.notify(id,nota)
}

Utworzoną funkcję wywołamy w zdarzenie kliknięcia w drugą kontrolkę Button

Wskazówka:


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    robKanal()
    val bt1=findViewById<Button>(R.id.button1)
    bt1.setOnClickListener {
        PowiadomienieProste()
    }
    val bt2=findViewById<Button>(R.id.button2)
    bt2.setOnClickListener {
        powiadomienie_z_Akcja()
    }
}

Skompiluj program i sprawdź działanie. Prawidłowo działająca aplikacja przy wysłaniu drugiego powiadomienia- patrz ikona powiadomienia (na poniższym rysunku)

Android Studio Notification

.. o takiej postaci

Android Studio Notification

Kliknij w Otwórz. Akcja z powiadomienia otworzy aplikację Google Maps

Android Studio Notification addAction

Powiadomienie z większą ilością treści

W powyższym przykładzie można zauważyć, że nie cała treść powiadomienia jest pokazywana. Aby to zmienić, należy przypisać styl z większa ilością treści do tworzonego powiadomienia.

setStyle(NotificationCompat.BigTextStyle().bigText(tresc))

Skorzystamy z poprzedniego kodu, który nieznacznie zmodyfikujemy.

Wskazówka:


fun powiadomienie_z_Akcja_dluga_tresc(){
    val celMapaGoogle= Uri.parse("geo:50.0135833,20.9174879")
    val intencja= Intent(Intent.ACTION_VIEW, celMapaGoogle)
    intencja.setPackage("com.google.android.apps.maps")
    val pIntent=PendingIntent.getActivity(this,
        0, intencja,PendingIntent.FLAG_UPDATE_CURRENT)
    val akcja=NotificationCompat.Action.Builder(
        android.R.drawable.sym_action_chat,
        "Otwórz", pIntent)
        .build();
    val tresc="W podanej lokalizacji doszło do niesamowitego wydarzenia." +
            "Nieznani goście we wskazanym miejscu zamówili bardzo duże ilości jedzenia." +
            "Nie płacąc rachunku rozdali potrzebującym"
    val nota = NotificationCompat.Builder(this,idKanalu)
        .setContentTitle("UWAGA!")
        .setStyle(NotificationCompat.BigTextStyle().bigText(tresc))
        .setSmallIcon(R.drawable.ic_powiadomienie_akcja)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .addAction(akcja)
        .build()
    val notificationManager=
        getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    val id = 2
    notificationManager.notify(id,nota)
}

Nowe powiadomienie wywołamy po kliknięciu w kolejną kontrolkę typu Button

Wskazówka:


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    robKanal()
    val bt1=findViewById<Button>(R.id.button1)
    bt1.setOnClickListener {
        PowiadomienieProste()
    }
    val bt2=findViewById<Button>(R.id.button2)
    bt2.setOnClickListener {
        powiadomienie_z_Akcja()
    }
    val bt3=findViewById<Button>(R.id.button3)
    bt3.setOnClickListener {
        powiadomienie_z_Akcja_dluga_tresc()
    }
}

Efektem działania jest poniższa ilustracja.

Android Studio Notification addAction

Powiadomienie z dużą ilustracją

Innym przykładem wykorzystania stylu powiadomienia jest zastosowanie powiadomienia z dużym obrazem. Jeżeli obraz umieszczony jest w zasobach projektu, to po pobraniu należy go przekonwertować na bitmapę (obiekt klasy Bitmap)

Wskazówka:


//konwertuj obraz z zasobów na bitmapę
val obraz:Bitmap = BitmapFactory.decodeResource(
           applicationContext.resources,R.drawable.anglia_holandia_1664_67
         )

Użycie stylu z dużym obrazem wymaga jego użycia BigPictureStyle() patrz poniższy kod

Wskazówka:


fun Powiadomienie_z_Obrazem(){
    //konwertuj obraz z asobów na bitmapę
    val obraz:Bitmap = BitmapFactory.decodeResource(
               applicationContext.resources,R.drawable.anglia_holandia_1664_67
             )
    val nota = NotificationCompat.Builder(this,idKanalu)
        .setContentTitle("UWAGA!")
        .setContentText("Przyszła nowa wiadomość")
        .setSmallIcon(R.drawable.powiadomienie)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setLargeIcon(obraz)
        .setStyle(NotificationCompat.BigPictureStyle()
            .bigPicture(obraz)
         )
        .build()
    val notificationManager=
        getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    val id = 1
    notificationManager.notify(id,nota)
}

Praktycznie jest to powielenie wcześniejszych rozwiązań. Utworzona funkcję wywołamy w zdarzeniu kliknięcia w kolejnej kontrolce Button. Patrz bt4

Wskazówka:


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    robKanal()
    val bt1=findViewById<Button>(R.id.button1)
    bt1.setOnClickListener {
        PowiadomienieProste()
    }
    val bt2=findViewById<Button>(R.id.button2)
    bt2.setOnClickListener {
        powiadomienie_z_Akcja()
    }
    val bt3=findViewById<Button>(R.id.button3)
    bt3.setOnClickListener {
        powiadomienie_z_Akcja_dluga_tresc()
    }
    val bt4=findViewById<Button>(R.id.button4)
    bt4.setOnClickListener {
        Powiadomienie_z_Obrazem()
    }
}

Po uruchomieniu aplikacji, wysłaniu tego typu powiadomienia zobaczymy monit z powiadomieniem wraz z ikoną przesłanego obrazu.

Android Studio Notification BigPictureStyle

Po kliknięciu w tak zwanego ptaszka, powiadomienie się rozwinie do pełnego wymiaru.

Android Studio Notification BigPictureStyle

Zagadnienie powiadomień w środowisku Android jest bardzo obszerne. Tu pokazałem podstawowe rodzaje powiadomień, a w zasadzie ich szablony.

Pełny kod rozwiązania

Wskazówka:


import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Build
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import android.net.Uri
import android.widget.RemoteViews


class MainActivity : AppCompatActivity() {
    //unikalny idetyfikator kanału
    val idKanalu="kanal_1"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        robKanal()
        val bt1=findViewById<Button>(R.id.button1)
        bt1.setOnClickListener {
            PowiadomienieProste()
        }
        val bt2=findViewById<Button>(R.id.button2)
        bt2.setOnClickListener {
            powiadomienie_z_Akcja()
        }
        val bt3=findViewById<Button>(R.id.button3)
        bt3.setOnClickListener {
            powiadomienie_z_Akcja_dluga_tresc()
        }
        val bt4=findViewById<Button>(R.id.button4)
        bt4.setOnClickListener {
            Powiadomienie_z_Obrazem()
        }
    }
    fun PowiadomienieProste(){
        val nota = NotificationCompat.Builder(this,idKanalu)
            .setContentTitle("UWAGA!")
            .setContentText("Przyszła nowa wiadomość")
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()
        val notificationManager=
            getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        val id = 1
        notificationManager.notify(id,nota)
    }
    fun powiadomienie_z_Akcja(){
        val celMapaGoogle= Uri.parse("geo:50.0135833,20.9174879")
        val intencja= Intent(Intent.ACTION_VIEW, celMapaGoogle)
        intencja.setPackage("com.google.android.apps.maps")
        val pIntent=PendingIntent.getActivity(this,
            0, intencja,PendingIntent.FLAG_UPDATE_CURRENT)
        val akcja=NotificationCompat.Action.Builder(
            android.R.drawable.sym_action_chat,
            "Otwórz", pIntent)
            .build();
        val nota = NotificationCompat.Builder(this,idKanalu)
            .setContentTitle("UWAGA!")
            .setContentText("W podanej lokalizacji doszło do niesamowitego wydarzenia:)")
            .setSmallIcon(R.drawable.ic_powiadomienie_akcja)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .addAction(akcja)
            .build()
        val notificationManager=
            getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        val id = 2
        notificationManager.notify(id,nota)
    }
    fun powiadomienie_z_Akcja_dluga_tresc(){
        val celMapaGoogle= Uri.parse("geo:50.0135833,20.9174879")
        val intencja= Intent(Intent.ACTION_VIEW, celMapaGoogle)
        intencja.setPackage("com.google.android.apps.maps")
        val pIntent=PendingIntent.getActivity(this,
            0, intencja,PendingIntent.FLAG_UPDATE_CURRENT)
        val akcja=NotificationCompat.Action.Builder(
            android.R.drawable.sym_action_chat,
            "Otwórz", pIntent)
            .build();
        val tresc="W podanej lokalizacji doszło do niesamowitego wydarzenia." +
                "Nieznani goście we wskazanym miejscu zamówili bardzo duże ilości jedzenia." +
                "Nie płacąc rachunku rozdali potrzebującym"
        val nota = NotificationCompat.Builder(this,idKanalu)
            .setContentTitle("UWAGA!")
            .setStyle(NotificationCompat.BigTextStyle().bigText(tresc))
            .setSmallIcon(R.drawable.ic_powiadomienie_akcja)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .addAction(akcja)
            .build()
        val notificationManager=
            getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        val id = 2
        notificationManager.notify(id,nota)
    }

    fun Powiadomienie_z_Obrazem(){
        //konwertuj obraz z asobów na bitmapę
        val obraz:Bitmap = BitmapFactory.decodeResource(
                   applicationContext.resources,R.drawable.anglia_holandia_1664_67
                 )
        val nota = NotificationCompat.Builder(this,idKanalu)
            .setContentTitle("UWAGA!")
            .setContentText("Przyszła nowa wiadomość")
            .setSmallIcon(R.drawable.powiadomienie)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setLargeIcon(obraz)
            .setStyle(NotificationCompat.BigPictureStyle()
                .bigPicture(obraz)
             )
            .build()
        val notificationManager=
            getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        val id = 1
        notificationManager.notify(id,nota)
    }

    private fun robKanal() {
        //Rób kanał dla API 26+
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val nazwa = "Kanał powiadomień"
            val przeznaczenie = "Testowy kanał powiadomień"
            val waznoscZnaczenia = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(idKanalu, nazwa, waznoscZnaczenia).apply {
                description = przeznaczenie
            }
            // rejestruj kanał w sytsemie
            val notificationManager: NotificationManager =
                getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}
Układ okresowy- kod qr
Układ okresowy

Układ okresowy pierwiastków- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Alkomat- wirtualny test kod qr
Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Taklarz- olinowanie stałe kod qr
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz