首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > windows >

怎么调用windows phone 7.1的后台闹钟功能 step by step

2012-09-22 
如何调用windows phone 7.1的后台闹钟功能 step by step自从 WP7.1之后,windows phone 开放一些后台调用,

如何调用windows phone 7.1的后台闹钟功能 step by step

自从 WP7.1之后,windows phone 开放一些后台调用,包括音乐,闹钟,播放器等,相信在做windows phone开发时,有可能会调用后台, 恰好我们的软件工程中需要用到闹钟提醒功能,现在就把具体的细节一步一步告诉大家。

包括实现多项提醒,存储和显示等功能。

1. 简介

Reminder是我们Microsoft Academic Search (MAS) 的Windows Phone 7的一个应用的模块,用来提醒用户会议中每个session的开始。用户可以设置reminder的开始时间,结束时间,reminder的消息以及铃声,同时用户也可以删除已经存在的reminder。我需要做的就是提供创建和删除reminder的API,已经管理现有的reminders。下面我就谈一谈我在实现过程中的方法,遇到的困难,教训以及解决方案。

2. 如何在Memory中存储ReminderList

程序运行时,需要在内存中存储临时的ReminderList的信息。下面我谈谈这个部分我的经验与总结。

2.1. 数据结构

选择何时的数据结构是非常重要的。我一开始打算使用C#的Dictionary和Tuple,结果发现Windows Phone并不支持Tuple,于是我自己定义了一个class Tuple5并且把它用作Dictionary的Value的Type。Class Tuple5的代码如下:

 1 public class Tuple5<T1, T2, T3, T4, T5> 2 { 3     public T1 Item1 { get; set; } 4     public T2 Item2 { get; set; } 5     public T3 Item3 { get; set; } 6     public T4 Item4 { get; set; } 7     public T5 Item5 { get; set; } 8  9     public Tuple5(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)10     {11         Item1 = item1;12         Item2 = item2;13         Item3 = item3;14         Item4 = item4;15         Item5 = item5;16     }17 }

?

存储ReminderList的Dictionary的type如下:

Dictionary<uint, Tuple5<DateTime, DateTime, string, RecurrenceInterval, Uri>>

?

其中uint是我给每个Reminder分配的一个Universally Unique Identifier (UUID),Tuple5里面五个参数分别为Reminder的开始时间,结束时间,消息,重复响铃频率和声音文件的地址。这样我就可以用这个Dictionary来存储我们的ReminderList了。

2.2. 使用Windows Phone的Alarm

为了让我们的Reminder能在设定的时间响铃,我们使用了Windows Phone SDK 7.1的新功能——Alarm。我首先参考了MSDN官方的代码示例,地址如下:

http://msdn.microsoft.com/en-us/library/hh202965(v=vs.92).aspx

然后自己开始编写代码。下面我主要讲一下如何设置一个Alarm。

首先我们需要使用Windows Phone的scheduler的namespace,代码如下:

using Microsoft.Phone.Scheduler;

然后就是使用传进来的开始时间beginTime,结束时间stopTime,消息message,重复响铃频率recurrence和声音文件的地址sound来创建一个Alram对象并且加入Scheduler,代码如下:

1 Alarm alarm = new Alarm(name);2 alarm.Content = message;3 alarm.Sound = sound;4 alarm.BeginTime = beginTime;5 alarm.ExpirationTime = stopTime;6 alarm.RecurrenceType = recurrence;7 ScheduledActionService.Add(alarm);

?

3. 如何在文件系统中存储ReminderList

因为用户设置的Alarm在下次启动程序的时候还要求能够删除和修改,所以必须要将现有的Alarms存在文件系统里。下面我讲一下我的经验。

3.1. Serialization的失败

我一开始尝试使用C#的XmlSerializer和DataContractSerializer来存储我的Dictionary,但是我经过一天的尝试,最终以失败结束。下面我就XmlSerializer谈谈我的实现方法。

我一开始尝试使用XmlSerializer来将我的Dictionary存成xml文件,然后下次直接从xml文件读取这个Dictionary。代码如下:

 1 XmlSerializer ser = new XmlSerializer(typeof(Dictionary<uint, Tuple5<DateTime, DateTime, string, RecurrenceInterval, Uri>>)); 2  3 // write 4 using (var stream = File.Create("ReminderList.xml")) 5 { 6     ser.Serialize(stream, ReminderList); // your instance 7 } 8  9 // read10 using (var stream = File.OpenRead("ReminderList.xml"))11 {12     ReminderList = (Dictionary<uint, Tuple5<DateTime, DateTime, string, RecurrenceInterval, Uri>>)ser.Deserialize(stream);13 }


