Broadcast сообщение что это

Обновлено: 30.06.2024

Для чего нужны Broadcast Receivers?

Допустим, у вас есть приложение, которое зависит от постоянного интернет-соединения. Вы хотите, чтобы ваше приложение получало уведомление при изменении интернет-соединения. Как это сделать? Возможным решением будет сервис, который всегда проверяет интернет-соединение. Эта реализация плоха по разным причинам, поэтому мы не будем ее рассматривать. Решением этой проблемы является широковещательный приемник (Broadcast Receiver), который прослушивает изменения, о которых вы сообщаете. Получатель трансляции всегда будет получать уведомления о трансляции, независимо от состояния вашего приложения. Неважно, работает ли ваше приложение в фоновом режиме или вообще не работает.

Теория Broadcast Receivers

  • Из других приложений
  • Из самой системы
  • Из вашего приложения

Это означает, что они вызываются, когда происходит определенное действие, которое они запрограммированы на прослушивание, например, трансляция (broadcast).

Есть два способа объявить приемник:

1.Объявив его в файле AndroidManifest.xml с тегом (также называемый статическим способом):

Реализация Broadcast Receivers

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

Собрав все вместе, получим:

Метод onReceive выполняется в главном потоке, и поэтому его выполнение должно быть кратким.

Если выполняется долгий процесс, система может завершить процесс после возврата метода. Чтобы обойти это, рассмотрите возможность использования goAsync или планировщиков заданий (scheduling a job). Вы можете прочитать больше об этом в нижней части этой статьи.

Пример динамической регистрации

Чтобы зарегистрировать приемник с контекстом, вам сначала нужно создать экземпляр вашего широковещательного приемника:

Затем вы можете зарегистрировать его в зависимости от конкретного контекста, который вы хотите:

Первый параметр для IntentFilter — это строка, представляющая действие.

Не забудьте отменить регистрацию вашего вещательного приемника, когда он вам больше не нужен

Трансляция события

Есть три способа отправки трансляций:

На что обратить внимание

  • Не отправляйте конфиденциальные данные через неявную трансляцию, потому что любое приложение, прослушивающее их, получит их. Вы можете предотвратить это, указав пакет или добавив разрешение на трансляцию.
  • Не запускайте активити из полученной трансляции, так как пользовательский опыт отсутствует. Выберите для отображения уведомления вместо этого.

Изменения в новых версиях

Следующие пункты относятся к изменениям в широковещательных приемниках, относящихся к каждой версии ОС Android (начиная с 7.0). Для каждой версии были установлены определенные ограничения, а также изменилось поведение. Помните об этих ограничениях, думая об использовании Broadcast Receivers.

Альтернативы Broadcast Receivers

Чтобы упростить навигацию по всем этим ограничениям, ниже приводится разбивка других компонентов, которые можно использовать при отсутствии широковещательного приемника. У каждого из них своя ответственность и свой вариант использования, поэтому постарайтесь определить, какой из них отвечает вашим потребностям.

  • LocalBroadcastManager — Как я уже упоминал выше, это действительно только для трансляций в вашем приложении
  • Scheduling A Job (Планирование задания) — задание может быть запущено в зависимости от полученного сигнала или триггера, поэтому вы можете обнаружить, что прослушиваемая трансляция может быть заменена заданием. Кроме того, JobScheduler гарантирует, что ваша работа будет завершена, но он будет учитывать различные системные факторы (время и условия), чтобы определить, когда он должен работать. При создании задания вы переопределите метод с именем onStartJob. Этот метод выполняется в основном потоке, поэтому убедитесь, что он завершает свою работу за ограниченное время. Если вам нужно выполнить сложную логику, подумайте о запуске фоновой задачи. Кроме того, возвращаемое значение для этого метода является логическим, где true означает, что определенные действия все еще выполняются, а false означает, что задание выполнено.

Ссылки на исходники

Если вы хотите из первых рук испытать радость и удивление, которые получают приемники вещания, вы можете перейти по этим ссылкам на репозитории, которые я настроил:

Полный список системных событий можно посмотреть в файле BROADCAST_ACTION.TXT в Android SDK.

Объявление в манифесте

Алгоритм объявления приёмника состоит из двух шагов:

Создать класс, расширяющий базовый класс BroadcastReceiver и реализовать в нём метод обратного вызова onReceive() .

Добавить элемент в манифест. При этом с помощью intent-фильтров нужно объявить события, на которые подписывается этот приёмник. Они могут быть как системные, так и пользовательские (как в данном случае).

