До сих пор мы рассматривали важность уведомлений на платформе Windows Phone вместе с различными типами уведомлений , доступных для вашего приложения. В этом посте мы рассмотрим настройку вашего приложения для получения уведомлений и способы отправки уведомлений.
Первым шагом в настройке приложения для получения уведомлений является регистрация в службе push-уведомлений Microsoft. Это делается путем создания экземпляра класса HttpNotificationChannel и вызова метода Open
. Метод Open
— это асинхронный метод, который устанавливает канал связи между службой push-уведомлений и вашим приложением, запущенным на этом конкретном устройстве. После открытия канала Channel Uri (который можно считать уникальным идентификатором канала) возвращается приложению через экземпляр HttpNotificationChannel
. Событие HttpNotificationChannel
экземпляре HttpNotificationChannel
, позволяя приложению определить, когда был настроен канал.
Следующий код иллюстрирует создание HttpNotificationChannel, подключение события ChannelUriUpdated
и затем открытие канала. Метод Open
будет возвращен немедленно, ChannelUriUpdated
событие ChannelUriUpdated
будет ChannelUriUpdated
вскоре после настройки канала. Обратите внимание, что ChannelName
— это произвольное имя, которое вы назначаете каналу для вашего приложения.
private const string ChannelName = "MyApplicationChannel"; public HttpNotificationChannel Channel { get; set; } public bool ChannelIsActive { get; set; } private void EstablishNotificationChannel() { Channel = new HttpNotificationChannel(ChannelName); Channel.ChannelUriUpdated += HttpChannelChannelUriUpdated; Channel.Open(); } private void HttpChannelChannelUriUpdated(object sender, NotificationChannelUriEventArgs e) { UpdateChannelIsActive(); } private void UpdateChannelIsActive() { ChannelIsActive = Channel != null && Channel.ChannelUri != null && !string.IsNullOrEmpty(Channel.ChannelUri.OriginalString); }
После открытия канал может продолжать существовать, даже если ваше приложение закрыто или захоронено. Это необходимо для того, чтобы устройство получало уведомления о плитках и тостах, когда приложение не активно. Если ваше приложение пытается создать новый канал каждый раз, когда оно запускается, будет возбуждено исключение, поскольку вы можете иметь только один активный канал за раз. Чтобы решить эту проблему, прежде чем пытаться создать новый HttpNotificationChannel
, необходимо вызвать статический метод Find
чтобы проверить, есть ли уже доступный канал, как показано в следующем коде.
private void EstablishNotificationChannel() { Channel = HttpNotificationChannel.Find(ChannelName); if (Channel == null) { Channel = new HttpNotificationChannel(ChannelName); Channel.ChannelUriUpdated += HttpChannelChannelUriUpdated; Channel.Open(); } else { Channel.ChannelUriUpdated += HttpChannelChannelUriUpdated; } UpdateChannelIsActive(); }
Следует отметить, что даже если HttpNotificationChannel
существует, вы все равно должны ChannelUriUpdated
событие ChannelUriUpdated
поскольку существуют сценарии, когда будет HttpNotificationChannel
экземпляр HttpNotificationChannel
, но канал не имел возможности инициализироваться. В этих случаях после настройки канала будет ChannelUriUpdated
событие ChannelUriUpdated
.
Пока что все, что мы сделали, это установили канал, по которому можно получать уведомления. Тем не менее, мы не сказали приложению или устройству, что делать при получении уведомления. Давайте пройдемся по каждому типу уведомлений по очереди.
Сырое уведомление
Когда канал уже установлен, вам больше ничего не нужно делать, чтобы настроить канал для получения уведомлений в приложении. Однако для обработки полученного уведомления вам нужно добавить обработчик события в событие HttpNotificationChannel
в HttpNotificationChannel
. Рисунок 4 иллюстрирует обработчик события для этого события; Свойство Body объекта Notification — это поток, из которого ваше приложение может прочитать, представляющий необработанные байты, отправленные через необработанное уведомление.

