SMB - BroadcastReceiver i notyfikacje

Slides:



Advertisements
Podobne prezentacje
C++ wykład 2 ( ) Klasy i obiekty.
Advertisements

C++ wykład 4 ( ) Przeciążanie operatorów.
Procedury wyzwalane Procedura wyzwalana (ang. trigger) - stanowi kod użytkownika przechowywany wewnątrz bazy i uruchamiany w określonych sytuacjach np.
Programowanie obiektowe
Wzorce.
PROGRAMOWANIE STRUKTURALNE
Podstawy informatyki Wirtotechnologia – Wskaźniki i referencje
Obiektowe metody projektowania systemów Command Pattern.
Struktury.
Systemy operacyjne Wykład nr 5: Wątki Piotr Bilski.

Język Java Wielowątkowość.
Evident – Środki Trwałe
Lekkie metodologie wytwarzania oprogramowania Raport z gry planistycznej Jakub Nowak Przemysław Warzyński.
Podstawy programowania II
Moduł 3: Zarządzanie grupami
Programowanie urządzeń mobilnych – wykład IV
Prezentacja funkcjonalności dziennika e-klasa
Architektura Systemu Źródło:
Telefon przyjazny programistom JAVA – szybkie wprowadzenie
Tworzenie aplikacji mobilnych
Tworzenie aplikacji mobilnych
Tworzenie aplikacji mobilnych
Programowanie obiektowe – zastosowanie języka Java SE
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Wzorce slajdów, animacje, różne orientacje slajdów
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 8.
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Procesy, wątki Program a proces Proces: Przestrzeń adresowa, kod, dane, stos (część pamięci do przechowania zmiennych lokalnych i niektórych adresów) Otwarte.
PROGRAMOWANIE W JAVA Informatyka Stosowana – ROK II / III Laboratoria mgr inż. Krzysztof Bzowski.
Paweł Starzyk Obiektowe metody projektowania systemów
Android - cykl życia aplikacji, przykład prostej aplikacji
Znajdowanie pokoju i wchodzenie do niego Skorzystaj z funkcji wyszukiwania programu Lync w celu znalezienia pokojów, do których masz dostęp. 1.W oknie.
Wykład 4 Dr Aneta Polewko-Klim Dr Aneta Polewko-Klim
Hooks w systemie Windows Autorzy: Paweł Kwiecień, Wojciech Kruczkowski Temat: Modelowanie użytkowników Zadaniem jest stworzenie (lub modyfikacja) systemu,
ASP.NET Dostęp do bazy danych z poziomu kodu Elżbieta Mrówka-Matejewska.
Zarządzanie stanem w aplikacjach ASP.NET Elżbieta Mrówka-Matejewska
Asocjacja,Kompozycja,Agregacja
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
InMoST, Java – przykładowa aplikacja Bartosz.Michalik
Windows Workflow Foundation. WF został wydany wraz z NET Framework 3.0 w 2006 r., a następnie zaktualizowany w NET Framework 3.5. Te dwie pierwsze wersje.
Komunikacja pomiędzy luźno powiązanymi komponentami Mateusz Sionkowski.
Wykład 4 Dr Aneta Polewko-Klim Dr Aneta Polewko-Klim
Programowanie Obiektowe – Wykład 6
Kurs języka C++ – wykład 3 ( )
Wątki, programowanie współbieżne
(według:
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
SMB – Pierwszy projekt Michail Mokkas.
Activity, Intent i przechowywanie danych
Programowanie obiektowe – zastosowanie języka Java SE
Windows Workflow Foundation
SMB Serwisy społecznościowe Facebook API
Aplikacje i usługi internetowe
SMB - Geolokalizacja Michail Mokkas.
PGO Interfejsy Michail Mokkas.
SMB – Procesy i wątki Michail Mokkas.
PGO - Projektowanie i implementacja pierwszych klas
PGO Dziedziczenie Michail Mokkas.
SMB Interfejs graficzny (widoki)
PGO Przeciążanie metod i konstruktorów
PGO Porównywanie obiektów
Zapis prezentacji:

SMB - BroadcastReceiver i notyfikacje Michail Mokkas

Broadcast Receiver Komponent umożliwiający rejestrowanie się do zdarzeń aplikacji lub systemu. Jak tylko dane zdarzenie się odbędzie, wszystkie zarejestrowane do niego „odbiorniki” (receiver) zostaną o tym poinformowane i będą miały możliwość podjęcia akcji. Często służy też jako rodzaj komunikacji pomiędzy kilkoma różnymi aplikacjami lub w obrębie jednej aplikacji.

Broadcast Receiver kont. 1 Odbiornik można rejestrować na dwa sposoby: Statyczny: za pośrednictwem pliku AndroidManifest.xml . Od Oreo, w celu zredukowania procesów, które chodzą w tle zostały dodane ograniczenia dotyczące statycznej rejestracji. Dynamiczny: za pośrednictwem metody Trzeba pamiętać o wyrejestrowaniu, jeżeli przestanie być nam potrzebny: unregisterReceiver(receiver); <receiver android:name="MyBroadcastReceiver“> <intent-filter> <action android:name="com.example.MY_CUSTOM_INTENT“/> </intent-filter> </receiver> registerReceiver(MyBroadcastReceiver mbr, new IntentFilter("com.example.MY_CUSTOM_INTENT"));

Przykład dynamicznej rejestracji public class MainActivity extends Activity { public static final String myIntent = "come.example.smb.myapplication.intent.action.EVENT1"; private MyBroadcastReceiver mbr = new MyBroadcastReceiver(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override protected void onStart(){ super.onStart(); registerReceiver(mbr, new IntentFilter(myIntent)); } @Override protected void onPause(){ super.onPause(); unregisterReceiver(mbr); } }

Przykład statycznej rejestracji <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.might.myapplication"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".OptionsActivity"></activity> <receiver android:name="MyBroadcastReceiver"> <intent-filter> <action android:name="com.example.MY_CUSTOM_INTENT“/> </intent-filter> </receiver> </application> </manifest>

Broadcast Receiver kont. 2 Broadcasty systemowe: android.intent.action.BOOT_COMPLETED android.intent.action.BATTERY_LOW android.intent.action.SCREEN_OFF android.net.wifi.STATE_CHANGE android.provider.Telephony.SMS_RECEIVED android.provider.Telephony.SIM_FULL Mamy możliwość dorabiania własnych. Całą listę dostępnych systemowych rozgłoszeń można znaleźć w pliku: /sdk/platforms/android-XX/data/broadcast_actions.txt

Typy rozgłoszeń Typy rozgłoszeń (broadcasts): Normalne (Normal): wszystkie odbiorniki wykonują akcje w tym samym czasie (wtedy, kiedy otrzymują intencję rozgłoszeniową). Uporządkowane (Ordered): broadcasty przesyłane są do jednego odbiornika. Po ukończeniu jego wykonywanych akcji broadcast przekazywany jest do kolejnego wraz z rezultatem podjętych akcji. Każdy z odbiorników może ukończyć proces uniemożliwiając podejmowanie akcji przez kolejne. O kolejności decyduje atrybut android:priority danego filtru intencji (intent-filter).

Priorytet odbiorników Kolejność, w której odbiorniki będą otrzymywały rozgłoszenia uporządkowane zależy od wartości priorytetu. Ustawia się go za pomocą parametru android:priority (statycznie) lub skorzystania z metody IntentFilter.setPriority() (dynamicznie). Wartość ta powinna być z przedziału: minimum: IntentFilter.SYSTEM_LOW_PRIORITY -1000 maximum: IntentFilter.SYSTEM_HIGH_PRIORITY 1000 domyślna: 0

Priorytet odbiorników kont. 1 Statycznie Dynamicznie <receiver android:name="MyBroadcastReceiver"> <intent-filter android:priority="999"> <action android:name="com.example.smb.myapplication.intent.action.EVENT1“/> </intent-filter> </receiver> @Override protected void onStart(){ super.onStart(); IntentFilter if1 = new IntentFilter(myIntent); if1.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY-1); registerReceiver(mbr, if1); }

Typy rozgłoszeń kont. 1 Typy rozgłoszeń (broadcasts): Zapisujące intencje (Sticky): intencja jest przechowywana po jej rozgłoszeniu. Nowe intencje nadpisują stare pasujące. Przy dynamicznej rejestracji odbiornika wszystkie przechowane intencje, które pasują do jego filtra są do niego rozesłane. Wraz z API 21 zostało potępione (deprecated), ponieważ stwarzało ryzyko naruszenia bezpieczeństwa. Nie zapisujące intencje (Non-Sticky): intencja zostaje usuwana po jej rozgłoszeniu. Wykorzystujące lub niewykorzystujące zezwolenia (Permissions).

Typy rozgłoszeń kont. 2 Rozgłoszenie intencji. private void onClick(View v){ Intent intent1 = new Intent(myIntent); String permission1 = Manifest.permission.READ_SMS; //normal broadcast sendBroadcast(intent1); //ordered broadcast 1 sendOrderedBroadcast(intent1, permission1); //ordered broadcast 2 sendOrderedBroadcast(intent1, permission1, new BroadcastReceiver(){ public void onReceive(Context context, Intent intent){ Toast.makeText(context, "Rezultat:"+getResultData(), Toast.LENGTH_LONG).show(); } },null, 0, null, null); //handler, initiatlCode, initialData, initialExtras }

Broadcast Receiver kont. 3 Cykl życiowy: Obiekt BroadcastReceiver uznawany jest za ważny od początku do końca wykonywania się metody onReceive() Z tego powodu nie możemy wykonywać żadnych asynchronicznych działań, które po ich ukończeniu zwracałyby rezultat do nieaktywnego już BroadcastReceivera (zlikwidowanego przez system). Od API 11 można za pomocą metody goAsync() Nie możemy z jego poziomu rejestrować się do usług (service binding) ani pokazywać dialogów. Alternatywą do dialogów mogą być notyfikacje tworzone za pomocą NotificationManager. Proces wykonujący nasz odbiornik jest uznawany jako pierwszoplanowy.

Zezwolenie na odbiór rozgłoszeń W celu uniemożliwienia otrzymywania rozgłoszonych intencji od wszystkich aplikacji i zaakceptowania tylko wybranych, możliwe jest utworzenie zezwoleń, które powinny te aplikacje posiadać. Alternatywą jest: ustawienie w manifescie, parametru: android:exported=”false” stworzenie LocaLBroadcastManager (nasłuchuje tylko na akcje z tego samego procesu)

Zezwolenia kont. 1 Aby stworzyć nasze własne zezwolenie w AndroidManifest.xml : W <receiver> dodajemy: <permission-group android:name="com.example.my_permissions" android:label="my permissions group" /> <permission android:name="com.example.my_permissions.MY_PERMISSION" android:permissionGroup="com.examples.my_permissions" android:label="my permission"/> <uses-permission android:name="com.example.my_permissions.MY_PERMISSION" /> <receiver android:name="MyBroadcastReceiver" android:permission="com.example.my_permissions.MY_PERMISSION"> <intent-filter> <action android:name="com.example.smb.myapplication.intent.action.EVENT1“ /> </intent-filter> </receiver>

Uruchamianie odbiornika w osobnym procesie W celu uruchomienia odbiornika w osobnym procesie można skorzystać z parametru android:process . Sprawi to, że odbiornik nie będzie zależny od działania naszej aplikacji. <receiver android:name="MyBroadcastReceiver" android:process=":remote"> <intent-filter> <action android:name="com.example.smb.myapplication.intent.action.EVENT1"> </action> </intent-filter> </receiver>

Przykład rozgłoszenia intencji Tworzenie: W naszym Activity dodajemy metodę: W pliku layout naszego Activity dodajemy guzik: public void broadcastIntent(View view){ Intent intent = new Intent(); intent.setAction("com.example.MY_CUSTOM_INTENT"); sendBroadcast(intent); } <Button android:id="@+id/button1" android:onClick="broadcastIntent" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/button_name" />

Przykład odbiornika Tworzenie: public class MyBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent){ Toast.makeText(context, "Intencja otrzymana.", Toast.LENGTH_LONG).show(); } }

Przykład odbiornika kont. 1 Przekazywanie rezultatu. public class Receiver1 extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent){ String tmp = getResultData(); setResultData(tmp+"Data from receiver1"); } }