Алгоритм объявления приёмника состоит из трёх шагов:

Создать класс, расширяющий базовый класс BroadcastReceiver и реализовать в нём метод обратного вызова onReceive() . Создать экземпляр этого класса.

Создать intent-фильтр и зарегистрировать приёмник, вызвав метод registerReceiver(BroadcastReceiver, IntentFilter) .

Отменить регистрацию приёмника при помощи метода unregisterReceiver(android.content.BroadcastReceiver) .

Общий принцип работы

В период выполнения метода onReceive() приёмник считается процессом переднего плана, поэтому система будет поддерживать выполнение этого процесса. Но как только ваш код вернётся из onReceive() , приёмник перестаёт быть активным, то есть его приоритет становится низким и система может его уничтожить в любое время.

По этой причине не следует запускать длительные фоновые потоки из приёмника: они, как и приёмник, для системы являются неактивными и уничтожаются вместе с ним.

Есть несколько способов, чтобы этого избежать:

    . Как правило приёмники могут работать до 10 секунд. Если же требуется немного больше времени, но не более 30 секунд, то следует использовать goAsync() ;, Service или JobIntentService . Данные системные средства должны использоваться, когда требуется выполнить более длительную работу.

Для использования этого метода нужно зарегистрировать приёмник с помощью LocalBroadcastManager .

Если LocalBroadcastManager не импортируется, то следует добавить зависимость:

В версии 1.1.0-alpha01 Google признали LocalBroadcastManager устаревшим (deprecated).

Установка разрешений

Пользовательские разрешения добавляются в манифест при помощи элемента

Допустим, у вас в манифесте объявлен приёмник с разрешением:

Или вы зарегистрировали приёмник с разрешением в контексте:

Полезные ссылки

Практическая часть показана в отдельной статье.

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

Зарегистрировать экземпляр класса BroadcastReceiver можно динамически в коде или статически в манифесте.

Если регистрация была сделана через манифест, приложение не обязано работать, чтобы ваш приёмник среагировал на трансляцию намерения. Приложение запустится автоматически, когда подходящие намерение будет транслировано. Система сама сканирует содержимое манифеста всех приложений и делает за нас всю работу. Это хорошее решение, позволяющее экономить ресурсы. Такой подход позволяет создавать приложения, способные реагировать на события даже после завершения или принудительного завершения.

Динамическая регистрация происходит с помощью метода Context.registerReceiver().

Перед этим создаётся класс, расширяющий базовый класс BroadcastReceiver и реализуется метод обратного вызова onReceive() обработчика событий.

Когда программа возвращается из метода onReceive(), приёмник становится неактивным и система полагает, что работа объекта BroadcastReceiver закончена. Процесс с активным широковещательным получателем защищён от уничтожения системой. Однако процесс, содержащий неактивные компоненты, может быть уничтожен системой в любое время, когда память, которую он потребляет, будет необходима другим процессам.

В частности, вы не можете отобразить диалог или осуществить связывание со службой внутри экземпляра BroadcastReceiver. Для первого случая необходимо вместо этого использовать методы класса NotificationManager. Во втором случае можно использовать вызов метода Context.startService(), чтобы послать команду для запуска службы.

Решение этой проблемы возможно, если запустить в методе onReceive() отдельную службу вместе с BroadcastReceiver и позволить службе выполнять задание, чтобы сохранить содержание процесса активным в течение всего времени вашей операции.

Это может быть полезным, когда приёмник используется для обновления элементов пользовательского интерфейса внутри активности, запуска служб или уведомления через NotificationManager. В таких случаях вы можете отменять регистрацию широковещательного приёмника, если активность не отображается на экране или находится в неактивном состоянии.

В коде программы можете написать приблизительно такой код (обычно используют метод onResume()):

Для отмены регистрации используется метод unregisterReceiver() в контексте приложения, передавая ему в качестве параметра экземпляр широковещательного приёмника (обычно в методе onPause()):

Приёмники системных событий

Следующий список показывает некоторые из встроенных действий, представленных как константы в классе Intent, которые используются для того, чтобы проследить изменения состояния устройства:

  • ACTION_BOOT_COMPLETED — передаётся один раз, когда устройство завершило свою загрузку. Требует разрешения RECEIVE_BOOT_COMPLETED
  • ACTION_CAMERA_BUTTON — передаётся при нажатии пользователем клавиши Camera
  • ACTION_DATE_CHANGED и ACTION_TIME_CHANGED - запускаются при изменении даты или времени на устройстве вручную пользователем
  • ACTION_SCREEN_OFF и ACTiON_SCREEN_ON — передаются, когда экран выключается или включается
  • ACTION_TIMEZONE_CHANGED — передаётся при изменении текущего часового пояса

