设为首页 收藏本站
查看: 1291|回复: 0

Windows phone 8 学习笔记(5) 图块与通知

[复制链接]

尚未签到

发表于 2015-5-22 13:34:55 | 显示全部楼层 |阅读模式
  基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标。一般一个应用必须有一个默认图块,还可以有若干个次要图块。另外,通知与图块的关系比较密切,我们可以通过在接受到消息时动态更新图块来达到适时的效果。我们本节把图块和通知放在一起讲。
  快速导航:
    一、图块
    二、图块更新计划
    三、本地通知
    四、推送通知

一、图块

1)定义默认图块
  默认图块只能在清单文件中定义它,并且选定的图块模板后就不能再改变,除非重新发布应用,但是我们可以更新同类型的模板。应用安装后默认状态不会出现在开始菜单,需要在程序清单中右键选择固定到开始屏幕项。
  图块模板类型:
    1.图标模版:它可以包含大小两种图标,三种图块都可以用。必须为包含透明背景的png格式metro风格图片。
    2.翻转模版:在中型、大型图块中可以实现翻转效果。
    3.循环模板:在中型、大型图块中实现多张背景图轮流切换。

2)创建更新图块
  图块的创建和更新可以通过两种方式,分别是定义模版xml或通过代码构建,下面的代码演示了如何创建和更新图块。