Przykład odbiornika kont. 2 Anulowanie dalszego rozgłaszania. public class Receiver2 extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent){ if(isOrderedBroadcast()){ abortBroadcast(); } Toast.makeText(context, "Intent received.", Toast.LENGTH_LONG).show(); } }

Przykład odbiornika kont. 3 W pliku AndroidManifest.xml dodajemy do <application> : <receiver android:name="MyBroadcastReceiver" > <intent-filter> <action android:name="com.example.MY_CUSTOM_INTENT" /> </intent-filter> </receiver>

Rezultat przykładu (1)

Przykład 2 Uruchomienie usługi po odpaleniu systemu: public class MyBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent){ Intent service_intent = new Intent(context, MyService.class); context.startService(service_intent); } }

Przykład 2 kont.1 Manifest: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.might.myapplication"> <users-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".OptionsActivity"></activity> <receiver android:name="MyBroadcastReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> </application> </manifest>

PackageManager Możemy wykorzystać PackageManagera w celu wyłączenia jakiegoś statycznie zarejestrowanego odbiornika po jednokrotnym wyłapaniu intencji i wykonaniu metody onReceive(). PackageManager pm = getPackageManager(); ComponentName cn = new ComponentName(getApplicationContext(), MyBroadcastReceiver.class); pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

