通常情况下,WP7不支持第三方应用程序后台运行,如何让应用程序可以在后台进行实时的更新数据呢,例如新浪微博可以再后台获取新消息,然后显示条目在【开始】界面的磁贴上
这种可以通过创建计划任务代理来实现后台程序功能
先放效果
这里绿色的磁铁为后台自动更新的,这样可以实现每天更新一次日期
1、首先,在工程中添加一个项目 Windows Phone 计划任务代理,命名为MyScheduledTaskAgent
重写 ScheduledAgent 类的 OnInvoke() 方法,把需要后台运行的代码放在这个函数里(这里可以处理不同的任务,每个任务执行时都会调用这个函数,这里通过判断任务的名字调用不同的代码)
protected override void OnInvoke(ScheduledTask task) { //TODO: 添加用于在后台执行任务的代码 if (task.Name == "myTileUpdate") { BackWork(); //循环执行,这里设置下次执行该任务时间,这里设置为5s,处于性能的考虑,建议设置大一点 ScheduledActionService.LaunchForTest("myTileUpdate", TimeSpan.FromSeconds(5)); } NotifyComplete(); }
2、把myTileUpdate任务的执行代码放到BackWork()函数中,下面实现BackWork函数
public void BackWork() { Deployment.Current.Dispatcher.BeginInvoke(() => { //调用UI用于创建图片,保存到隔离存储空间 CreateImage(); }); string jpeg = "Shared/ShellContent/Tiles/datetime.jpg"; foreach (ShellTile TileToFind in ShellTile.ActiveTiles) { StandardTileData NewTileData = new StandardTileData { //使用隔离存储空间里的图片 BackgroundImage = new Uri("isostore:/" + jpeg, UriKind.Absolute), }; TileToFind.Update(NewTileData); } }
这里有一点要注意的,这里图片文件一定要存到Shared/ShellContent/这个目录里,不然会出现无法访问,在这里我卡了好久
除了常规数据存储外,独立存储用于下列特殊用途情形(摘自MSDN)
http://technet.microsoft.com/zh-cn/library/ff402541(v=VS.92).aspx
路径 |
用途 |
备注 |
---|---|---|
Shared |
用于托管 Media、ShellContent 和 Transfers 文件夹。 |
该文件夹在应用程序安装时创建,但可以将其删除。 |
Shared/Media |
专辑封面:应用程序可以在播放背景音频时使用此文件夹在通用音量控件 (UVC) 中显示专辑封面。 |
该文件夹在应用程序安装时创建,但可以将其删除。有关更多信息,请参阅如何:与 Windows Phone 的音乐和视频中心集成。 |
Shared/ShellContent |
应用程序磁贴:磁贴可以显示每个磁贴正面和背面上的背景图像。背景图像可以存储在独立存储中,但是必须位于此文件夹或其子文件夹中。 |
该文件夹在应用程序安装时创建,但可以将其删除。有关更多信息,请参阅Windows Phone 的图块概述。 |
Shared/Transfers |
后台文件传输:即使当应用程序不再在前台中运行时,应用程序仍可以将文件保存到后台中的独立存储中。 |
该文件夹在应用程序安装时创建,但可以将其删除。有关更多信息,请参阅Windows Phone 的后台文件传输概述。 |
3、对于CreateImage函数大家可以根据需要绘制,然后保存到隔离存储空间,也可以从网上下载图片
public void CreateImage() { //随机颜色 Color c = new Color(); byte[] bs = new byte[3]; ran.NextBytes(bs); c.A = 255; c.R = bs[0]; c.G = bs[1]; c.B = bs[2]; DateTime date = DateTime.Now; Canvas canvas = new Canvas(); canvas.Background = new SolidColorBrush(c); canvas.Height = canvas.Width = 173; TextBlock tbTop = new TextBlock(); TextBlock tbCenter = new TextBlock(); TextBlock tbBotton = new TextBlock(); tbTop.Width = tbCenter.Width = canvas.Width; tbBotton.Width = 161; tbTop.TextAlignment = tbCenter.TextAlignment = System.Windows.TextAlignment.Center; tbBotton.TextAlignment = System.Windows.TextAlignment.Right; tbTop.FontSize = 28; tbCenter.FontSize = 80; tbBotton.FontSize = 20; tbTop.Foreground = tbBotton.Foreground = tbCenter.Foreground = new SolidColorBrush(Colors.White); tbTop.Text = date.ToString("yyyy年MM月"); tbCenter.Text = date.Day.ToString(); tbBotton.Text = date.DayOfWeek.ToString(); Canvas.SetTop(tbTop, 10); Canvas.SetTop(tbCenter, 35); Canvas.SetTop(tbBotton, 133); canvas.Children.Add(tbTop); canvas.Children.Add(tbCenter); canvas.Children.Add(tbBotton); WriteableBitmap bitmap = new WriteableBitmap(canvas, null); using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication()) { string directory = "Shared/ShellContent/Tiles"; string jpg = directory + "/datetime.jpg"; if (!file.DirectoryExists(directory)) { file.CreateDirectory(directory); } using (IsolatedStorageFileStream stream = file.OpenFile(jpg, System.IO.FileMode.OpenOrCreate)) { bitmap.SaveJpeg(stream, 173, 173, 0, 100); } } }
4、做好后台代码的工作,接下来是添加到我们的项目中
选择刚刚写好的计划代理MyScheduledTaskAgent
5、接下来是启动这个后台代理
这里我添加了一个按钮btnSwitch,用于打开和关闭这个后台代理
private void btnSwitch_Click(object sender, RoutedEventArgs e) { Button btn = sender as Button; ScheduledAction task; if ((task = ScheduledActionService.Find("myTileUpdate")) == null) { //打开后台 PeriodicTask periodictask = new PeriodicTask("myTileUpdate"); periodictask.Description = "简单的计划代理"; ScheduledActionService.Add(periodictask); ScheduledActionService.LaunchForTest("myTileUpdate", TimeSpan.FromSeconds(5)); btn.Content = "关闭后台代理"; } else { //关闭后台 ScheduledActionService.Remove("myTileUpdate"); btn.Content = "打开后台代理"; } }
6、到这里,后台计划代理算是完成了