[C#]


    public partial class MainPage : PhoneApplicationPage
{
// 构造函数
public MainPage()
{
InitializeComponent();
// 用于本地化 ApplicationBar 的示例代码
//BuildLocalizedApplicationBar();
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
CreateTitle();
}

private void ShowTitle()
{
var tilte = ShellTile.ActiveTiles.FirstOrDefault();
if (tilte != null)
{
MessageBox.Show(tilte.NavigationUri.ToString());
}
}
//图标图块
IconicTileData iconicTileData = new IconicTileData()
{
Title = "标题",
Count = 5,
WideContent1 = "第一行文本",
WideContent2 = "第二行文本",
WideContent3 = "第三行文本",
SmallIconImage = new Uri("/Assets/Tiles/IconLarge.png", UriKind.Relative),
IconImage = new Uri("/Assets/Tiles/IconSamall.png", UriKind.Relative),
//透明度设置为255才会显示自定义颜色背景,否则显示为系统背景
BackgroundColor = new Color { A = 255, R = 0, G = 148, B = 255 }
};
//图标图块模板
string iconicTileXml = @"


/Assets/Tiles/IconLarge.png
/Assets/Tiles/IconSamall.png
第一行文本
第二行文本
第三行文本
6
标题
#FF524742

";
//可用于清除Count(如果加了Action="Clear",则清除该项的显示)
string iconicTileXml2 = @"


0

";
//翻转图块
FlipTileData flipTileData = new FlipTileData()
{
Title = "标题",
BackTitle = "背面标题",
BackContent = "背面的文本内容部分",
WideBackContent = "在宽图块背面的文本内容",
Count = 5,
SmallBackgroundImage = new Uri("/Assets/Tiles/Samall.png", UriKind.Relative),
BackgroundImage = new Uri("/Assets/Tiles/Medium.png", UriKind.Relative),
//不设置背景图像则显示为系统背景色
//BackBackgroundImage = new Uri("Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative),
WideBackgroundImage = new Uri("/Assets/Tiles/Large.png", UriKind.Relative),
//WideBackBackgroundImage = new Uri("/Assets/Tiles/IconicTileMediumLarge.png", UriKind.Relative)
};
//翻转图块模板
string flipTileXml = @"


/Assets/Tiles/Samall.png
/Assets/Tiles/Large.png
/Assets/Tiles/IconicTileMediumLarge.png
在宽图块背面的文本内容
/Assets/Tiles/Medium.png
6
标题
Assets/Tiles/FlipCycleTileMedium.png
背面标题
背面的文本内容部分

";

//循环图块
CycleTileData cycleTileData = new CycleTileData()
{
Title = "标题",
Count = 10,
SmallBackgroundImage = new Uri("/Assets/Tiles/Samall.png", UriKind.Relative),
CycleImages = new Uri[]
{
new Uri("/Assets/Tiles/Title1.png", UriKind.Relative),
new Uri("/Assets/Tiles/Title2.png", UriKind.Relative),
new Uri("/Assets/Tiles/Title3.png", UriKind.Relative),
}
};
//循环图块模板
string cycleTileXml = @"


/Assets/Tiles/Samall.png
/Assets/Tiles/Title1.png
/Assets/Tiles/Title2.png
/Assets/Tiles/Title3.png
6
标题

";

private void CreateTitle()
{
//添加一个次要图块
ShellTile.Create(new Uri("/Page1.xaml", UriKind.Relative), iconicTileData, true);
//通过xml模板添加
ShellTile.Create(new Uri("/Page1.xaml", UriKind.Relative), new IconicTileData(iconicTileXml), true);
}
private void ClearCount()
{
//清除Count
ShellTile.ActiveTiles.ElementAt(1).Update(new IconicTileData(iconicTileXml2));
}
private void UpdateTitle()
{
//更新默认图块的内容,我们定义的翻转模版,这里不能修改模版类型
ShellTile.ActiveTiles.FirstOrDefault().Update(flipTileData);
}
}

  

二、图块更新计划
  我们可以定义一个更新计划,定期的更新图块的背景图像。当应用退出以后,这个更新计划依然能够在后台运行。它的实现代码如下:

[C#]  


        ShellTileSchedule SampleTileSchedule = new ShellTileSchedule();
//计划是否已经执行
bool TileScheduleRunning = false;
//开始执行计划
private void Button_Click_1(object sender, RoutedEventArgs e)
{
//指定计划执行一次还是多次
SampleTileSchedule.Recurrence = UpdateRecurrence.Interval;
//指定计划的更新间隔时间
SampleTileSchedule.Interval = UpdateInterval.EveryHour;
//指定计划的执行次数,如果未设置,则为不确定次数
SampleTileSchedule.MaxUpdateCount = 50;
//指定计划的开始时间
SampleTileSchedule.StartTime = DateTime.Now;
//获取背景图像的网络URI
SampleTileSchedule.RemoteImageUri = new Uri(@"http://images.iyunv.com/cnblogs_com/lipan/319399/o_Large.png");
SampleTileSchedule.Start();
}
//停止计划
private void Button_Click_2(object sender, RoutedEventArgs e)
{
if (TileScheduleRunning) SampleTileSchedule.Stop();
}

  

三、本地通知
  通知分为本地通知和推送通知。我们可以通过本地通知实现本地消息和提醒功能。

1)本地消息和提醒
  我们可以定义提醒和闹钟的功能,在应用退出以后,当计划的提醒时间达到时,提醒或者闹钟功能将自动别触发,其中闹钟的功能我们还可以自定义铃声。下面看看代码实现的过程。

[XAML]


        






























[C#]


    public partial class Page1 : PhoneApplicationPage
{
public Page1()
{
InitializeComponent();
}
IEnumerable notifications;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ListboxInit();
base.OnNavigatedTo(e);
}
private void ListboxInit()
{
//返回系统所有已注册的通知
notifications = ScheduledActionService.GetActions();
listbox1.ItemsSource = notifications;
}
//删除一个通知
private void deleteButton_Click(object sender, RoutedEventArgs e)
{
string name = (string)((Button)sender).Tag;
ScheduledActionService.Remove(name);
ListboxInit();
}
//新增一个通知
private void Button_Click_1(object sender, RoutedEventArgs e)
{
String name = System.Guid.NewGuid().ToString();
if (radioButton1.IsChecked == true)
{
//名称,唯一标识
Reminder reminder = new Reminder(name);
//消息标题
reminder.Title = textbox1.Text;
reminder.Content = "这里是提醒的正文部分。";
//消息重现类型
reminder.RecurrenceType = RecurrenceInterval.Daily;
//开始时间
reminder.BeginTime = DateTime.Now + new TimeSpan(0, 0, 30);
//结束时间
reminder.ExpirationTime = DateTime.Now + new TimeSpan(0, 0, 45);
//从提醒启动应用程序时的启动URI
reminder.NavigationUri = new Uri("/Page2.xaml?a=test", UriKind.Relative);
//注册
ScheduledActionService.Add(reminder);
}
else
{
//可以自定义铃声的通知
Alarm alarm = new Alarm(name);
alarm.Content = "这里是闹钟的正文部分。";
//提醒时播放的文件
alarm.Sound = new Uri("/1.mp3", UriKind.Relative);
//消息重现类型
alarm.RecurrenceType = RecurrenceInterval.Daily;
//开始时间
alarm.BeginTime = DateTime.Now + new TimeSpan(0, 0, 30);
//结束时间
alarm.ExpirationTime = DateTime.Now + new TimeSpan(0, 1, 30);
//注册
ScheduledActionService.Add(alarm);
}
ListboxInit();
}
}

2)本地Toast
  通过本地Toast可以在实现Toast消息弹出,但是当应用运行时则不会弹出,所以一般在后台计划中被调用。详细情况请见《Windows phone 8 学习笔记 多任务 后台代理》 。
  

