mirror of
https://github.com/farcasclaudiu/myfriendsaround.git
synced 2026-06-29 01:01:58 +03:00
push notification helper library
http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/01/14/windows-push-notification-server-side-helper-library.aspx http://create.msdn.com/en-us/education/catalog/article/pnhelp-wp7
This commit is contained in:
+79
@@ -0,0 +1,79 @@
|
||||
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Views.InboxView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:tk="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||
FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||
d:DesignHeight="480" d:DesignWidth="480">
|
||||
|
||||
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="Views">
|
||||
<VisualState x:Name="NormalView" />
|
||||
<VisualState x:Name="ScheduleView">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="TileScheduleView" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="120"/>
|
||||
<RowDefinition Height="120"/>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel d:LayoutOverrides="Height">
|
||||
<TextBlock Margin="12,12,0,0" Text="Active Push Pattern" FontSize="24" />
|
||||
<ListBox ItemsSource="{Binding PushPatterns}"
|
||||
IsHitTestVisible="False"
|
||||
SelectedItem="{Binding PushPattern, Mode=TwoWay}"
|
||||
ItemsPanel="{StaticResource ItemsPanelTemplate}"
|
||||
ItemContainerStyle="{StaticResource PatternListBoxItemStyle}"
|
||||
HorizontalAlignment="Center">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
TextAlignment="Center" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" d:LayoutOverrides="Height">
|
||||
<TextBlock Margin="12,12,0,0" Text="Counter (if relevant)" FontSize="24" />
|
||||
<TextBlock Margin="12,12,0,0" Text="{Binding Counter}" Foreground="LightBlue" />
|
||||
</StackPanel>
|
||||
<TextBlock Margin="12,12,0,17" Text="Raw Messages (last on top)" Grid.Row="2" d:LayoutOverrides="Height" FontSize="24" />
|
||||
<ListBox ItemsSource="{Binding RawMessages}" Grid.Row="4" Margin="12,0,12,80"/>
|
||||
<Border x:Name="TileScheduleView"
|
||||
Grid.Row="1" Grid.RowSpan="3"
|
||||
Visibility="Collapsed"
|
||||
Background="{StaticResource PhoneChromeBrush}">
|
||||
<StackPanel>
|
||||
<TextBlock Margin="12,12,0,17" Text="Tile Image (located on server)" Grid.Row="2" d:LayoutOverrides="Height" FontSize="24" />
|
||||
<ListBox ItemsSource="{Binding ServerImages}"
|
||||
SelectedItem="{Binding SelectedServerImage, Mode=TwoWay}"
|
||||
Margin="12,0,12,0" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Content="Schedule" Click="ButtonSchedule_Click" />
|
||||
<Button Content="Test Now" Click="ButtonTestNow_Click" Grid.Column="1" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Shapes;
|
||||
using System.IO;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading;
|
||||
using Microsoft.Phone.Shell;
|
||||
|
||||
using Microsoft.Phone.Notification;
|
||||
|
||||
using WindowsPhone.Recipes.Push.Client.Services;
|
||||
using WindowsPhone.Recipes.Push.Client.Controls;
|
||||
|
||||
namespace WindowsPhone.Recipes.Push.Client.Views
|
||||
{
|
||||
public partial class InboxView : UserControl
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <value>Url of the GetTileImage REST service.</value>
|
||||
private static readonly string GetTileImageService = App.ServerAddress + "/ImageService/GetTileImage?uri={0}";
|
||||
|
||||
private readonly ObservableCollection<string> _rawMessages = new ObservableCollection<string>();
|
||||
private ShellTileSchedule _tileSchedule;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public ObservableCollection<string> RawMessages
|
||||
{
|
||||
get { return _rawMessages; }
|
||||
}
|
||||
|
||||
public IEnumerable<string> ServerImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return new string[]
|
||||
{
|
||||
"number0.png",
|
||||
"number1.png",
|
||||
"number2.png",
|
||||
"number3.png",
|
||||
"number4.png",
|
||||
"number5.png",
|
||||
"number6.png",
|
||||
"number7.png",
|
||||
"number8.png",
|
||||
"number9.png"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string SelectedServerImage
|
||||
{
|
||||
get { return (string)GetValue(SelectedServerImageProperty); }
|
||||
set { SetValue(SelectedServerImageProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for SelectedServerImage. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty SelectedServerImageProperty =
|
||||
DependencyProperty.Register(
|
||||
"SelectedServerImage",
|
||||
typeof(string),
|
||||
typeof(InboxView),
|
||||
new PropertyMetadata("number0.png"));
|
||||
|
||||
|
||||
|
||||
public IEnumerable<string> PushPatterns
|
||||
{
|
||||
get { return new string[] { "One Time", "Counter", "Ask to Pin", "Custom Tile", "Tile Schedule" }; }
|
||||
}
|
||||
|
||||
public string PushPattern
|
||||
{
|
||||
get { return (string)GetValue(PushPatternProperty); }
|
||||
set { SetValue(PushPatternProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for PushPattern. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty PushPatternProperty =
|
||||
DependencyProperty.Register(
|
||||
"PushPattern",
|
||||
typeof(string),
|
||||
typeof(InboxView),
|
||||
new PropertyMetadata(null, PushPatternChanged));
|
||||
|
||||
private static void PushPatternChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var view = d as InboxView;
|
||||
if ("Tile Schedule".CompareTo(e.NewValue) == 0)
|
||||
{
|
||||
VisualStateManager.GoToState(view, "ScheduleView", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager.GoToState(view, "NormalView", false);
|
||||
}
|
||||
}
|
||||
|
||||
public int Counter
|
||||
{
|
||||
get { return (int)GetValue(CounterProperty); }
|
||||
set { SetValue(CounterProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for Counter. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty CounterProperty =
|
||||
DependencyProperty.Register(
|
||||
"Counter",
|
||||
typeof(int),
|
||||
typeof(InboxView),
|
||||
new PropertyMetadata(0));
|
||||
|
||||
public string TileScheduleParameter
|
||||
{
|
||||
get { return (string)GetValue(TileScheduleParameterProperty); }
|
||||
set { SetValue(TileScheduleParameterProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for TileScheduleParameter. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty TileScheduleParameterProperty =
|
||||
DependencyProperty.Register(
|
||||
"TileScheduleParameter",
|
||||
typeof(string),
|
||||
typeof(InboxView),
|
||||
new PropertyMetadata("number0.png"));
|
||||
|
||||
#endregion
|
||||
|
||||
public InboxView()
|
||||
{
|
||||
DataContext = this;
|
||||
InitializeComponent();
|
||||
|
||||
Loaded += InboxView_Loaded;
|
||||
Unloaded += InboxView_Unloaded;
|
||||
UpdateServerInfo();
|
||||
}
|
||||
|
||||
private void InboxView_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
UnregisterRawNotification();
|
||||
}
|
||||
|
||||
private void InboxView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
RegisterRawNotification();
|
||||
}
|
||||
|
||||
private void UpdateServerInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var pushService = new PushServiceClient();
|
||||
pushService.GetServerInfoCompleted += (s1, e1) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
pushService.CloseAsync();
|
||||
if (e1.Result != null)
|
||||
{
|
||||
Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
PushPattern = e1.Result.PushPattern;
|
||||
Counter = e1.Result.Counter;
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Show();
|
||||
}
|
||||
};
|
||||
|
||||
pushService.GetServerInfoAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Show();
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterRawNotification()
|
||||
{
|
||||
var context = PushContext.Current;
|
||||
if (context != null)
|
||||
{
|
||||
context.RawNotification += context_RawNotification;
|
||||
}
|
||||
}
|
||||
|
||||
private void UnregisterRawNotification()
|
||||
{
|
||||
var context = PushContext.Current;
|
||||
if (context != null)
|
||||
{
|
||||
context.RawNotification -= context_RawNotification;
|
||||
}
|
||||
}
|
||||
|
||||
private void context_RawNotification(object sender, HttpNotificationEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var stream = new StreamReader(e.Notification.Body))
|
||||
{
|
||||
var rawMessage = stream.ReadToEnd();
|
||||
_rawMessages.Insert(0, rawMessage);
|
||||
if ("AskToPin".CompareTo(rawMessage) == 0)
|
||||
{
|
||||
AskToPin();
|
||||
}
|
||||
|
||||
UpdateServerInfo();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Show();
|
||||
}
|
||||
}
|
||||
|
||||
private void AskToPin()
|
||||
{
|
||||
NotificationBox.Show("Important", "Please pin your application to Start Screen so this application can work properly.");
|
||||
}
|
||||
|
||||
private void ButtonSchedule_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_tileSchedule = new ShellTileSchedule();
|
||||
_tileSchedule.Recurrence = UpdateRecurrence.Interval;
|
||||
_tileSchedule.StartTime = DateTime.Now;
|
||||
_tileSchedule.Interval = UpdateInterval.EveryHour;
|
||||
_tileSchedule.RemoteImageUri = new Uri(string.Format(GetTileImageService, TileScheduleParameter));
|
||||
_tileSchedule.Start();
|
||||
}
|
||||
|
||||
private void ButtonTestNow_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var pushService = new PushServiceClient();
|
||||
pushService.UpdateTileCompleted += (s1, e1) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
pushService.CloseAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Show();
|
||||
}
|
||||
};
|
||||
|
||||
pushService.UpdateTileAsync(PushContext.Current.NotificationChannel.ChannelUri, SelectedServerImage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WindowsPhone.Recipes.Push.Client.Views
|
||||
{
|
||||
public class LoginEventArgs : EventArgs
|
||||
{
|
||||
public Exception Exception { get; private set; }
|
||||
|
||||
public LoginEventArgs(Exception exception = null)
|
||||
{
|
||||
Exception = exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Views.PushSettingsView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:my="clr-namespace:WindowsPhone.Recipes.Push.Client.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||
FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||
d:DesignHeight="628" d:DesignWidth="480">
|
||||
|
||||
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
|
||||
<my:PushSettingsControl x:Name="settingsControl" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace WindowsPhone.Recipes.Push.Client.Views
|
||||
{
|
||||
public partial class PushSettingsView : UserControl
|
||||
{
|
||||
public PushSettingsView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Views.UserLoginView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
|
||||
xmlns:my="clr-namespace:WindowsPhone.Recipes.Push.Client.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||
FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||
d:DesignHeight="480" d:DesignWidth="480">
|
||||
|
||||
<!--ContentPanel - place additional content here-->
|
||||
<Grid x:Name="LayoutRoot">
|
||||
<my:ProgressBarWithText x:Name="progress" Margin="0,-40,0,0" Text="Login..." FontSize="24" ShowProgress="True" Visibility="Collapsed" />
|
||||
<StackPanel x:Name="login" Visibility="Collapsed">
|
||||
<StackPanel>
|
||||
<TextBlock Text="User Name" />
|
||||
<TextBox x:Name="textBoxUserName" Text="{Binding UserName, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
<Button x:Name="buttonLogin" Content="Login" Click="ButtonLogin_Click" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Shapes;
|
||||
using System.IO.IsolatedStorage;
|
||||
|
||||
using WindowsPhone.Recipes.Push.Client.Services;
|
||||
using System.Threading;
|
||||
|
||||
namespace WindowsPhone.Recipes.Push.Client.Views
|
||||
{
|
||||
public partial class UserLoginView : UserControl
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private readonly IsolatedStorageSettings Settings = IsolatedStorageSettings.ApplicationSettings;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public string UserName { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler<LoginEventArgs> Login;
|
||||
|
||||
#endregion
|
||||
|
||||
public UserLoginView()
|
||||
{
|
||||
DataContext = this;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
Loaded += UserLoginView_Loaded;
|
||||
}
|
||||
|
||||
private void UserLoginView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string userName;
|
||||
if (!Settings.TryGetValue("LoginPage.UserName", out userName))
|
||||
{
|
||||
login.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserName = userName;
|
||||
InternalLogin();
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonLogin_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
Settings["LoginPage.UserName"] = UserName;
|
||||
login.Visibility = Visibility.Collapsed;
|
||||
InternalLogin();
|
||||
}
|
||||
|
||||
private void OnLogin(LoginEventArgs args)
|
||||
{
|
||||
if (Login != null)
|
||||
{
|
||||
Login(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
private void InternalLogin()
|
||||
{
|
||||
login.Visibility = Visibility.Collapsed;
|
||||
progress.Visibility = Visibility.Visible;
|
||||
|
||||
var pushContext = PushContext.Current;
|
||||
pushContext.Connect(c => RegisterClient(c.ChannelUri));
|
||||
}
|
||||
|
||||
private void RegisterClient(Uri channelUri)
|
||||
{
|
||||
// Register the URI with 3rd party web service.
|
||||
try
|
||||
{
|
||||
var pushService = new PushServiceClient();
|
||||
pushService.RegisterCompleted += (s, e) =>
|
||||
{
|
||||
pushService.CloseAsync();
|
||||
|
||||
Completed(e.Error);
|
||||
};
|
||||
|
||||
pushService.RegisterAsync(UserName, channelUri);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Completed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void Completed(Exception ex)
|
||||
{
|
||||
login.Visibility = Visibility.Visible;
|
||||
progress.Visibility = Visibility.Collapsed;
|
||||
|
||||
Dispatcher.BeginInvoke(() => OnLogin(new LoginEventArgs(ex)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user