Типы трансляций

Есть три способа отправки трансляций

Если важно, чтобы приёмники получали намерения в определённом порядке или могли влиять на транслируемое намерение, можно использовать метод sendOrderedBroadcast():

Ограничения в Android 8.0 Oreo (API 26)

В качестве замены для некоторых случаев подойдёт JobScheduler.

Ограничения в Android 9.0 Pie (API 28)

Стало доступно меньше информации, получаемой при трансляции системы Wi-Fi и Network_State_Changed_Action.

Multicast (мультикаст) – процесс отправки пакета от одного хоста к некоторой ограниченной группе хостов.

Unicast

Тип передачи данных Unicast (индивидуальный) используется для обычной передачи данных от хоста к хосту. Способ Unicast работает в клиент-серверных и пиринговых (peer-to-peer, от равного к равному) сетях.

В unicast пакетах в качестве IP адреса назначения используется конкретный IP адрес устройства, для которого этот пакет предназначен. IP адрес конкретного устройства состоит из порции адреса сети (в которой находится это устройство) и порции адреса хоста (порции, определяющей это конкретное устойчиво в его сети). Это все приводит к возможности маршрутизации unicast пакетов по всей сети.

Multicast и broadcast пакеты, в отличие от unicast пакетов, имеют свои собственные специальные (зарезервированные) IP адреса для использования их в заголовке пакетов в качестве пункта назначения. Из-за этого, broadcast пакеты в основном ограничены пределами локальной сети. Multicast трафик также может быть ограничен границами локальной сети, но с другой стороны также может и маршрутизироваться между сетями.

В IP сетях unicast адрес является адресом, то есть адресом конечного устройства (например, компьютера). Для типа передачи данных unicast, адреса хостов назначаются двум конечным устройствам и используются (эти адреса) как IP адрес источника и IP адрес получателя.

В течение процесса инкапсуляции передающий хост размещает свой IP адрес в заголовок unicast пакета в виде адреса источника, а ИП адрес принимающего хоста размещается в заголовке в виде адреса получателя. Используя эти два IP адреса, пакеты unicast могут передаваться через всю сеть (т.е. через все подсети).

Multicast

  • видео и аудио рассылка
  • обмен информацией о маршрутах, используемый в маршрутизируемых протоколах.
  • распространение программного обеспечения
  • ленты новостей

Multicast клиенты

Хосты, которые хотят получить определенные multicast данные, называются multicast клиентами. Multicast клиенты используют сервисы инициированные (начатые) клиентскими программами для рассылки multicast данных группам.

Каждая multicast группа представляет собой один multicast IP адрес назначения. Когда хост рассылает данные для multicast группы, хост помещает multicast IP адрес в заголовок пакета (в раздел пункта назначения).

Broadcast (Широковещание)

Из-за того, что тип передачи broadcast используется для отправки пакетов ко всем хостам в сети, пакеты использую специальный broadcast IP адрес. Когда хост получает пакет, в заголовке которого в качестве адреса получателя указан broadcast адрес, он обрабатывает пакет так, как будто это unicast пакет.

Когда хосту необходимо передать какую-то информацию всем хостам в сети используется способ передачи данных broadcast. Еще когда адрес специальных сервисов (служб) или устройств заранее неизвестен, то для обнаружения также используется broadcast (широковещание).

  • создание карты принадлежности адресов верхнего уровня к нижним (например, какой IP адрес на конкретном устройстве со своим MAC адресом)
  • запрос адреса (в качестве примера можно взять протокол ARP)
  • протоколы маршрутизации обмениваются информацией о маршрутах (RIP, EIGRP, OSPF)

Когда хосту нужна информация, он отправляет запрос на широковещательный адрес. Все остальные хосты в сети получат и обработают этот запрос. Один или несколько хостов вложат запрашиваемую информацию и ответят на запрос. В качестве типа передачи данных, отвечающие на запрос будут использовать unicast.

В отличие от unicast передачи, где пакеты могут быть маршрутизированы через всю сеть, broadcast пакеты, как правило, ограничиваются локальной сетью. Это ограничение зависит от настройки маршрутизатора, который ограничивает сеть и следит за типом широковещания (broadcast).

Существует два типа broadcast передачи данных: направленное широковещание и ограниченное широковещание.

Направленный broadcast (направленное широковещание)