PackageManager kont. 1 Stany, które można wykorzystać to: COMPONENT_ENABLED_STATE_DEFAULT - stan taki jaki jest opisany w AndroidManifest.xml . COMPONENT_ENABLED_STATE_DISABLED - wyłączony. COMPONENT_ENABLED_STATE_ENABLED - włączony. Zmiana stanu komponentu może sprawić, że zachowanie aplikacji będzie nieprzewidywalne. W tej sytuacji flaga DONT_KILL_APP zapobiega przed likwidacją aplikacji przez system.

Pending intent (oczekujące intencje) Są to swojego rodzaju przepustki, które dana aplikacja może przekazać innej aplikacji umożliwiając w ten sposób otrzymanie przez nią zezwoleń pierwszej w celu wykonania jakichś poleceń. W celu uzyskania PendingIntent musimy użyć jednej z metod: PendingIntent.getActivity() - do uruchomienia aktywności. PendingIntent.getBroadcast() - do rozgłoszenia. PendingIntent.getService() - do uruchomienia usługi. Unieważniamy za pomocą metody cancel() .

Pending Intent kont. 1 Argumenty metod get[Activity/Broadcast/Service](): Context - kontekst aplikacji requestCode - prywatny kod zapytania do uzyskania tego samego pending intentu w przyszłości (np. w celu anulowania za pomocą metody cancel()) intent - jawna intencja (explicit) aktywności jaka ma być uruchomiona flag - flaga: FLAG_CANCEL_CURRENT - jeżeli pending intent już istnieje to istniejący powinien być anulowany przed stworzeniem nowego. FLAG_IMMUTABLE - pending intent powinien być niezmienny. FLAG_NO_CREATE - jeżeli pending intent nie istnieje to zwróc null zamiast tworzyć nowy. FLAG_ONE_SHOT - ten pending intent może być użyty jedynie raz. FLAG_UPDATE_CURRENT - jeżeli pending intent już istnieje to zachowaj go, ale zamień jego dane (extra data) z tymi z nowego.