最后编译时提示我Uri不能被Serialized。于是我将Uri改成string,他还是提示我Tuple5的Serialization出错,于是我仔细研究这个,尝试了几种方法,包括在我的class Tuple5的定义加上[Serializable()]的属性,最后还是没有成功,于是我开始考虑自己将Dictionary转化成文件。

3.2. 自己将Dictionary转化成文件

因为使用Serialization失败,我开始自己将Dictionary存入文件,我使用了最简单的方法,就是将每个item一行行以string形式存入文件,代码如下:

 1 // Obtain the virtual store for the application. 2 IsolatedStorageFile myStore = IO.GetUserStore(); 3 myStore.CreateDirectory("Reminder"); 4  5 // Specify the file path and options. 6 using (var isoFileStream = new IsolatedStorageFileStream("Reminder\\ReminderList.dat", FileMode.OpenOrCreate, myStore)) 7 { 8     //Write the data 9     using (var isoFileWriter = new StreamWriter(isoFileStream))10     {11         foreach (KeyValuePair<uint, Tuple5<DateTime, DateTime, string, RecurrenceInterval, Uri>> kvp in ReminderList)12         {13             isoFileWriter.WriteLine(Convert.ToString(kvp.Key));14             isoFileWriter.WriteLine(kvp.Value.Item1.ToString());15             isoFileWriter.WriteLine(kvp.Value.Item2.ToString());16             isoFileWriter.WriteLine(kvp.Value.Item3);17             isoFileWriter.WriteLine(kvp.Value.Item4.ToString());18             if (kvp.Value.Item5 != null)19             {20                 isoFileWriter.WriteLine(kvp.Value.Item5.AbsoluteUri);21             }22             else23             {24                 isoFileWriter.WriteLine("");25             }26         }27     }28 }

?

有一点要说明的是,Windows Phone使用的是独立的存储文件IsolatedStorageFile,与PC上并不一样。

3.3. 从文件中读取ReminderList

每次启动时,都要能够从文件中读取ReminderList。我是写了一个静态构造函数来从文件读取ReminderList。静态构造函数有一个对象被声明就会调用,且整个程序只调用一次,从文件读取ReminderList的代码如下:

 1 // Obtain a virtual store for the application. 2 IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication(); 3  4 try 5 { 6     // Specify the file path and options. 7     using (var isoFileStream = new IsolatedStorageFileStream("Reminder\\ReminderList.dat", FileMode.Open, myStore)) 8     { 9         // Read the data.10         using (var isoFileReader = new StreamReader(isoFileStream))11         {12             string line = null;13             while ((line = isoFileReader.ReadLine()) != null)14             {15                 uint newId = Convert.ToUInt32(line);16                 line = isoFileReader.ReadLine();17                 DateTime startTime = DateTime.Parse(line);18                 line = isoFileReader.ReadLine();19                 DateTime stopTime = DateTime.Parse(line);20                 line = isoFileReader.ReadLine();21                 string message = line;22                 line = isoFileReader.ReadLine();23                 RecurrenceInterval recurrence = RecurrenceInterval.None;24                 switch (line)25                 {26                 case "None": recurrence = RecurrenceInterval.None; break;27                 case "Daily": recurrence = RecurrenceInterval.Daily; break;28                 case "EndOfMonth": recurrence = RecurrenceInterval.EndOfMonth; break;29                 case "Monthly": recurrence = RecurrenceInterval.Monthly; break;30                 case "Weekly": recurrence = RecurrenceInterval.Weekly; break;31                 case "Yearly": recurrence = RecurrenceInterval.Yearly; break;32                 default: recurrence = RecurrenceInterval.None; break;33                 }34 35                 line = isoFileReader.ReadLine();36                 Uri sound = null;37                 if (line != "")38                 {39                     sound = new Uri(line, UriKind.Relative);40                 }41                 Tuple5<DateTime, DateTime, string, RecurrenceInterval, Uri> newReminder = new Tuple5<DateTime, DateTime, string, RecurrenceInterval, Uri>(startTime, stopTime, message, recurrence, sound);42                 ReminderList.Add(newId, newReminder);43             }44         }45     }46 }47 catch48 {49     // TODO:50 }

?

4. 其他细节

虽然实现了Reminder的模块,我还是考虑了很多需要完善的细节,下面举出两个例子。

4.1. 重复的Reminder

用户在设置同一个session的reminder的时候,可能会修改设置,但是在我的程序里就会导致设置两个alarms,于是调用者对于同一个session必须先delete这个alarm(用之前create alarm返回的ID),然后才能创建新的。

4.2. 删去过期的Reminder

有些Alarms已经过了stopTime了,系统需要定期删掉这些Alarms。我是在每次创建新的alarm之前清理过期的alarms。

下面就是我花了将近三天时间研磨总结出来的,如果感觉对你有用,请推荐我们,相信这是对我们新手开发windows phone过程中的鼓励!

热点排行