Направленный broadcast отправляется всем хостам какой-то конкретной сети. Этот тип широковещания удобно использовать для отправки broadcast трафика всем хостам за пределами локальной сети.

Ограниченный broadcast (ограниченное широковещание)

Ограниченный broadcast используется для передачи данных всем хостам в локальной сети. В такие пакеты в качестве пункта назначения вставляется IP адрес 255.255.255.255. Маршрутизаторы такой широковещательный трафик не передают. Пакеты, переданные ограниченным broadcast будут распространяться только в локальной сети. По этой причине локальные сети IP также называют широковещательным доменом (broadcast domain). Маршрутизаторы образуют границу для широковещательного домена. Без границы пакеты бы распространялись по всей сети, каждому хосту, уменьшая быстродействие сетевых устройств и забивая пропускную способность каналов связи.

Приведу пример ограниченного broadcast: хост находится внутри сети 172.16.5.0/24 и хочет передать пакет всем хостам в его сети. Используя в качестве пункта назначения IP адрес 255.255.255.255, он отправляет широковещательный пакет. Этот пакет примут и обработают все хосты только в этой локальной сети (172.16.5.0/24).

Я пытался через telnet, netcat, ни там ни там не получилось, так-же заметил что порт надо, порт любой? Или я вобше совсем что-то не так делаю и понимаю? Может оно вобше на другом уровне работает где нету понятия порт.

Так-же хотелось бы знать как принимать все что идет по broadcast-у.

P.S: Я просто юзерь и хочу посмотреть как оно работает, прошу не судить строго). Спасибо.)

  • Вопрос задан более трёх лет назад
  • 6454 просмотра

Простой 7 комментариев

1. Как именно вы пытались это делать? У вас только слова - ни логов, ни примеров команд.
2. Какие устройства подключены к роутеру, как вы проверяли что ничего не работает?

MegaCraZy6

Saboteur, ну пытался сделать так чтоб слушать широковещательный канал.
У меня адреса роутера 192.168.0.1, вот я и решил что тот канал на 192.168.0.255
netcat 192.168.0.255 1500

MegaCraZy6

MegaCraZy6

Saboteur, Подключено две виртуальных машины на Линуксе, компьютер мой, и мобилка на крайняк,

Там адреса устройств 192.168.0.100, 192.168.0.101 и так далее

MegaCraZy6

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

П.С: сначала исполнял команду чтоб слушать.

Так-же забавно решил немного поиграться с коммандами а именно:

Слушать:
netcat -u -l 0.0.0.0 -p 4000


192.168.0.105 - Listener
192.168.0.100 - Sender

Вот такое вот я нашел, не понимаю почему не работае совсем никак если что на всех виртуальных машинах, и на физическом ПК стоит Debian

похоже баг в самом nc вашей версии debian

Nanto

Broadcast-адрес -- это широковещательный адрес вашей сети, а роутер тут ни при чём. Всё, что будет отправлено на этот адрес, будет получено всеми хостами данной подсети.
В локальных сетях используется для технических нужд, таких как arp и других подобных. Совершенно непонятно, зачем туда что-то отправлять вручную.

Если интересно, какие широковещательные пакеты ходят в сети -- просто посмотрите через Wireshark то, что пересылается на этот адрес.

MegaCraZy6

Broadcast - это вид передачи данных. Почитайте, что такое unicast, multicast - возможно тогда вы сообразите, что такое тип(метод или т.п.) передачи данных и как работает. Хотите запустить broadcast пакет - вросто включите на вашей сетевой карте получение адреса автоматически, и ваша сетевая сама отправит пакет на broadcast адрес в поисках DHCP-сервера. Т.е. broadcast - это просто отправка пакета, с абсолютно любым содержимым в качестве данных (обработка содержимого, это уже вопрос более высокого уровня, и на отправку влиять никак не будет) на широковещательный адрес сети - это последний допустимый адрес, который может быть в вашей сети. Коммутатор, просто видит, что адрес широковещательный, и распуливает этот пакет абсолютно во все дурки, в какие может - разбираться с тем, чей пакет будет уже устройство, которое не может передать пакет никуда дальше, конечный узел, к примеру комп или принтер. Устройство смотрит, что внутри, и решает ему это или нет. В случае DHCP-запроса, DHCP-сервер видит, что это его искали и отвечает. Если DHCP-сервера нет то все просто видят, что пакет не к ним, и они отбрасывают пакет. Что бы "увидеть", что и как, как и писали выше - ставите wireshark, включаете на сетевой автоматический адрес, и смотрите на пакет (не знаю правда, чем это вам поможет)) ).

Читайте также: