Одним из моих любимых моментов в Android является система оповещений, позволяющая разработчикам непосредственно связываться с пользователями за пределами главного приложения. С запуском Android N, уведомления станут привычным визуальным обновлением, включающим в себя новый дизайн, измененный по размеру и содержанию. Это сделано для того, чтобы сделать его проще для восприятия, с новыми присущими только Android N деталями, такими как имя приложения и модуль расширения (экспандер). Вот хорошая схема изменений от Android M до N:
Визуальные изменения – не единственные, которые будут обновлены в Android N, будет целый набор новых особенностей предусмотренных для разработчиков, в которых они же увидят целый ряд преимуществ для использования. Комплект уведомлений позволит разработчикам группировать уведомления при помощи метода группировки (Builder.SetGroup() ). Настраиваемые представления были усовершенствованы и стало возможным использование системы уведомлений при помощи заголовков, действий и расширенных макетов с настраиваемым представлением.И наконец, моя любимая особенность – это прямой ответ, позволяющий пользователям отвечать на сообщение через уведомление теперь не придётся открывать приложение. Это, так же как и в приложениях Android Wear, которые могут отсылать обратно сообщения в главное приложение.
Начало
В предыдущих версиях Android, все разработчики должны были управлять уведомлениями и действием всех нажатий на экран, а сейчас они могут запустить Activity или Service/BroadcastReceiver для определенных действий. Суть прямого ответа заключается в том, чтобы распространить работу дистанционного ввода, позволяющего пользователям отвечать на сообщения без запуска приложения. Это самый лучший метод для обработки ответных сообщений в пределах Activity, так пользователь может решить нажать ли ему на уведомление или же воспользоваться старым способом.
Предварительное требование нужно для выполнения прямого ответа. Для этого нужен BroadcastReceiver или Service, которые могут обрабатывать или получать отклик от пользователя. Например, мы хотим запустить уведомление из MainActivity, которое отправит Intent со значением “com.xamarin.directreply.REPLY”. Далее наш BroadcastReceiver отфильтрует должным образом. В первую очередь убедитесь в том, что Android Support Library v4 NuGet установлен в приложениях для Android. (Необходимо для корректной работы приложения с уведомлениями).
В MainActivity мы создадим несколько постоянных строк, которые в дальнейшем смогут рассматриваться в коде:
1 2 3 4 5 | int requestCode = 0; public const string REPLY_ACTION = "com.xamarin.directreply.REPLY"; public const string KEY_TEXT_REPLY = "key_text_reply"; public const string REQUEST_CODE = "request_code"; |
Создание Pending Intent
Pending Intent в Android – это описание Intent и целевого воздействия для их достижения. Поэтому мы хотим создать тот, который будет запускать процесс ответа, если пользователь использует Android N или же сможет запустить MainActivity с более старых устройств.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Intent intent = null; PendingIntent pendingIntent= null; //If Android N then enable direct reply, else launch main activity. if ((int)Build.VERSION.SdkInt >= 24) { intent = new Intent(REPLY_ACTION) .AddFlags(ActivityFlags.IncludeStoppedPackages) .SetAction(REPLY_ACTION) .PutExtra(REQUEST_CODE, requestCode); pendingIntent = PendingIntent.GetBroadcast(this, requestCode, intent, PendingIntentFlags.UpdateCurrent); } else { intent = new Intent(this, typeof(MainActivity)); intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.NewTask); pendingIntent = PendingIntent.GetActivity(this, requestCode, intent, PendingIntentFlags.UpdateCurrent); } |
Создание и прикрепление RemoteInput
Основной принцип работы прямого ответа заключается в создании и прикреплении RemoteInput, который скажет Android, что мы собираемся добавить прямой ответ, и именно это позволит пользователям вводить текст.
1 2 3 4 5 6 | var replyText = "Reply to message..."; //create remote input that will read text var remoteInput = new Android.Support.V4.App.RemoteInput.Builder(KEY_TEXT_REPLY) .SetLabel(replyText) .Build(); |
После создания RemoteInput мы можем создать новое действие и прикрепить его к новому действию:
1 2 3 4 5 | var action = new NotificationCompat.Action.Builder(Resource.Drawable.action_reply, replyText, pendingIntent) .AddRemoteInput(remoteInput) .Build(); |
Создание и отправка уведомлений
После создания дистанционного ввода уже можно отправлять уведомление.
1 2 3 4 5 6 7 8 9 10 11 12 13 | var notification = new NotificationCompat.Builder(this) .SetSmallIcon(Resource.Drawable.reply) .SetLargeIcon(BitmapFactory.DecodeResource(Resources, Resource.Drawable.avatar)) .SetContentText("Hey, it is James! What's up?") .SetContentTitle("Message") .SetAutoCancel(true) .AddAction(action) .Build(); using (var notificationManager = NotificationManagerCompat.From(this)) { notificationManager.Notify(requestCode, notification); } |
Теперь уведомление работает, и мы можем видеть дистанционный ввод:
Обработка ввода
Когда пользователь вводит текст в прямой ответ, мы получаем текст из цели, выполненный в виде нескольких линий кодов.
1 2 | var remoteInput = RemoteInput.GetResultsFromIntent(Intent); var reply = remoteInput?.GetCharSequence(MainActivity.KEY_TEXT_REPLY) ?? string.Empty; |
Это будет выполняться в сервисе фоновой обработки или же в BroadcastReceiver при помощи специализированного фильтра целей “com.xamarin.directreply.REPLY”.
Здесь вы можете увидеть BroadcastReceiver, который будет высвечивать на экране всплывающее сообщение и обновлять уведомление и останавливать индикатор выполнения в нем.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | [BroadcastReceiver(Enabled = true)] [Android.App.IntentFilter(new[] { MainActivity.REPLY_ACTION })] /// <summary> /// A receiver that gets called when a reply is sent /// </summary> public class MessageReplyReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { if (!MainActivity.REPLY_ACTION.Equals(intent.Action)) return; int requestId = intent.GetIntExtra(MainActivity.REQUEST_CODE, -1); if (requestId == -1) return; var reply = GetMessageText(intent); using (var notificationManager = NotificationManagerCompat.From(context)) { //Create new notification to display, or re-build existing conversation to update with new response var notificationBuilder = new NotificationCompat.Builder(context); notificationBuilder.SetSmallIcon(Resource.Drawable.reply); notificationBuilder.SetContentText("Replied"); var repliedNotification = notificationBuilder.Build(); //Call notify to stop progress spinner. notificationManager.Notify(requestId, repliedNotification); } Toast.MakeText(context, $"Message sent: {reply}", ToastLength.Long).Show(); } /// <summary> /// Get the message text from the intent. /// Note that you should call <see cref="Android.Support.V4.App.RemoteInput.GetResultsFromIntent(intent)"/> /// to process the RemoteInput. /// </summary> /// <returns>The message text.</returns> /// <param name="intent">Intent.</param> static string GetMessageText(Intent intent) { var remoteInput = RemoteInput.GetResultsFromIntent(intent); return remoteInput?.GetCharSequence(MainActivity.KEY_TEXT_REPLY) ?? string.Empty; } } |
Узнать больше
Чтобы узнать больше о новых функциях в Android N, включая улучшенные уведомления, не забудьте прочитать Android N — Руководство по началу работы. Вы можете найти полный пример прямого ответа и других усовершенствований уведомлений в Галерее примеров
Автор: James Montemagno
Источник: Официальный блог Xamarin
Написать ответ