Откажитесь от уведомлений и вместо этого покажите действие на экране блокировки Android
16 марта 2023 г.Сегодня мы узнаем, как отображать действие в полноэкранном режиме вместо уведомления, когда устройство заблокировано.
По умолчанию Android показывает то же уведомление, что и при разблокировке устройства, но в некоторых случаях, например при телефонном звонке, может потребоваться отобразить действие в полноэкранном режиме.
Вы можете найти исходный код здесь.
Создание уведомления
Давайте начнем с создания простого уведомления, которое позже будет использоваться для отображения действия на экране просмотра.
Первое, что нам нужно сделать перед созданием уведомления, — это создать канал для его отображения.
private const val CHANNEL_ID = "heads_up_alerts"
private const val CHANNEL_NAME = "Heads Up Alerts"
private val notificationManager = NotificationManagerCompat.from(context)
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
val channel = NotificationChannel(
CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH
).apply {
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
}
notificationManager.createNotificationChannel(channel)
}
Сначала мы извлекаем NotificationManager
из NotificationManagerCompat
. Это интерфейс, используемый для работы с уведомлениями на Android. Затем мы создаем NotificationChannel
, который принимает в качестве аргументов идентификатор, имя и важность канала. Рекомендуется использовать NotificationManager.IMPORTANCE_HIGH
, чтобы повысить вероятность того, что уведомление появится в виде предупреждения. Мы также меняем lockscreenVisibility
на Notification.VISIBILITY_PUBLIC
, чтобы сообщить Android, что уведомление может отображаться на экране блокировки. Наконец, мы вызываем notificationManager.createNotificationChannel
, чтобы зарегистрировать канал.
Вплоть до Android Naught (25) не было необходимости создавать каналы уведомлений, поэтому в начале метода стояла причина защиты.
Когда мне следует создать канал?
Нет проблем с многократным вызовом createNotificationChannel
для одного и того же канала. Android проигнорирует его, если существует канал с таким же идентификатором.
Вы должны зарегистрировать свои каналы как можно раньше, желательно, когда вызывается Application.onCreate
.
Каналы неизменяемы; если вам нужно изменить какую-либо конфигурацию канала, вам придется либо удалить приложение, либо изменить идентификатор канала.
Создание простого уведомления
Теперь, когда мы создали канал, мы можем создать уведомление.
private fun createNotification(): Notification {
val contentIntent = Intent(context, HomeActivity::class.java)
val contentPendingIntent = PendingIntent.getActivity(context, 0, contentIntent, 0)
return NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.notifications_active_black_24)
.setColor(ResourcesCompat.getColor(context.resources, R.color.purple_200, null))
.setContentTitle(context.getString(R.string.notification_title))
.setAutoCancel(true)
.setContentIntent(contentPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.build()
}
Во-первых, мы начинаем с создания PendingIntent
, это намерение, которое будет вызываться при нажатии на уведомление. Здесь мы просто начнем действие. Затем мы вызываем NotificationCompat.Builder
, чтобы определить, как будет выглядеть уведомление. Параметр CHANNEL_ID
должен иметь тот же идентификатор, который мы использовали ранее для создания канала. Если вы хотите узнать, как настроить уведомление, ознакомьтесь с документацией Android. .
Следующий шаг — просто вызвать notificationManager
, чтобы отобразить уведомление. Идентификатор уведомления может быть любым; оно используется только в том случае, если вам нужно взаимодействовать с уведомлением позже.
const val NOTIFICATION_ID = 24756
notificationManager.notify(NOTIFICATION_ID, createNotification())
Это то, что вы должны увидеть, когда отображается ваше уведомление.
Создание действия на экране блокировки
Теперь мы создадим действие, которое будет отображаться на экране блокировки. Это действие очень похоже на обычное действие, но вам нужно изменить две вещи, чтобы оно отображалось на экране блокировки.
Первый — это вызов showWhenLockedAndTurnScreenOn
после onCreate
, чтобы указать, что действие может отображаться на экране блокировки и что экран должен включаться при его появлении. Я добавил этот метод в действие, но вы можете легко добавить его как расширение действия на случай, если будете использовать его в других местах.
class LockscreenActivity : AppCompatActivity() {
private lateinit var binding: ActivityLockscreenBinding
override fun onCreate(savedInstanceState: Bundle?) {
showWhenLockedAndTurnScreenOn()
super.onCreate(savedInstanceState)
binding = ActivityLockscreenBinding.inflate(layoutInflater)
setContentView(binding.root)
}
private fun showWhenLockedAndTurnScreenOn() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
setTurnScreenOn(true)
} else {
window.addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
)
}
}
}
Второе — изменить определение манифеста, добавив launchMode
и showOnLockScreen
.
<activity
android:name=".presentation.LockscreenActivity"
android:launchMode="singleTop"
android:showOnLockScreen="true" />
Вот и все. Вы создали действие, которое может отображаться на экране блокировки. Последнее, что нам нужно сделать, это сообщить Android, что мы хотим, чтобы это действие отображалось на экране блокировки, а не в уведомлении.
Добавление действия в уведомление
Нам нужно изменить метод createNotification
, который мы определили ранее. Нам нужно создать еще один PendingIntent
, который запустит действие, которое будет отображаться на экране блокировки. Затем мы передаем это намерение в setFullScreenIntent
. Также важно добавить категорию, например БУДИЛЬНИК или ЗВОНОК, чтобы повысить вероятность ее появления на экране блокировки.
private fun createNotification(): Notification {
val contentIntent = Intent(context, HomeActivity::class.java)
val contentPendingIntent = PendingIntent.getActivity(context, 0, contentIntent, 0)
val fullScreenIntent = Intent(context, LockscreenActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(context, 0, fullScreenIntent, 0)
return NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.notifications_active_black_24)
.setColor(ResourcesCompat.getColor(context.resources, R.color.purple_200, null))
.setContentTitle(context.getString(R.string.notification_title))
.setAutoCancel(true)
.setContentIntent(contentPendingIntent)
.setFullScreenIntent(fullScreenPendingIntent, true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.build()
}
Вот видео конечного результата.
Это не работает!!!
Для некоторых из вас действие может не отображаться на экране блокировки из-за вашего телефона. Не все телефоны позволяют использовать полноэкранные намерения по умолчанию. У меня Xiaomi, и он не включен по умолчанию.
Чтобы включить его, вам нужно перейти в настройку приложения -> Другие разрешения -> Показывать на экране блокировки.
Уведомление также не появится, если у вас уже есть уведомление с тем же идентификатором, которое не было отклонено. В идеале вы должны отменить уведомление, вызвав notificationManager.cancel(id)
, когда действие экрана блокировки будет уничтожено.
Заключение
Уведомления Android — это отличный способ уведомить пользователей о том, что им нужно что-то сделать, но они могут работать некорректно, когда телефон заблокирован. Полноэкранные действия решают эту проблему, позволяя отображать действия, даже если телефон заблокирован.
Исходный код можно найти здесь.
Ресурсы
Как управлять входящим видеовызовом для каждой версии ОС Android с уведомлениями FCM
Фото Рами Аль-Заят на Unsplash
:::информация Также опубликовано здесь.< /em>
:::
Оригинал