Излъчващи приемници за начинаещи

Да приемем, че имате приложение, което зависи от стабилна интернет връзка. Искате приложението ви да получи известие, когато се промени интернет връзката. Как правиш това? Възможно решение би било услуга, която винаги проверява интернет връзката. Това изпълнение е лошо по различни причини, така че дори няма да го обмислим. Решението на този проблем е Broadcast Receiver и той ще се вслушва в промените, които му кажете. Излъчващият приемник винаги ще получава известие за излъчване, независимо от състоянието на вашето приложение. Няма значение дали приложението ви в момента работи, във фонов режим или изобщо не работи.

Заден план

Излъчващите приемници са компоненти във вашето приложение за Android, които слушат предадени съобщения (или събития) от различни обекти:

  • От други приложения
  • От самата система
  • От вашето приложение

Това означава, че те се извикват, когато е настъпило определено действие, което те са програмирани да слушат (IE, излъчване).

Излъчването е просто съобщение, обвито вътре в обект Intent. Излъчването може да бъде неявно или изрично.

  • Един имплицитно предаването е тази, която не е насочена към вашето приложение, специално, така че не е свойствена за вашата кандидатура. За да се регистрирате за такъв, трябва да използвате IntentFilter и да го декларирате във вашия манифест. Трябва да направите всичко това, защото операционната система Android преминава през всички декларирани филми за намерение във вашия манифест и проверява дали има съвпадение. Поради това поведение неявните излъчвания нямат целеви атрибут. Пример за неявно излъчване би било действие на входящо SMS съобщение.
  • Един изрично предаването е тази, която е насочена специално за вашето приложение на компонент, който е известен предварително. Това се случва поради целевия атрибут, който съдържа името на пакета на приложението или името на клас на компонент.

Има два начина за деклариране на приемник:

  1. Като декларирате такъв във вашия файл AndroidManifest.xml с маркера (наричан още статичен)

Ще забележите, че декларираният по-горе излъчващ приемник има свойство експортирано = ”true” . Този атрибут казва на приемника, че може да приема излъчвания извън обхвата на приложението.

2. Или динамично чрез регистриране на екземпляр с registerReceiver (това, което е известно като контекстно регистрирано)

public abstract Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter);

Изпълнение

За да създадете свой собствен приемник за излъчване, първо трябва да разширите родителския клас BroadcastReceiver и да замените задължителния метод onReceive:

public void onReceive(Context context, Intent intent) { //Implement your logic here }

Събирането на всичко дава резултат:

public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { StringBuilder sb = new StringBuilder(); sb.append("Action: " + intent.getAction() + "\n"); sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n"); String log = sb.toString(); Toast.makeText(context, log, Toast.LENGTH_LONG).show(); } }
⚠️Методът onReceive работи върху основната нишка и поради това изпълнението му трябва да бъде кратко.

Ако се изпълни дълъг процес, системата може да убие процеса, след като методът се върне. За да заобиколите това, помислете за използване на goAsync или планиране на работа. Можете да прочетете повече за планирането на работа в долната част на тази статия.

Пример за динамична регистрация

За да регистрирате приемник с контекст, първо трябва да инстанцирате екземпляр на вашия излъчващ приемник:

BroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();

След това можете да го регистрирате в зависимост от конкретния контекст, който желаете:

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); this.registerReceiver(myBroadcastReceiver, filter);

Не забравяйте да отпишете вашия приемник за излъчване, когато вече не ви е необходим

@Override protected void onStop() { super.onStop(); unregisterReceiver(myBroadcastReceiver); }

Излъчване на събитие

Целта зад излъчването на съобщения от вашето приложение е да му позволите да реагира на събития, когато се случват вътре в него. Помислете за сценарий, при който в една част от кода потребителят изпълнява определено действие и поради това искате да изпълните друга логика, която имате на друго място.

Има три начина за изпращане на предавания:

  1. В sendOrderedBroadcastметод, не забравяйте да изпращате излъчвания само до един приемник наведнъж. Всяко излъчване може от своя страна да предава данни на следващото или да спре разпространението на излъчването към приемниците, които следват
  2. В sendBroadcast е подобен на метода, споменати по-горе, с една разлика. Всички излъчващи приемници получават съобщението и не зависят един от друг
  3. Методът LocalBroadcastManager.sendBroadcast изпраща само излъчвания до приемници, дефинирани във вашето приложение и не надвишава обхвата на вашето приложение . Пример за изпращане на персонализирано излъчване

//giphy.com/gifs/23gUJhHyWkXEwl7UYV/html5

Има неща и неща, на които да обърнете внимание

  • Не изпращайте чувствителни данни чрез неявно излъчване, защото всяко приложение, което го слуша, ще го получи. Можете да предотвратите това, като посочите пакет или прикачите разрешение към излъчването
  • Не започвайте дейности от предаване, получено, тъй като липсва потребителско изживяване. Вместо това изберете да показвате известие.

Следните точки се отнасят до промени в излъчващите приемници, свързани с всяка версия на Android OS (започвайки от 7.0). За всяка версия са настъпили определени ограничения и поведението също се е променило. Имайте предвид тези ограничения, когато мислите за използване на излъчен приемник.

  • 7.0 и по-нови (API ниво 24) - две системни излъчвания са деактивирани, Action_New_Picture и Action_New_Video (но те бяха върнати в Android O за регистрирани приемници)
  • 8.0 и по-нови (API ниво 26) - Повечето неявни излъчвания трябва да бъдат регистрирани динамично, а не статично (във вашия манифест). Можете да намерите излъчванията, които са били в белия списък в тази връзка.
  • 9.0 и по-нови (API ниво 28) - По-малко информация, получена при излъчване на Wi-Fi система и Network_State_Changed_Action.

Промените в Android O са тези, за които трябва да сте най-наясно. Причината за тези промени беше, че това доведе до проблеми с производителността, изтощаване на батерията и нараняване на потребителския опит. Това се случи, защото много приложения (дори и тези, които в момента не се изпълняват) слушаха системна промяна и когато тази промяна се случи, настъпи хаос. Представете си, че всяко приложение, регистрирано в действието, оживява, за да провери дали трябва да направи нещо заради излъчването. Вземете под внимание нещо като състоянието на Wi-Fi, което се променя често и ще започнете да разбирате защо тези промени са настъпили.

Алтернативи на излъчваните приемници

За да улесните навигацията във всички тези ограничения, по-долу е представена разбивка на други компоненти, които можете да използвате при липса на излъчен приемник. Всеки от тях има различна отговорност и случай на употреба, така че опитайте се да очертаете кой отговаря на вашите нужди.

  • LocalBroadcastManager - Както споменах по-горе, това е валидно само за излъчвания във вашето приложение
  • Планиране на работа - Работа може да се изпълни в зависимост от получения сигнал или задействане, така че може да откриете, че излъчването, което слушате, може да бъде заменено със задача. Освен товаJobScheduler, ще гарантира, че работата ви ще завърши, но ще вземе предвид различни системни фактори (време и условия), за да определи кога трябва да работи. Когато създавате работа, ще замените метод, наречен onStartJob . Този метод работи на основната нишка, така че се уверете, че завършва работата си за ограничен период от време. Ако трябва да изпълните сложна логика, помислете за стартиране на фонова задача. Освен това, върнатата стойност за този метод е булева стойност, където true означава, че все още се извършват определени действия, а false означава, че работата е свършена

Ако искате да изпитате от първа ръка радостта и учудването, които са излъчващи приемници, можете да следвате тези връзки към хранилища, които съм създал:

  1. Персонализирано излъчване (с декларация за манифест)
  2. Регистриране на излъчване (без деклариране на такова в манифеста)
  3. LocalBroadcastManager

Излъчено.