Вопрос или проблема
Я использую FCM для пуш-уведомлений на Android, и все работает хорошо, но у меня есть требование, которое я должен реализовать, и я не уверен, возможно ли это.
Итак, когда приложение на переднем плане (пользователь использует приложение), и появляется пуш-уведомление, и пользователь на него нажимает, уведомление перенаправит его на какой-то ЦЕЛЕВОЙ ЭКРАН,
Что я хочу, так это чтобы при нажатии на уведомление возможность показать диалоговое окно предупреждения (независимо от того, какой экран в данный момент открыт), сообщая пользователю, что он покидает текущий экран (с кнопками “перейти” и “отказаться”)?
PS: В настоящее время я использую свой SplashActivity (который является моим активным экраном) для ожидаемого намерения
val intent = Intent(this, SplashActivity::class.java).apply {
putExtra(ENTITY_ID, entityId?.toInt())
putExtra(ENTITY_TYPE, entityType)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
val pendingIntent: PendingIntent? = TaskStackBuilder.create(this).run {
addNextIntentWithParentStack(intent)
getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
}
val bitmap: Bitmap? = fetchBitmapFromUrl(notificationImageUrl, this)
val notification = NotificationCompat.Builder(this, CHANNEL_NEW_CONTENT)
.setColor(ContextCompat.getColor(this, R.color.yaraBlue))
.setContentTitle(title)
.setContentText(description)
.setSmallIcon(R.drawable.ic_notification_yara)
.setLargeIcon(bitmap)
.setStyle(
NotificationCompat.BigPictureStyle()
.bigPicture(bitmap)
.bigLargeIcon(null)
)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build()
Используйте пользовательский приемник широковещательных сообщений или обрабатывайте это в своем главном активе, чтобы показать AlertDialog.
Приемник широковещательных сообщений
class NotificationReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val entityId = intent.getIntExtra(ENTITY_ID, -1)
val entityType = intent.getStringExtra(ENTITY_TYPE)
// Запускаем активность для показа диалога
val dialogIntent = Intent(context, MainActivity::class.java).apply {
putExtra(ENTITY_ID, entityId)
putExtra(ENTITY_TYPE, entityType)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
context.startActivity(dialogIntent)
}
}
Показать диалог в MainActivity
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Проверяем, была ли эта активность запущена из уведомления
if (intent != null && intent.hasExtra(ENTITY_ID)) {
val entityId = intent.getIntExtra(ENTITY_ID, -1)
val entityType = intent.getStringExtra(ENTITY_TYPE)
// Показываем AlertDialog
showLeaveScreenDialog(entityId, entityType)
}
}
private fun showLeaveScreenDialog(entityId: Int, entityType: String?) {
val builder = AlertDialog.Builder(this)
builder.setTitle("Покидание текущего экрана")
builder.setMessage("Вы собираетесь покинуть текущий экран. Хотите продолжить?")
builder.setPositiveButton("Перейти") { dialog, _ ->
dialog.dismiss()
// Перейдите к целевому экрану здесь
navigateToTargetScreen(entityId, entityType)
}
builder.setNegativeButton("Отказаться") { dialog, _ ->
dialog.dismiss()
}
builder.show()
}
private fun navigateToTargetScreen(entityId: Int, entityType: String?) {
// Реализуйте навигацию к вашему целевому экрану здесь
}
Измените свое PendingIntent
val intent = Intent(this, NotificationReceiver::class.java).apply {
putExtra(ENTITY_ID, entityId?.toInt())
putExtra(ENTITY_TYPE, entityType)
}
val pendingIntent: PendingIntent? = PendingIntent.getBroadcast(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
Попробуйте это
Ответ или решение
Чтобы реализовать функциональность предупреждения пользователя перед переходом на экран уведомления при активном взаимодействии с приложением в Android, можно воспользоваться кастомным BroadcastReceiver
и переопределить метод onNewIntent
в вашей главной активности. Вот пошаговое руководство по реализации этой задачи.
Шаг 1: Создание BroadcastReceiver
Сначала нужно создать BroadcastReceiver
, который будет обрабатывать клик по уведомлению:
class NotificationReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val entityId = intent.getIntExtra(ENTITY_ID, -1)
val entityType = intent.getStringExtra(ENTITY_TYPE)
// Запускаем активность для отображения диалогового окна
val dialogIntent = Intent(context, MainActivity::class.java).apply {
putExtra(ENTITY_ID, entityId)
putExtra(ENTITY_TYPE, entityType)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
context.startActivity(dialogIntent)
}
}
Шаг 2: Отображение AlertDialog в MainActivity
Теперь нужно переопределить метод onNewIntent
в вашей главной активности, чтобы показать диалоговое окно:
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Проверяем, если активность была запущена из уведомления
if (intent != null && intent.hasExtra(ENTITY_ID)) {
val entityId = intent.getIntExtra(ENTITY_ID, -1)
val entityType = intent.getStringExtra(ENTITY_TYPE)
// Показать AlertDialog
showLeaveScreenDialog(entityId, entityType)
}
}
private fun showLeaveScreenDialog(entityId: Int, entityType: String?) {
val builder = AlertDialog.Builder(this)
builder.setTitle("Выход с текущего экрана")
builder.setMessage("Вы собираетесь покинуть текущий экран. Хотите продолжить?")
builder.setPositiveButton("Перейти") { dialog, _ ->
dialog.dismiss()
// Переход на экран назначения
navigateToTargetScreen(entityId, entityType)
}
builder.setNegativeButton("Отменить") { dialog, _ ->
dialog.dismiss()
}
builder.show()
}
private fun navigateToTargetScreen(entityId: Int, entityType: String?) {
// Реализуйте навигацию к вашему целевому экрану здесь
// Например, используя Intent для перехода на нужный экран
}
Шаг 3: Изменение PendingIntent
Теперь изменим PendingIntent
, чтобы он ссылался на ваш BroadcastReceiver
вместо прямого перехода на целевую активность:
val intent = Intent(this, NotificationReceiver::class.java).apply {
putExtra(ENTITY_ID, entityId?.toInt())
putExtra(ENTITY_TYPE, entityType)
}
val pendingIntent: PendingIntent? = PendingIntent.getBroadcast(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
Итог
Теперь, когда пользователь нажимает на уведомление, вместо прямого перехода на экран назначения, будет показано диалоговое окно с предупреждением о том, что он покидает текущий экран. Если пользователь выберет "Перейти", вы сможете реализовать навигацию на нужный экран, иначе пользователь останется на текущем экране.
Эта структура информации позволит вам реализовать требуемую функциональность, сохраняя при этом контроль над пользователями вашего приложения.