数据交换=>Windows_Mobile+WCF+Exchange2007 - part2

相关文章

数据交换=>Windows_Mobile+WCF+Exchange2007 - part1
 

 

数据交换=>Windows_Mobile+WCF+Exchange_2007

 

摘要:WCF作为一个新的特征在.Net Compact Framework中得到实现。本文将基于 Exchange2007继续探讨WCF Compact特有的消息存储和转发特性(Store and Forward messaging)。这一部分将之前的调度器应用升级到支持照片共享,并结合Virtual Earth加入了定位元素。

Keywords:

WCF,Windows Mobile,.Net Compact Framework,Exchange Server 2007,Virtual Earth

 

 (本文英文原文由marteaga发表于Opennetcf Community 原题为“Exchanging Data using Windows Mobile, Windows Communication Foundation, .NET Compact Framework and Exchange 2007”)

 

非常建议您先阅读前面一篇文章Change_your_life=>Windows_Mobile+WCF+Exchange2007 - part1

 

 

加强版的调度器应用

 

为了用于实际的企业应用,我们把之前的调度器应用做了一些加强. 比如, 使用SQL Server 存放调度器发出的请求, 现场的服务执行终端会被打上一个GPS的标签. 你也可以使用SQL Replication存储并同步数据, 并使用WCF 来提示应用程序进行同步。

 

  • 图片共享的应用场景

 

图片共享的应用允许用户分享他们最近拍摄的照片,使用WCF和Exchange来发送照片. 这里我们假设一个Windows Mobile 应用跑在两台独立的设备上,我们的桌面应用不再是调度器的角色(后面会详细介绍)。

我们假设这个应用是由于在两个希望分享近期照片的朋友之间,不过同样的主题还是可以用于一个LOB型的应用。比如一个现场的工人可以拍摄一张问题组件照片发送给中央调度器,由调度器分析并指派相应的助理或者专家到现场。

 

 

Windows Mobile端的实现

 

在前面的示例中,我们在桌面的应用程序中初始化了消息对象。在接下来的这个程序中,我们将会在移动设备来做这个工作。并将消息发往桌面应用以及另一个设备。

和之前的调度器应用一样,我们将使用WCFMessagingManager,XmlSerializerWrapper略有不同的是在这个例子里面我们发送的是一个PhotoData消息对象,而不是DispatchMessage。
 
先如下创建WCFMessagingManager:

 

    WindowsMobileMailBinding binding = newWindowsMobileMailBinding();
    m_messagingManager = newWCFMessagingManager<PhotoData>(binding, m_config.IncomingChannel);

 
PhotoData的定义如下:

 

    public class PhotoData

    {

 

privateBitmap m_bitmap = null;

 

public PhotoData(string filename)

{

    //这里我们暂且以多伦多的纬度和经度为例

    this.Latitude = 43.6919;

    this.Longitude = -79.5782;

 

    //设置文件名

    FileName = filename;

    SetProperties();

 

    //设置ID

    Id = Guid.NewGuid();

}

 

public PhotoData()

{

}

 

public string Comment { get; set; }

 

public Guid Id { get; set; }

 

public string FileName { get; set; }

 

public double Latitude { get; set; }

 

public double Longitude { get; set; }

 

public int FileSize { get; set; }

 

public string Base64Data { get; set; }

 

///<returns></returns>

public Bitmap GetBitmapImage()

{ ... }

 

private void SetProperties()

{ ... }

 

}

 

你可以看到, 这里 photoData有各种各样的一些属性:图片说明,文件名,纬度/经度,文件大小,Base64数据。当通过WCF发送消息的时候,我们需要确保图片被正确的转化为Base64的字符串:

 

    private void SetProperties()

    {

        if (File.Exists(FileName))

        {

            //Grab the byte data from the file

            FileStream fs = File.Open(FileName, FileMode.Open);

            byte[] data = newbyte[fs.Length];

            fs.Read(data, 0, data.Length);

            fs.Close();

 

            //Set the file size

            FileSize = data.Length;

            

            //convert the byte[] to base64

            Base64Data = Convert.ToBase64String(data);

        }

    }

 

上述方法从PhotoData(string)的构造器中被调用并设置属性。可以看到PhotoData有两个构造器, 其中无参构造器是用于在XmlSerializerWrapper中调用XmlSerializer来反序列化XML数据. 所以当一个PhotoData对象被接收到的时候,XmlSerializer会自动反序列化数据.


PhotoData还有一个public的方法,来返回要显示的位图对象:

 

    public Bitmap GetBitmapImage()

    {

        if (m_bitmap == null)

        {

            if (Base64Data != null)

            {

                byte[] imageData = Convert.FromBase64String(Base64Data);

                m_bitmap = new Bitmap(new MemoryStream(imageData));

            }

        }

        return m_bitmap;

    }

 

在接收端只需要调用GetBitmapImage就可以显示图片了. Windows Mobile端的UI很直观,几乎无须说明,只用到了一个pictureBox和两个menuItems:


 

我们使用Microsoft.WindowsMobile.Forms.CameraCaptureDialog来拍摄照片(Windows Mobile 5 and later) :

 

    using (CameraCaptureDialog ccd = newCameraCaptureDialog())

    {

        if (ccd.ShowDialog() == DialogResult.OK)

        {

            CurrentPhotoData = newPhotoData(ccd.FileName);

            CurrentPhotoData.FileName = ccd.FileName;

            pictureBox1.Image = newBitmap(CurrentPhotoData.FileName);

        }

    }

 

