Как реализовать собственный BroadcastReceiver?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Реализация собственного BroadcastReceiver в Android
Для реализации собственного BroadcastReceiver в Android необходимо выполнить несколько ключевых шагов. BroadcastReceiver — это компонент Android, который позволяет приложению реагировать на системные или пользовательские широковещательные сообщения (broadcasts). Вот подробное руководство по созданию и использованию собственного приемника.
1. Создание класса BroadcastReceiver
Сначала создайте класс, который наследуется от android.content.BroadcastReceiver и переопределите метод onReceive(). Этот метод вызывается системой при получении соответствующего broadcast.
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast
class MyCustomReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// Обработка полученного broadcast
val action = intent.action
when (action) {
"com.example.MY_CUSTOM_ACTION" -> {
val data = intent.getStringExtra("data_key")
Toast.makeText(
context,
"Custom broadcast received: $data",
Toast.LENGTH_SHORT
).show()
// Дополнительная логика обработки
performCustomLogic(context, data)
}
Intent.ACTION_AIRPLANE_MODE_CHANGED -> {
// Реакция на системное событие
val isAirplaneModeOn = intent.getBooleanExtra("state", false)
handleAirplaneModeChange(context, isAirplaneModeOn)
}
}
}
private fun performCustomLogic(context: Context, data: String?) {
// Реализация вашей бизнес-логики
}
private fun handleAirplaneModeChange(context: Context, isEnabled: Boolean) {
// Обработка изменения режима полета
}
}
2. Регистрация BroadcastReceiver
Существует два способа регистрации приемника: статически в манифесте и динамически в коде.
Статическая регистрация (в AndroidManifest.xml)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application>
<receiver
android:name=".MyCustomReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!-- Регистрация на кастомное действие -->
<action android:name="com.example.MY_CUSTOM_ACTION" />
<!-- Регистрация на системные события -->
<action android:name="android.intent.action.AIRPLANE_MODE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<!-- Для некоторых системных broadcast требуются разрешения -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</manifest>
Динамическая регистрация (в коде Activity/Fragment/Service)
class MainActivity : AppCompatActivity() {
private lateinit var myReceiver: MyCustomReceiver
private val intentFilter = IntentFilter().apply {
addAction("com.example.MY_CUSTOM_ACTION")
addAction(Intent.ACTION_POWER_CONNECTED)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myReceiver = MyCustomReceiver()
// Регистрация приемника
registerReceiver(myReceiver, intentFilter)
}
override fun onDestroy() {
super.onDestroy()
// ВАЖНО: всегда отменяйте регистрацию динамических receiver
unregisterReceiver(myReceiver)
}
}
3. Отправка кастомных broadcast
Для отправки собственных broadcast сообщений используйте класс Intent:
// Отправка неупорядоченного broadcast
fun sendCustomBroadcast(context: Context) {
val intent = Intent("com.example.MY_CUSTOM_ACTION").apply {
putExtra("data_key", "Hello from broadcast!")
putExtra("timestamp", System.currentTimeMillis())
}
// Отправка с разрешением (опционально)
context.sendBroadcast(
intent,
"com.example.CUSTOM_PERMISSION" // требуется объявить в манифесте
)
}
// Отправка упорядоченного broadcast
fun sendOrderedBroadcastExample(context: Context) {
val intent = Intent("com.example.ORDERED_ACTION").apply {
putExtra("priority_data", "High priority message")
}
context.sendOrderedBroadcast(
intent,
"com.example.CUSTOM_PERMISSION",
MyResultReceiver(), // получатель результата
null, // handler
Activity.RESULT_OK,
"initial_data",
null // bundle
)
}
// Local broadcast (в пределах приложения) с использованием LocalBroadcastManager
fun sendLocalBroadcast(context: Context) {
// Для старых версий Android
val localIntent = Intent("com.example.LOCAL_ACTION")
LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent)
// Для AndroidX/современных приложений
val localBroadcastManager = LocalBroadcastManager.getInstance(context)
localBroadcastManager.sendBroadcast(localIntent)
}
4. Важные особенности и best practices
-
Производительность: Метод
onReceive()выполняется в главном потоке и должен завершаться быстро (рекомендуется ≤ 10 секунд). Для длительных операций используйтеJobIntentService,WorkManagerилиForeground Service. -
Жизненный цикл: После возврата из
onReceive()система может уничтожить процесс приемника. Для асинхронных операций используйтеgoAsync():
class AsyncReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val pendingResult = goAsync()
CoroutineScope(Dispatchers.IO).launch {
// Длительная операция
performLongOperation()
// Завершаем операцию
pendingResult.finish()
}
}
}
-
Безопасность: Для защиты broadcast используйте разрешения:
- Объявите permission в манифесте отправителя и получателя
- Используйте
android:exported="false"для receiver, которые должны получать только внутренние broadcast
-
Системные ограничения: Начиная с Android 8.0 (API 26), введены ограничения на статическую регистрацию для многих системных событий. Используйте динамическую регистрацию или
JobScheduler/WorkManager. -
Локальные broadcast: Для коммуникации внутри приложения предпочтительнее использовать
LocalBroadcastManager(до API 30) или механизмы типаLiveData,Flow, илиEventBus.
5. Отладка и мониторинг
Для отладки broadcast можно использовать команды ADB:
# Отправка кастомного broadcast через ADB
adb shell am broadcast -a com.example.MY_CUSTOM_ACTION --es data_key "test_value"
# С дополнительными extras
adb shell am broadcast -a com.example.MY_ACTION --ei int_key 42 --ez bool_key true
Реализация собственного BroadcastReceiver требует внимания к жизненному циклу, производительности и безопасности, но предоставляет мощный механизм для реактивного программирования и межкомпонентного взаимодействия в Android-приложениях.