Notyfikacje System Android umożliwia ukazywanie notyfikacji związanych z aplikacjami na pasku notyfikacji (status bar). Możliwe jest dodanie elementów, które zarządzają dostępnymi aktywnościami, usługami itp. image source: https://developer.android.com/guide/topics/ui/notifiers/notifications

NotificationCompat.Builder Metody klasy NotificationCompat.Builder : setContentTitle() - zmienia treść pierwszej linijki. setContentText() - zmienia treść drugiej linijki. setSmallIcon() - ustawia obrazek, który będzie w niej widoczny (z lewej). setContentIntent() - ustala pending intent, jaki jest wysyłany podczas kliknięcia na notyfikację. setAutoCancel() - notyfikacja znika po kliknięciu w nią. build() - tworzy notyfikację.

NotificationManager Klasa odpowiedzialna za powiadamianie użytkownika o zdarzeniach, jakie mają miejsce. Sposób informowania użytkownika o różnych sprawach, które się wydarzyły w tle. Zarządza: Notyfikacjami (w statusbarze) Lampkami LED Powiadamianiem poprzez oświetlenie tła, odpaleniem dźwięku lub wibracją Metoda notify(int id, Notification notificaition) - publikuje notyfikację w statusbarze (jeżeli identyfikator będzie taki sam to notyfikacje będą się nadpisywać)

Tworzenie notyfikacji Tworzenie (z poziomu Activity): private final String channelID = "channel1"; private int id = 0; public void onClick(View view) { Intent intent = new Intent(this, Main2Activity.class); PendingIntent pendint = PendingIntent.getActivity(this, 0, intent, 0); NotificationCompat.Builder notif = new NotificationCompat.Builder(this, channelID) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(getString(R.string.my_title)) .setContentText(getString(R.string.my_text)) .setContentIntent(pendint) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setAutoCancel(true); NotificationManagerCompat nm = NotificationManagerCompat.from(this); nm.notify(id++, notif.build()); }

Rezultat

Kanały notyfikacji (API 26+) Nasza notyfikacja musi być przydzielona do kanału. Użytnownik może wybrać, które kanały notyfikacji naszej apki go interesują, a które np. blokować. Należy pamiętać, by wywołać metodę zanim wyświetlimy notyfikację np. w onCreate() (jeżeli znajdujemy się w Activity). //API 26+ private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // SDK >= 26 CharSequence name = getString(R.string.my_channel); String description = getString(R.string.my_chan_desc); int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(channelID, name, importance); channel.setDescription(description); NotificationManager nm = getSystemService(NotificationManager.class); nm.createNotificationChannel(channel); } }

Przykład niestandardowej notyfikacji Do stworzenia niestandardowej notyfikacji potrzebujemy: MainActivity.java – klasa głównej aktywności z guzikiem do tworzenia notyfikacji. MyNotification.java – klasa aktywności, która jest uruchomiana po kliknięciu w notyfikację. activity_main.xml – układ MainActivity. activity_my_notification.xml – układ MyNotification. mojanotyfikacja.xml – układ niestandardowej notyfikacji.

Przykład kont. 1 MainActivity.java (part 1)

Przykład kont. 2 MainActivity.java (part 2)

Przykład kont. 3 activity_main.xml

Przykład kont. 4 MyNotification.java

Przykład kont. 5 activity_my_notification.xml

Przykład kont. 6 mojanotyfikacja.xml

Rezultat