四、推送通知
  推送通知都需要借助于微软推送云服务器,因为一般来讲,应用退出以后是不会保留后台服务去等待接受消息的,这种做法比较费电。推送通知的做法是,当有消息推送过来的时候,由系统去统一完成消息的接收,用户选择性的去启动应用。

1. 推送通知的类型
  推送通知主要有三种类型,如下:
    1.磁贴通知:消息到达时,将会更新应用的默认图块,这样直观的现实当前应用有更新内容。
    2.Toast推送通知:消息到达时,将会在屏幕上方弹出一个Toast提示,用户单击即可启动应用。
    3.raw通知:这个通知在应用运行的前提下,提供灵活的消息处理,但是非允许状态下将无法接受消息。

2. 推送通知的实现
  要实现推送通知,首先我们需要建立推送通道。在Windows phone 中建立推送通道,并且得到通道的URI。代码如下:

[C# Windows phone]


        //磁贴通知
private void TileInit()
{
//推送服务通道
HttpNotificationChannel pushChannel;
//通道名称
string channelName = "TileSampleChannel";
InitializeComponent();
//尝试发现是否已经创建
pushChannel = HttpNotificationChannel.Find(channelName);
var newChannel = false;
//没有发现,新建一个
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
newChannel = true;
}
//通知通道关联URI改变时:
pushChannel.ChannelUriUpdated += new EventHandler(PushChannel_ChannelUriUpdated);
//出错时:
pushChannel.ErrorOccurred += new EventHandler(PushChannel_ErrorOccurred);
if (newChannel)
{
pushChannel.Open();
//将通知订阅绑定到默认图块
pushChannel.BindToShellTile();
}
else
{
MessageBox.Show(String.Format("通道URI: {0}", pushChannel.ChannelUri.ToString()));
}
}
//Toast通知
private void ToastInit()
{
//推送服务通道
HttpNotificationChannel pushChannel;
//通道名称
string channelName = "ToastSampleChannel";
InitializeComponent();
//尝试发现是否已经创建
pushChannel = HttpNotificationChannel.Find(channelName);
var newChannel = false;
//没有发现,新建一个
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
newChannel = true;
}
//通知通道关联URI改变时:
pushChannel.ChannelUriUpdated += new EventHandler(PushChannel_ChannelUriUpdated);
//出错时:
pushChannel.ErrorOccurred += new EventHandler(PushChannel_ErrorOccurred);
//收到Toast消息时:(如果程序未启动则弹出Toast,否则触发该事件)
pushChannel.ShellToastNotificationReceived += new EventHandler(PushChannel_ShellToastNotificationReceived);
if (newChannel)
{
pushChannel.Open();
//将通知订阅绑定到ShellToast
pushChannel.BindToShellToast();
}
else
{
MessageBox.Show(String.Format("通道URI: {0}", pushChannel.ChannelUri.ToString()));
}
}
//Row通知
private void RawInit()
{
//推送服务通道
HttpNotificationChannel pushChannel;
//通道名称
string channelName = "RawSampleChannel";
InitializeComponent();
//尝试发现是否已经创建
pushChannel = HttpNotificationChannel.Find(channelName);
var newChannel = false;
//没有发现,新建一个
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
newChannel = true;
}
//通知通道关联URI改变时:
pushChannel.ChannelUriUpdated += new EventHandler(PushChannel_ChannelUriUpdated);
//出错时:
pushChannel.ErrorOccurred += new EventHandler(PushChannel_ErrorOccurred);
//收到Raw通知时:(只有应用运行时才触发本事件)
pushChannel.HttpNotificationReceived += new EventHandler(PushChannel_HttpNotificationReceived);

if (newChannel)
{
pushChannel.Open();
//这里并没有绑定操作
}
else
{
MessageBox.Show(String.Format("通道URI: {0}", pushChannel.ChannelUri.ToString()));
}
}

