- Broadcast (Широковещательные сообщения)
- Передача сообщений
- Приёмники широковещательных сообщений
- Периодическое срабатывание каждую минуту
- TIME_TICK на Kotlin
- Автостарт Activity или Service при загрузке (перезагрузке) девайса
- Следим за питанием
- Android — Broadcast Receivers
- Creating the Broadcast Receiver
- Registering Broadcast Receiver
- Broadcast-Receiver
- Broadcasting Custom Intents
- Example
Broadcast (Широковещательные сообщения)
В Android существует понятие широковещательных сообщений, которые можно отправлять или принимать. Оба процесса между собой не связаны и их можно использовать по отдельности.
Передача сообщений
Для начала научимся отправлять сообщения. В одном из уроков мы учились запускать другую активность с помощью намерения Intent. Но намерения можно использовать для отправки сообщений, предназначенные не какому-то отдельному приложению, объекту или компоненту, а всем. И любая программа, оборудованная специальным приёмником, может поймать это сообщение и предпринять свои шаги на основе полученной информации.
Для понимания, представьте, что радистка Кэт отправляет сообщение: «Срочно пришлите кота! Хочу быть сильной независимой женщиной. А ваш Штирлиц — фашист!». Возможно в этом сообщении содержится шифровка, что нужно прислать жену, столик для жены разведчика в кафе заказан, а Штирлиц — козёл! Но это не важно для нашего урока.
Любой человек, имеющий специальный оборудованный радиоприёмник, может принять это сообщение. Так же поступают и программы. Они обзаводятся приёмниками и прослушивают определённый тип сообщений.
Сообщения может создавать сама система, а также ваша программа и чужие программы.
Передача сообщений весьма проста в реализации. В вашем приложении необходимо создать сообщение, которое вы хотите передать. Установите при необходимости поля action, data и category (действие, данные и категорию) вашего сообщения и путь, который позволяет приёмникам широковещательных сообщений точно определять «своё» сообщение. В этом сообщении строка действия ACTION должна быть уникальной, чтобы идентифицировать передаваемое действие. В таких случаях создают строку-идентификатор действия по правилам именования пакетов Java. Например, для обнаружения кота в большом здании:
Далее вы создаёте объект Intent, загружаете в него нужную информацию и вызываете метод sendBroadcast(), передав ему в качестве параметра созданный объект Intent. Дополнительные данные можно использовать в extras как необязательные параметры.
Виртуальный код для обнаружения кота:
В этом примере мы создали намерение с уникальной строкой, передали дополнительные данные (имя кота и его координаты), отправили сообщение. Другое приложение, связанное с картами, может принять сообщение и показать кота на карте.
Существуют также родственные методы sendStickyBroadcast() и sendOrderedBroadcast().
Для старых устройств этого было вполне достаточно, но начиная с Android 3.0, в целях безопасности сообщения будут игнорироваться остановленными приложениями, чтобы они не запускались. Поэтому следует добавлять дополнительный флаг, разрешающий запуск активности.
Мы напишем простой пример, который будет отправлять сообщения и также создадим приёмник для его получения. О приёмнике мы поговорим подробно во второй части урока. А пока получим первое представление о нём.
Создайте новый проект и разместите на экране кнопку с надписью «Отправить сообщение». Присвойте атрибуту onClick название метода, в котором будет происходит отправка широковещательного сообщения.
В классе активности создаём уникальную строку и реализуем метод для щелчка кнопки. Также добавим дополнительные данные — первую часть послания радистки.
Запустив пример, вы можете нажать на кнопку и отправлять сообщение. Только ваше сообщение уйдёт в никуда, так как ни одно приложение не оборудовано приёмником для него. Исправим ситуацию и создадим приёмник в своём приложении. Мы будем сами принимать свои же сообщения.
Приёмник представляет собой обычный Java-класс на основе BroadcastReceiver. Вы можете создать вручную класс и наполнить его необходимыми методами. Раньше так и поступали. Но в студии есть готовый шаблон, который поможет немного сэкономить время.
Щёлкаем правой кнопкой мыши на названии пакета и выбираем New | Other | Broadcast Receiver
В диалоговом окне задаём имя приёмника, остальные настройки оставляем без изменений.
Студия создаст изменения в двух местах. Во-первых, будет создан класс MessageReceiver:
Во-вторых, в манифесте будет добавлен новый блок.
В него следует добавить фильтр, по которому он будет ловить сообщения.
Вернёмся в класс приёмника и модифицируем метод onReceive().
Снова запустим пример и ещё раз отправим сообщение. Так как наше приложение теперь оборудовано не только передатчиком, но и приёмником, то оно должно уловить сообщение и показать его нам.
Вы можете создать другое приложение с приёмником, чтобы одно приложение посылало сообщение, а другое принимало.
Приёмники широковещательных сообщений
Вот плавно мы перешли к приёмникам широковещательных сообщений. На самом деле вам не так часто придётся рассылать сообщения, гораздо чаще встречается потребность принимать сообщения. В первую очередь, сообщения от системы. Примерами таких сообщений могут быть:
- Низкий заряд батареи
- Нажатие на кнопку камеры
- Установка нового приложения
Приёмник можно создать двумя способами — через манифест (мы использовали этот способ в примере) и программно через метод registerReceiver(). Между двумя способами есть существенная разница. Приёмник, заданный в манифесте, известен системе, которая сканирует файлы манифеста всех установленных приложений. Поэтому, даже если ваше приложение не запущено, оно всё равно сможет отреагировать на поступающее сообщение.
Приёмник, созданный программно, может работать только в том случае, когда активность вашего приложения активна. Казалось, это является недостатком и нет смысла использовать такой подход. Но всё не так просто. Некоторые системные сообщения могут обрабатываться только приёмниками, созданными программно. И в этом есть свой резон. Например, если ваше приложение не запущено, ему нет смысла принимать сообщения о заряде батареи. Иначе заряд батареи будет расходоваться ещё быстрее при лишней бесполезной работе. Информацию о заряде батареи ваше приложение может получить, когда в этом есть необходимость. Следует сверяться с документацией, какой вид приёмника следует использовать.
При программной регистрации приёмника мы можем также снять регистрацию, когда больше не нуждаемся в нём с помощью метода unregisterBroadcastReceiver().
Периодическое срабатывание каждую минуту
Рассмотрим пример периодического срабатывания приёмника каждую минуту с помощью системного намерения android.intent.action.TIME_TICK. Приёмник будет создан программно. Добавим на экран активности две кнопки для регистрации и отмены регистрации широковещательного сообщения.
Создадим вручную новый класс TimeBroadcastReceiver, наследующий от BroadcastReceiver:
Вы можете создать класс приёмника и через шаблон, как мы это сделали в предыдущем примере. Но в этом случае удалите запись о нём в манифесте, так как нам он не понадобится. Но если вы забудете сделать это, то ничего страшного не произойдёт, так как там не прописаны фильтры.
Откроем код главной активности и зарегистрируем (а также снимем регистрацию) приёмник:
Запускаем проект и нажимаем на первую кнопку, чтобы включить рассылку широковещательного сообщения. Теперь каждую минуту будет срабатывать запуск всплывающего сообщения с текущим временем. Даже если вы переключитесь на другое приложение, то всё равно будете видеть сообщения.
Это один из примеров, когда приёмник следует регистрировать программно. Я видел часто на форумах вопросы, почему не работает данное намерение android.intent.action.TIME_TICK. А не надо было его регистрировать в манифесте.
В нашем примере мы устанавливали и снимали регистрацию через нажатия кнопок. Обычно включают регистрацию в методе onResume(), а снимают регистрацию в методе onPause().
Необходимо помнить, что программная регистрация широковещательного сообщения создаётся в основном потоке приложения и это может послужить источником ошибок, если операции в BroadcastReceiver занимают длительное время. Как вариант, используйте сервисы. Почитайте на эту тему статью (en).
TIME_TICK на Kotlin
Напишем похожий пример на Kotlin. Разместите на экране TextView, в котором будет отображаться время. Код для активности ниже. Обратите внимание, что мы не создаём отдельный класс для BroadcastReceiver, включаем регистрацию в onResume() и снимаем регистрацию в onPause().
Автостарт Activity или Service при загрузке (перезагрузке) девайса
Ещё один полезный пример, который часто используется приложениями.
Если ваше приложение (сервис) должно запускаться сразу после перезагрузки устройства, то используйте намерение android.intent.action.BOOT_COMPLETED:
Мы создали отдельный класс для широковещательного сообщения. Также нужно создать разрешение и зарегистрировать приёмник в манифесте.
Следим за питанием
Нет, речь пойдёт не о правильном питании кота. Имеется в виду питание от электричества. Если ваше устройство отключить от зарядки, то система оповещает об этом событии через широковещательное намерение android.intent.action.ACTION_POWER_DISCONNECTED.
Не станем заводить новый приёмник, а откроем манифест и добавим дополнительный фильтр к приёмнику сообщений от радистки Кэт.
А в классе MessageReceiver добавим код для метода.
Пример нужно проверять на реальном устройстве. Подключите устройство к питанию, а затем выдерните кабель. На экране появится сообщение.
Источник
Android — Broadcast Receivers
Broadcast Receivers simply respond to broadcast messages from other applications or from the system itself. These messages are sometime called events or intents. For example, applications can also initiate broadcasts to let other applications know that some data has been downloaded to the device and is available for them to use, so this is broadcast receiver who will intercept this communication and will initiate appropriate action.
There are following two important steps to make BroadcastReceiver works for the system broadcasted intents −
Creating the Broadcast Receiver.
Registering Broadcast Receiver
There is one additional steps in case you are going to implement your custom intents then you will have to create and broadcast those intents.
Creating the Broadcast Receiver
A broadcast receiver is implemented as a subclass of BroadcastReceiver class and overriding the onReceive() method where each message is received as a Intent object parameter.
Registering Broadcast Receiver
An application listens for specific broadcast intents by registering a broadcast receiver in AndroidManifest.xml file. Consider we are going to register MyReceiver for system generated event ACTION_BOOT_COMPLETED which is fired by the system once the Android system has completed the boot process.
Broadcast-Receiver
Now whenever your Android device gets booted, it will be intercepted by BroadcastReceiver MyReceiver and implemented logic inside onReceive() will be executed.
There are several system generated events defined as final static fields in the Intent class. The following table lists a few important system events.
Sr.No | Event Constant & Description | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 |
Step | Description |
---|---|
1 | You will use Android studio to create an Android application and name it as My Application under a package com.example.tutorialspoint7.myapplication as explained in the Hello World Example chapter. |
2 | Modify main activity file MainActivity.java to add broadcastIntent() method. |
3 | Create a new java file called MyReceiver.java under the package com.example.tutorialspoint7.myapplication to define a BroadcastReceiver. |
4 | An application can handle one or more custom and system intents without any restrictions. Every intent you want to intercept must be registered in your AndroidManifest.xml file using tag |
5 | Modify the default content of res/layout/activity_main.xml file to include a button to broadcast intent. |
6 | No need to modify the string file, Android studio take care of string.xml file. |
7 | Run the application to launch Android emulator and verify the result of the changes done in the application. |
Following is the content of the modified main activity file MainActivity.java. This file can include each of the fundamental life cycle methods. We have added broadcastIntent() method to broadcast a custom intent.
Following is the content of MyReceiver.java:
Following will the modified content of AndroidManifest.xml file. Here we have added tag to include our service:
Following will be the content of res/layout/activity_main.xml file to include a button to broadcast our custom intent −
Let’s try to run our modified Hello World! application we just modified. I assume you had created your AVD while doing environment set-up. To run the app from Android studio, open one of your project’s activity files and click Run icon from the tool bar. Android Studio installs the app on your AVD and starts it and if everything is fine with your set-up and application, it will display following Emulator window −
Now to broadcast our custom intent, let’s click on Broadcast Intent button, this will broadcast our custom intent «com.tutorialspoint.CUSTOM_INTENT» which will be intercepted by our registered BroadcastReceiver i.e. MyReceiver and as per our implemented logic a toast will appear on the bottom of the the simulator as follows −
You can try implementing other BroadcastReceiver to intercept system generated intents like system boot up, date changed, low battery etc.
Источник