Отправка любого типа уведомления — это вопрос выполнения HTTP-операции POST в ChannelUri
экземпляра приложения. Вы должны установить некоторые дополнительные заголовки, а полезные данные должны быть соответствующим образом отформатированы в зависимости от типа отправляемого уведомления. Для необработанного уведомления полезная нагрузка не структурирована.
Следующий код устанавливает новый веб-запрос к предоставленному channelUri
, устанавливает соответствующие заголовки, открывает поток запросов, записывает notificationMessage
и затем завершает запрос. Этот код также иллюстрирует, как можно проанализировать ответ для извлечения информации о состоянии об уведомлении, канале и подключенном состоянии устройства.
private static Guid SendNotification(byte[] notificationMessage, Uri channelUri, int notificationType, string targetHeader = null) { var request = (HttpWebRequest)WebRequest.Create(channelUri); request.Method = "POST"; request.Headers = new WebHeaderCollection(); var messageId = Guid.NewGuid(); request.Headers["X-MessageID"] = messageId.ToString(); request.Headers["X-NotificationClass"] = notificationType.ToString(); if (!string.IsNullOrEmpty(targetHeader)) { request.ContentType = "text/XML"; request.Headers["X-WindowsPhone-Target"] = targetHeader; } request.BeginGetRequestStream((result) => { var req = result.AsyncState as HttpWebRequest; using (var requestStream = req.EndGetRequestStream(result)) { requestStream.Write(notificationMessage, 0, notificationMessage.Length); } req.BeginGetResponse((responseResult) => { var responseRequest = result.AsyncState as HttpWebRequest; using (var response = responseRequest.EndGetResponse(responseResult)) { string notificationStatus = response.Headers["X-NotificationStatus"]; string notificationChannelStatus = response.Headers["X-SubscriptionStatus"]; string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"]; } }, req); }, request); return messageId; }
Теперь все, что вам нужно сделать, это вызвать метод SendNotification
с соответствующими параметрами. Для необработанного уведомления вы должны сделать следующий звонок. 3 указывает, что тип уведомления является необработанным уведомлением, которое должно быть отправлено немедленно.
private void SendRawClick(object sender, RoutedEventArgs e) { var msg = Encoding.UTF8.GetBytes("Hello World!"); SendNotification(msg, Channel.ChannelUri, 3); }
Обратите внимание, что в случае необработанного уведомления вам не нужно указывать свойство targetHeader
поскольку оно относится только к плиткам и тост-уведомлениям.
Тост Уведомление
Поскольку вы хотите, чтобы всплывающие уведомления отображались для вашего приложения, даже если пользователь отсутствует в вашем приложении, вы должны сообщить операционной системе, что она должна принимать всплывающие уведомления от имени вашего приложения. Для этого вам нужно вызвать метод HttpNotificationChannel
экземпляре HttpNotificationChannel
после HttpNotificationChannel
Open
.
Channel = new HttpNotificationChannel(ChannelName); Channel.ChannelUriUpdated += HttpChannelChannelUriUpdated; Channel.Open(); Channel.BindToShellToast();
Когда пользователь находится в вашем приложении и в ваше приложение отправляется тост-сообщение, а не обычный тост-интерфейс, ваше приложение будет перехватывать это сообщение, вызывая событие HttpNotificationChannel
экземпляре HttpNotificationChannel
.
Channel.HttpNotificationReceived += HttpChannelHttpNotificationReceived; Channel.ShellToastNotificationReceived += HttpChannelShellToastNotificationReceived;
В соответствующем обработчике событий вы можете проанализировать коллекцию возвращаемых строк. Тостовые уведомления состоят из двух строк с ключевыми значениями «text1» и «text2».
private void HttpChannelShellToastNotificationReceived(object sender, NotificationEventArgs e) { var sb = new StringBuilder(); foreach (var kvp in e.Collection) { sb.AppendLine(string.Format("Key:{0} Value:{1}", kvp.Key, kvp.Value)); } this.Dispatcher.BeginInvoke(() => { MessageBox.Show(sb.ToString()); }); }
Наконец, для отправки всплывающего уведомления вам просто нужно сгенерировать правильно сформированный XML и преобразовать его в байтовый массив, который становится полезной нагрузкой уведомления.
private void SendToastClick(object sender, RoutedEventArgs e) { var messageTemplate = "<?XML version="1.0" encoding="utf-8"?>" + "<wp:Notification XMLns:wp="WPNotification">" + "<wp:Toast>" + "<wp:Text1>{0}</wp:Text1>" + "<wp:Text2>{1}</wp:Text2>" + "</wp:Toast>" + "</wp:Notification>"; var message = string.Format(messageTemplate, "Hello", "World!"); byte[] msg = Encoding.UTF8.GetBytes(message); SendNotification(msg, Channel.ChannelUri, 2,"toast"); }
В этом случае значение 2, указанное в методе SendNotification
указывает на немедленное уведомление о тосте. Обратите внимание, что вам также необходимо указать параметр targetHeader
для «toast».
Плитка Уведомление
Как и в случае с всплывающими уведомлениями, для того, чтобы устройство обрабатывало уведомление о плитке, пока приложение не запущено, необходимо сообщить об этом операционной системе. Это делается с BindToShellTile
метода BindToShellTile
. Обратите внимание, что, поскольку вы можете обновить Live Tile фоновым изображением с удаленного сервера, метод BindToShellTile
может принять коллекцию доменов в качестве параметра. В фоновом уведомлении могут быть указаны только фоновые изображения из этих доменов (или локальных плиток, поставляемых с приложением).
Channel = new HttpNotificationChannel(ChannelName); Channel.ChannelUriUpdated += HttpChannelChannelUriUpdated; Channel.Open(); var allowedDomains = new Collection<Uri>(); allowedDomains.Add(new Uri("Http://www.builttoroam.com")); Channel.BindToShellTile(allowedDomains);
При получении уведомления о плитке в приложении не возникает никаких событий, даже если приложение работает. Как и в случае с всплывающими уведомлениями, отправка уведомления в виде плитки требует только правильного сообщения в формате XML.
private void SendTileClick(object sender, RoutedEventArgs e) { var messageTemplate = "<?XML version="1.0" encoding="utf-8"?>" + "<wp:Notification XMLns:wp="WPNotification">" + "<wp:Tile>" + "<wp:BackgroundImage>{0}</wp:BackgroundImage>" + "<wp:Count>{1}</wp:Count>" + "<wp:Title>{2}</wp:Title>" + "</wp:Tile> " + "</wp:Notification>"; var message = string.Format(messageTemplate, "Background2.jpg", 5, "New Title"); byte[] msg = Encoding.UTF8.GetBytes(message); SendNotification(msg, Channel.ChannelUri, 1, "token"); }
Обратите внимание, что «1» указывает, что уведомление плитки должно быть отправлено немедленно и что targetHeader должен быть «токеном» (а не «плиткой», как вы ожидали). Это конкретное обновление плитки ссылается на другое изображение, Background2.jpg, которое упаковано как Контент в файле XAP приложения, значок 5 и новый заголовок, который будет отображаться, как показано на рисунке 2.
В этом посте вы увидели очень быстрый обзор настройки приложения для получения уведомлений, а также того, как вы можете отправлять необработанные, всплывающие и мозаичные уведомления на устройство.