//URI更新时
void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(String.Format("通道URI: {0}", e.ChannelUri.ToString()));
});
}
//遇到错误时
void PushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
{
//处理错误
}
//收到Toast通知时
void PushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
StringBuilder message = new StringBuilder();
string relativeUri = string.Empty;
message.AppendFormat("收到 Toast {0}:\n", DateTime.Now.ToShortTimeString());
foreach (string key in e.Collection.Keys)
{
message.AppendFormat("{0}: {1}\n", key, e.Collection[key]);
if (key.ToLower() == "wp:param") relativeUri = e.Collection[key];
}
Dispatcher.BeginInvoke(() => MessageBox.Show(message.ToString()));
}
//收到Raw通知时:
void PushChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
{
string message;
using (System.IO.StreamReader reader = new System.IO.StreamReader(e.Notification.Body))
{
message = reader.ReadToEnd();
}
Dispatcher.BeginInvoke(() =>
MessageBox.Show(String.Format("收到 Row {0}:\n{1}",
DateTime.Now.ToShortTimeString(), message))
);
}

  得到推送URI后,我们需要一个web服务端,这个服务端就是我们用来向自己的应用发送推送消息的地方,如果web端用.net实现,那么实现方式如下:

[C# .Net]


        //发送磁贴消息
private void SendTile()
{
try
{
string subscriptionUri = TextBoxUri.Text.ToString();
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
httpWebRequest.Method = "POST";
string tileMessage = "" +
"" +
"" +
"/Assets/Tiles/FlipCycleTileMedium.png" +
"5" +
"标题" +
"" +
"背面标题" +
"背面文本内容" +
" " +
"";
byte[] notificationMessage = Encoding.Default.GetBytes(tileMessage);
httpWebRequest.ContentLength = notificationMessage.Length;
httpWebRequest.ContentType = "text/xml";
//X-WindowsPhone-Target设置为token
httpWebRequest.Headers.Add("X-WindowsPhone-Target", "token");
//Tile消息类型为 1
httpWebRequest.Headers.Add("X-NotificationClass", "1");

using (Stream requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

}
catch (Exception ex)
{
}
}
//发送Toast消息
private void SendToast()
{
try
{
//这个URI就是通道创建时由WP客户端获取到的,需要提交到服务端
string uri = TextBoxUri.Text.ToString();
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
httpWebRequest.Method = "POST";
string toastMessage = "" +
"" +
"" +
"标题" +
"内容部分" +
"/Page2.xaml?NavigatedFrom=ToastNotification" +
" " +
"";
byte[] notificationMessage = Encoding.Default.GetBytes(toastMessage);
//设置请求头
httpWebRequest.ContentLength = notificationMessage.Length;
httpWebRequest.ContentType = "text/xml";
//X-WindowsPhone-Target设置为toast
httpWebRequest.Headers.Add("X-WindowsPhone-Target", "toast");
//Toast消息类型为 2
httpWebRequest.Headers.Add("X-NotificationClass", "2");
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
//获取相应头包含的状态信息
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
}
catch (Exception ex)
{
}
}
//发送Raw消息
private void SendRaw()
{
try
{
string subscriptionUri = TextBoxUri.Text.ToString();
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
httpWebRequest.Method = "POST";
//这里的消息内容完全自定义,也可以为非xml
string rawMessage = "" +
"" +
"a" +
"b" +
"";
byte[] notificationMessage = Encoding.Default.GetBytes(rawMessage);
httpWebRequest.ContentLength = notificationMessage.Length;
httpWebRequest.ContentType = "text/xml";
//没有 X-WindowsPhone-Target 头
//Raw消息类型为 3
httpWebRequest.Headers.Add("X-NotificationClass", "3");
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

}
catch (Exception ex)
{
}
}

  


作者:[Lipan]
出处:[http://www.iyunv.com/lipan/]
版权声明:本文的版权归作者与博客园共有。转载时须注明原文出处以及作者,并保留原文指向型链接,不得更改原文内容。否则作者将保留追究其法律责任。

《上一篇:Windows phone 8 学习笔记 应用的启动 系列目录 下一篇:Windows phone 8 学习笔记 多任务》

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-69613-1-1.html 上篇帖子: [Windows Phone 8开发系统]1. 环境搭建与创建第一个项目! 下篇帖子: Windows 8开发 ApplicationBar的图标与对应的Unicode编码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表