Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Так ли нужна одновременная работа нескольких приложений в фоновом режиме? На самом деле, в большинстве случаев, нам нужно, чтобы приложение имело возможность оповестить пользователя о том, что что-то изменилось или необходимы какие-то действия с его стороны. И в этой части серии статей мы познакомимся с возможностями системы, которые позволяют нам оповещать пользователя, напоминать ему или даже предоставлять саму востребованную информацию без необходимости запускать приложение!
Предупреждения (Alarm) и напоминания (Reminder)
Приложения в Windows Phone могут использовать оповещения двух типов: предупреждения (Alarms) и напоминания (Reminders), которые будут отображаться пользователю в виде диалоговых окон, по расписанию. Интерфейс оповещений и напоминаний соответствует тому, который используют системные приложения. Это позволяет сторонним приложениям общаться с пользователем на знакомом ему языке системного интерфейса.
Объекты Alarm и Reminder наследуются от класса ScheduledNotification и имеют достаточно много общего, однако, есть и определенный отличия. Классический вариант оповещения Alarm – это будильник, а оповещения Reminder – напоминание о событии в календаре.
Обратите внимание, что каждое приложение может зарегистрировать до 50 оповещений, а точность отображения пользователю – около минуты.
Давайте кратко рассмотрим основные параметры оповещений.
Предупреждения (Alarm)
Предупреждение (Alarm) отображается пользователю в виде диалогового окна с 2-мя кнопками отложить (snooze) и закрыть (dismiss), а также тремя текстовыми блоками. Верхний блок – название приложения, которое зарегистрировало предупреждение. Далее, текстовый блок, который отображается всегда и не может быть изменён с надписью Будильник (Alarm) и, самый последний блок – текст, который был указан при создании предупреждения.
Предупреждение (Alarm) позволяет указать звуковой файл, который будет проигран при отображении его пользователю, он проигрывается с нарастающей громкостью.
Если пользователь коснётся любой области оповещения, кроме кнопок, будет загружено основное приложение и отобразится его начальная страница, так, как будто пользователь запустил его из списка программ.
Напоминание (Reminder)
Напоминание (Reminder) отображается пользователю в виде диалогового окна с 2-мя кнопками, выпадающим списком для выбора, на сколько отложить оповещение и тремя текстовыми блоками.
Верхний блок – название приложения, которое зарегистрировало предупреждение. Далее, текстовый блок, который отображает заголовок оповещения, который был указан при его создании, и, самый последний блок – текст – содержание напоминания, указанный при создании.
Если пользователь коснётся любой области оповещения, кроме кнопок, будет загружено основное приложение, при этом, разработчик, при создании напоминания может указать URI страницы с параметрами, на которые перейдёт пользователь.
В отличие от предупреждения (Alarm) будет вегда использоваться звук для оповещения установленный в настройках устройства.
Пример работы с Alarm и Reminder
Давайте теперь на практике попробуем разобраться с оповещениями.
Создадим новое приложение на базе стандартного шаблона Windows Phone Application и назовём приложение SimpleNotificationManager.
После того, как проект приложения будет создан, добавьте в приложение поддержку Silverlight for Windows Phone Toolkit.
Убедитесь, что у вас установлен NuGet Package Manager (Tools -> Extension Manager …)
При необходимости – установите.
После этого в меню Visual Studio выберите, Tools -> Library Package Manager -> Manage NuGet Packages …
Откроется графическая утилита установки пактов NuGet. Найдите и установите пакет Silverlight for Windows Phone Toolkit.
После этого, ваш проект будет выглядеть следующим образом.
Перед тем, как продолжить, для всех картинок в папке Toolkit.Content установите тип сборки (Build Action) в Content (по умолчанию стоит Resource).
Итак, Silverlight for Windows Phone Toolkit подключён к проекту. Давайте добавим, как мы это уже делали ранее, пространство имён toolkit в XAML файл MainPage.xaml, чтобы использовать элементы управления из Silverlight for Windows Phone Toolkit на нашей главной странице:
Мы добавили следующую строку:
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
И в результате XAML будет выглядеть следующим образом:
<phone:PhoneApplicationPage
x:Class="SimpleNotificationManager.MainPage"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
Теперь нужно сделать интерфейс создания оповещений. Нужен выбор типа, выбор времени оповещения, заголовка (в случае напоминания) и содержания. Я сделал простой интерфейс на базе комбинации элементов управления StackPanel:
При этом, XAML код страницы MainPage.xaml (внутри тега phone:PhoneApplicationPage) выглядит следующим образом:
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="МЕНЕДЖЕР ОПОВЕЩЕН�Й"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="установка" Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<RadioButton Content="предупреждение" GroupName="NotificationType"
Name="AlarmType" IsChecked="True" />
<RadioButton Content="напоминание" GroupName="NotificationType"
Name="ReminderType" />
<StackPanel Orientation="Horizontal" Margin="15,0,0,0">
<TextBlock Text="дата и время" FontSize="22.667"
VerticalAlignment="Center"/>
<toolkit:DatePicker Name="NotificationDate"/>
<toolkit:TimePicker Name="NotificationTime"/>
</StackPanel>
<StackPanel Margin="15,15,0,0">
<TextBlock Name="NotificationTitleCaption" Text="заголовок оповещения"
FontSize="22.667" VerticalAlignment="Center" Visibility="Collapsed"/>
<TextBox Name="NotificationTitle" FontSize="22.667"
Margin="-10,0,0,0" Visibility="Collapsed"/>
<TextBlock Text="текст оповещения" FontSize="22.667"
VerticalAlignment="Center"/>
<TextBox Name="NotificationText" FontSize="22.667" Margin="-10,0,0,0"/>
</StackPanel>
<Button Content="установить" Name="SetNotification" FontSize="22.667" Width="450"/>
<Button Content="посмотреть список" Name="CheckNotification" FontSize="22.667" Width="450" />
</StackPanel>
</Grid>
</Grid>
В зависимости от того, какой тип оповещения создаётся, поле ввода для заголовка оповещения и соответствующий текстовый блок с названием поля либо отображаются, либо нет. По умолчанию, выбрано предупреждение и эти элементы управления не отображаются. Нам необходимо обрабатывать изменения типа создаваемого оповещения и либо отображать, либо не отображать этот блок.
Если мы назначим обработчики изменения состояний радио-кнопок в XAML коде, может сложиться такая ситуация, что они сработают ещё до того, как создадутся элементы управления, которые мы хотим скрывать/показывать. Поэтому, мы добавим в код обработчик события Loaded страницы, а уже в него добавим регистрацию обработчиков изменения состояния радио-кнопок:
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
AlarmType.Checked +=new RoutedEventHandler(AlarmType_Checked);
ReminderType.Checked +=new RoutedEventHandler(ReminderType_Checked);
}
И напишем обработчики событий радио-кнопок:
private void AlarmType_Checked(object sender, RoutedEventArgs e)
{
NotificationTitleCaption.Visibility = System.Windows.Visibility.Collapsed;
NotificationTitle.Visibility = System.Windows.Visibility.Collapsed;
}
private void ReminderType_Checked(object sender, RoutedEventArgs e)
{
NotificationTitleCaption.Visibility = System.Windows.Visibility.Visible;
NotificationTitle.Visibility = System.Windows.Visibility.Visible;
}
Теперь осталось добавим код, который собственно и создаёт предупреждения и напоминания.
Для упрощения кода, разрешим нашему приложению в каждый момент времени иметь только одно предупреждение и одно напоминание. Зададим для них имена (должны быть уникальными среди всех, создаваемых приложением оповещений) в виде констант в классе:
const string MY_ALARM = "My Alarm";
const string MY_REMINDER = "My Reminder";
Обратите внимание, что для использования объектов Alarm и Reminder необходимо добавить следующую запись в блок using:
using Microsoft.Phone.Scheduler;
Теперь напишем две простые функции, которые будут создавать Alarm и Reminder соответственно.
private void CreateAlarm()
{
DateTime date = (DateTime)NotificationDate.Value;
DateTime time = (DateTime)NotificationTime.Value;
DateTime beginTime = date + time.TimeOfDay;
if (beginTime < DateTime.Now)
{
MessageBox.Show("Указанное время оповещения уже прошло!");
return;
}
if (ScheduledActionService.Find(MY_ALARM) != null)
ScheduledActionService.Remove(MY_ALARM);
Alarm myAlarm = new Alarm(MY_ALARM);
myAlarm.Content = NotificationText.Text;
myAlarm.RecurrenceType = RecurrenceInterval.None;
myAlarm.BeginTime = beginTime;
myAlarm.ExpirationTime = beginTime.AddMinutes(5);
ScheduledActionService.Add(myAlarm);
}
private void CreateReminder()
{
DateTime date = (DateTime)NotificationDate.Value;
DateTime time = (DateTime)NotificationTime.Value;
DateTime beginTime = date + time.TimeOfDay;
if (beginTime < DateTime.Now)
{
MessageBox.Show("Указанное время оповещения уже прошло!");
return;
}
if (ScheduledActionService.Find(MY_REMINDER) != null)
ScheduledActionService.Remove(MY_REMINDER);
Reminder myReminder = new Reminder(MY_REMINDER);
myReminder.Title = NotificationTitle.Text;
myReminder.Content = NotificationText.Text;
myReminder.RecurrenceType = RecurrenceInterval.None;
myReminder.BeginTime = beginTime;
myReminder.ExpirationTime = beginTime.AddMinutes(5);
myReminder.NavigationUri = new Uri("/NotificationList.xaml",UriKind.RelativeOrAbsolute);
ScheduledActionService.Add(myReminder);
}
Давайте взглянем на код функций поближе.
Перед созданием мы выполняем простую проверку, что время, на которые мы хотим назначить оповещение еще не прошло:
DateTime date = (DateTime)NotificationDate.Value;
DateTime time = (DateTime)NotificationTime.Value;
DateTime beginTime = date + time.TimeOfDay;
if (beginTime < DateTime.Now)
{
MessageBox.Show("Указанное время оповещения уже прошло!");
return;
}
Затем, поскольку по дизайну приложения, мы можем иметь только одно предупреждение и одно оповещение, мы ищем, присутствует ли уже ранее созданное оповещение и если оно присутствует, удаляем его.
Ниже, для примера приведён пример для Alarm:
if (ScheduledActionService.Find(MY_ALARM) != null)
ScheduledActionService.Remove(MY_ALARM);
Дальше, в обоих функциях создаётся однократное оповещение, которое закончится через 5 минут, после указанного времени.
При этом, для типа Reminder мы задаём заголовок и URI перехода, при нажатии на область уведомления.
Reminder myReminder = new Reminder(MY_REMINDER);
myReminder.Title = NotificationTitle.Text;
myReminder.Content = NotificationText.Text;
myReminder.RecurrenceType = RecurrenceInterval.None;
myReminder.BeginTime = beginTime;
myReminder.ExpirationTime = beginTime.AddMinutes(5);
myReminder.NavigationUri = new Uri("/NotificationList.xaml",
UriKind.RelativeOrAbsolute);
ScheduledActionService.Add(myReminder);
Теперь осталось добавить в XAML код ссылку на обработчик события Click:
<Button Content="установить" Name="SetNotification" FontSize="22.667"
Width="450" Click="SetNotification_Click" />
И добавить в код простой обработчик:
private void SetNotification_Click(object sender, RoutedEventArgs e)
{
if ((bool)AlarmType.IsChecked)
CreateAlarm();
if ((bool)ReminderType.IsChecked)
CreateReminder();
}
Соберите приложение, запустите его (F5) и проверьте, как оно работает.