пятница, 13 июля 2012 г.

Уведомления в Jelly Bean

Операционная система Android 4.1 (Jelly Bean) вышла в Июне 2012 года. Одним из заметных изменений этой версии стало обновление системы уведомлений. В новой редакции они стали более яркими и информативными.
Новые уведомления отображаются двумя способами: если уведомление первое в списке, то для него отводится больше места и оно отображается целиком, если оно располагается вторым или третьим, то для его отображения будет использоваться более компактный вариант.
Для разработчиков появился ряд шаблонных стилей, которые можно использовать при отображении уведомления: Notification.BigPictureStyle, Notification.BigTextStyle, Notification.InboxStyle. Каждый из данных стилей имеет свои дизайнерские особенности. Рассмотрим каждый из них отдельно.

BigTextStyle

Данный стиль предназначен для отображения объемных текстовых сообщений.
Resources resources = context.getResources();
// set intent action in notification
Intent i = new Intent(NotificationBroadcastReceiver.ACTION_NOTIFICATION_CLICK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, i, 0);

Notification notification = new Notification.BigTextStyle(
    new Notification.Builder(context)
    .setContentTitle("Text title")
    .setContentText("Text, shown when notification isn't expanded")
    .setSmallIcon(R.drawable.ic_launcher)// Image, shown in notification bar
    .setLargeIcon(BitmapFactory.decodeResource(resources,
        R.drawable.ic_launcher))// Bitmap Shown in notification
    .setAutoCancel(true)
    .addAction(R.drawable.action_icon, "Action text",pendingIntent))
    .bigText("Long Text, shown in expanded viewn\n"
        + "Long Text, shown in expanded viewn\n"
        + "Long Text, shown in expanded viewn\n"
        + "Long Text, shown in expanded viewn\n")
    .build();

NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NTF_ID_TEST, notification);

После вызова данного Notification-а получаем сообщение следующего вида:


BigPictureStyle

Данный стиль удобен для отображения обновления галереи того или иного приложения, например, отслеживание обновления фотографий в Facebook или других социальных сетях и сервисах.
Notification notification = new Notification.BigPictureStyle(
    new Notification.Builder(context)
    .setContentTitle("Text title")
    .setContentText("Text, shown when notification isn't expanded")
    .setSmallIcon(R.drawable.ic_launcher)// image, shown in notification bar
    .setLargeIcon(BitmapFactory.decodeResource(resources,
        R.drawable.jelly_bean_android))// Bitmap Shown in notification
    .setAutoCancel(true)
    .addAction(R.drawable.action_icon, "Action text",pendingIntent))
    .bigPicture(BitmapFactory.decodeResource(resources, R.drawable.jelly_beans))
    .build();

После вызова данного Notification-а получаем сообщение следующего вида:

InboxStyle

Данный стиль предназначен для отображения списков, например списка полученных писем, или списка запланированных покупок.
Notification notification = new Notification.InboxStyle(
    new Notification.Builder(context)
    .setContentTitle("Shopping list")
    .setSmallIcon(R.drawable.shopping_bag_icon)
    .setLargeIcon(BitmapFactory.decodeResource(resources,
        R.drawable.shopping_bag_icon))
    .setAutoCancel(true)
    .addAction(R.drawable.action_icon, "View whole list",pendingIntent))
    .addLine("apples")
    .addLine("mellon")
    .addLine("coca-cola")
    .build();

После вызова данного Notification-а получаем сообщение следующего вида:


Уведомления с произвольным UI

Наиболее интересным нововведением для разработчиков является возможность использования различных компонентов, относящихся к классу RemoteView. Это позволяет наиболее гибко использовать систему уведомлений.
Не очевидным моментом при использовании RemoteView оказался способ задания расширенного уведомления. Эта возможность отсутствует в Notification.Builder и после нескольких экспериментов выяснилось, что созданный нами RemoteView требуется напрямую указывать полю bigContentView, который находится в классе Notification.
Создадим короткий пример. Уменьшенное уведомление (notification_layout) будет содержать заголовок и короткий текст. Расширенное уведомление (notification_layout_expanded) будет содержать заголовок, длинный текст и кнопку для перехода.
Создание и вызов уведомления выглядит следущим образом:
RemoteViews view = new RemoteViews(context.getPackageName(),
    R.layout.notification_layout);
RemoteViews viewExpanded = new RemoteViews(context.getPackageName(),
    R.layout.notification_layout_expanded);

// set intent and register onclick
Intent i = new Intent(
    NotificationBroadcastReceiver.ACTION_NOTIFICATION_BUTTON_CLICK);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
viewExpanded.setOnClickPendingIntent(R.id.NotificationAppButton, pi);

Notification notification = new Notification.Builder(context).setContent(view)
    .setSmallIcon(R.drawable.ic_launcher).setAutoCancel(true)
    .build();

notification.bigContentView = viewExpanded; // <---- the most tricky moment

NotificationManager nm = (NotificationManager) context
    .getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NTF_ID_TEST, noti);

При нажатии на кнопку, отображенную на уведомлении, отправляется широковещательный intent, который обрабатывается обычным BroadcastReveiver-ом. После вызова данного Notification-а получаем:


Приоритет уведомлений

В Jelly Bean появилась возможность задать приоритет уведомления, что влияет на очерёдность их отображения. Команда андроид-разработчиков выделила приоритеты от PRIORITY_MIN до PRIORITY_MAX (значения от -2 до 2), где приоритетом по умолчанию является PRIORITY_DEFAULT (значение 0).
Также для отображения экстренных уведомлений можно воспользоваться методом setFullScreenIntent(PendingIntent, boolean). При вызове таких уведомлений сразу же отработает Intent, прикреплённый к уведомлению, минуя Notification Bar.
В целом данные нововведения являются довольно простыми, чтобы их нужно было рассматривать детально, но при экспериментировании с этой функциональностью возник ряд морально–этических вопросов: а кто будет пользоваться низкими приоритетами для уведомлений, если есть вероятность, что в определённых ситуациях такие уведомления вообще отображаться не будут?! Не станут ли разработчики эксплуатировать только PRIORITY_MAX и игнорировать ранжирование остальных приоритетов? Не станет ли функциональность setFullScreenIntent излюбленной среди рекламодателей?
Ответы на данные вопросы покажет нам только время. Но стоит напомнить, что в ответ на использование приоритета уведомлений у пользователей появился простой способ отключить показ уведомления любой программы.

Комментариев нет:

Отправить комментарий