拍摄完照片,我们让PictureBox来显示刚刚拍摄的图片.然后, 我们调用WCFMessageingManager.SendMessage直接将图片发送出去:

 

    //Send the message to the device

    m_messagingManager.SendMessage(m_config.SendToEmail, m_config.OutgoingChannel, CurrentPhotoData);

    //Send the message to the desktop

    m_messagingManager.SendMessage(m_config.SendToEmail, m_config.OutgoingChannelDesktop, CurrentPhotoData);

 

 

桌面端的实现

 

桌面端只是简单的监听photaData并显示它们, UI也很简单, 使用了一个listBox来显示当前来内存中的Photodata对象, 一个pictureBox来显示图片和一个WebBrowser控件来显示Virtual Earth地图和拍摄地点.(关于Virtual Earth的集成,后文有介绍)

UI如下图所示:

 

当WCFMessagingManager.IncomingMessage事件被主UI处理之后,我们希望更新我们的UI, 这里我们使用了BeginInvoke:

 

    this.BeginInvoke(newEventHandler(delegate(object sender, EventArgs ea)

    {

        //find the message in the internal list

        var message = from tmsg in m_messagesReceived

        where tmsg.Id.Equals(body.Id)

        select tmsg;

     

        if (message.Count() == 0)

        {

            //add the item to the list

            m_messagesReceived.Add(body);

        }

 

        UpdateListbox();

    }));

 

参数m_messagesRecevied是List<string>类型, 用作 ListBox的dataSource:

 

    listBox1.DataSource = m_messagesReceived;

 

在ListBox.SelectedIndexChanged事件中, 我们显示照片以及在VE的地图上标记拍摄地点:

 

    if (listBox1.SelectedIndex >= 0 && listBox1.SelectedIndex < m_messagesReceived.Count)

    {

        PhotoData pd = m_messagesReceived[listBox1.SelectedIndex];

        //从Photodata中获取照片并显示

        this.pictureBox1.Image = pd.GetBitmapImage();

 

        //显示拍摄地点的标记

        executeScript(ClearPushpinsScript);

     

        executeScript(AddPushpinScript, pd.Id.ToString(),

        (pd.Comment == null ? "No Comments" : pd.Comment.ToString()),

        pd.Latitude, pd.Longitude);

        //设置标记中心

        executeScript(SetCenter, pd.Latitude, pd.Longitude);

        //设置放大倍数显示

        executeScript(Zoom, 18);

    }

 

 

执行结果

 

我们用一台运行着Windows Mobile 5.0 的Palm Treo 700wx 拍摄了一张照片,并发送给桌面的应用以及一台Windows mobile 6.1 Professional的模拟器 :

 

 

 

Virtual Earth在桌面应用中的集成

 

由于我们的PhotoData包含有纬度和经度信息,自然会想到在桌面应用中将VE集成进去。这里我们选用了 WinForms Earth v2.  不过我们需要把它原来的Code稍作更新,因为它们已经很过时了。要在WinForm中使用VE我们需要做以下一些工作:

  1. 需要一个本地的HTML页来加载VE的地图,这个HTML 文件里面还应当包含一些javascript的函数,我们可以从.NET 的应用中去调用到。
  2. ComVisible(true) 特性需要被添加到你的form中,当然这个特性标签也可以被加到那个处理.NET 代码和HTML文档的通信类上,不过在此为了简便,我们直接加到form上。
  3. .NET中和HTMLdocument JavaScript的代码交互是通过调用WebBrowser.Document.InvokeScript方法完成的
  4. HTMLdocument中和.NET的交互是通过JavaScript的函数window.external.X 这里X表示在.NET代码中你的方法名。这个方法当然必须是public的. WinForms Earth V2 中有相关的示例

 

进一步的加强

 

这里我们是把坐标写死,实际上我们可以使用真是的GPS的设备,来捕获当前坐标,可以参考WM6SDK中的 GPS Sample 。在桌面端,你可以将每一个photodata对象存入SQLServer Compact Database中。当然你也可以把这些图片数据和你的Flickr 或是 facebook相册结合起来;)

 

  • 总结

 

E-mail已经风靡很长时间了, 在如今的移动设备上Email也是最先实现的几个功能之一。 和Windows Mobile一起,现在我们有了direct push email 和.NET Compact Framework 3.5我们可以将email 和direct push 技术纳入到我们的Windows Mobile的应用当中去。作为开发人员,这里的Compact WCF使得我们减少了对移动设备的通信问题的烦恼,使得程序员能专注于应用程序本身,而不再是设备定址问题。

 

完整的代码在此处下载

Enjoy! 

 

黄季冬

 


 

 

 

 

posted on 2008-08-02 12:13 Freesc Huang 阅读(977) 评论(4) 编辑 收藏

评论

#1楼 2008-08-02 13:06 AppleSeeker      

强悍的。支持下  回复 引用 查看   

#2楼[楼主] 2008-08-02 13:10 fox23      

@AppleSeeker
希望能带来一些启发;)
 回复 引用 查看   

#3楼 2008-08-02 18:40 江南白衣      

很不错,UP:)  回复 引用 查看   

#4楼[楼主] 2008-08-04 20:07 fox23      

本文于今日下午发生灵异事件,标记一下,恩~  回复 引用 查看   

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

公告

These postings are provided "AS IS" with no warranties
and confer no rights.


Locations of visitors to this page

Blog Keywords
Embedded System,Visual Studio,.Net Framework,.Net Compact Framework,.Net Micro Framework,Windows Mobile,Windows Embedded CE,Emulator,WCF,CLR,Design & Pattern,C/C++,C#,Matlab,Algorithms
昵称:Freesc Huang
园龄:4年11个月
粉丝:32
关注:4

统计

  • 随笔 - 197
  • 文章 - 0
  • 评论 - 840

搜索

 

随笔分类(227)

随笔档案(197)

Blogs

Link

积分与排名

最新评论

阅读排行榜

评论排行榜

推荐排行榜