智能手機應用程序開發是軟件開發的一個新的熱點,但如何才能跨入這道門楣呢?今天我通過為自己的多普達565手機添加一個天氣預報程序來向大家講解一下。我們都知道QQ有一個免費提供給Blog引用的天氣預報服務網址http://appnews.qq.com/cgi-bin/news_qq_search?city=上海(上海是我自己所在城市,如果想看自己的城市,在瀏覽器中改成城市名稱即可),現在我使用QQ提供的這個服務,將其包裝部署為一個Web服務,并編寫程序使得我的多普達565智能手機能使用這個Web服務。
設備要求:
PC開發環境:Windows xp SP2,Visual Studio 2003.NET,.NET Framework 1.1 SP1
操作系統:Windows Mobile(TM) 2003第二版,版本4.21.1088(Build 14235.2.0.0)
智能手機:多普達565
一、環境安裝
首先我們必須安裝.NET Mobile所需要的開發環境,必須安裝的軟件(如下軟件都是微軟提供免費下載和使用的)
1、Microsoft ActiveSync 3.7.1
下載網址:http://www.microsoft.com/windowsmobile/downloads/activesync37.mspx,里面有中文版本,或者,在手機附帶的微軟光盤里面有安裝程序;最新版本Microsoft ActiveSync 3.8出來了,可以到摘要的頁面中去找鏈接下載,但這個程序我還是用的老版本。
作用:同步手機和PC機數據的程序
2、Microsoft SMARTPHONE 2003 SDK.msi
下載網址:
http://download.microsoft.com/download/e/3/1/e310bb99-2f33-4d79-bb8a-41d9cb3c79b4/Microsoft SMARTPHONE 2003 SDK.msi
3、MobileAppDevToolkit2004.exe
二、設計并部署WebService
1、建立一個名為WeatherService的WebService,并將QQ的天氣服務轉為xml WebService服務,部署在一臺具有固定ip的服務器上。
2、新建一個WeatherDataSet.XSD,存儲我們的天氣信息
<?xml version="1.0" encoding="utf-8" ?> <xs:element name="WeatherDataSet" msdata:IsDataSet="true"> 3、WeatherService的源代碼如下 #region Using directives using System; #endregion namespace WeatherService [WebService(Description="WeatherService 天氣Service",Namespace="WeatherService")] public class Weather : System.Web.Services.WebService #region 構造函數 public Weather() if(DateTime.Today.AddDays(1).Month.ToString().Length == 1) #endregion #region 組件設計器生成的代碼 //Web 服務設計器所必需的 private IContainer components = null; /// <summary> private void InitializeComponent() /// <summary> protected override void Dispose( bool disposing ) #endregion #region [OK] GetWeatherDataSet 天氣預報 [WebMethod(Description="天氣預報")] public DataSet GetWeatherDataSet(string cityName) try //System.Diagnostics.Trace.WriteLine( tommorow ); WeatherDataSet weatherDs = new WeatherDataSet(); private WeatherDataSet.WeatherDSRow GetWeatherRow(ref WeatherDataSet weatherDs,string weatherData,string cityName) weatherRow.Date1 = DateTime.Now.ToLongDateString(); weatherRow.Weather1 = weatherData.Substring(weatherData.IndexOf("天氣")+"天氣".Length,weatherData.IndexOf("氣溫")-(weatherData.IndexOf("天氣")+"天氣".Length)); weatherRow.Temp1 = weatherData.Substring(weatherData.IndexOf("氣溫")+"氣溫".Length,weatherData.IndexOf("風力")-(weatherData.IndexOf("氣溫")+"氣溫".Length)).Replace("℃-","℃/"); weatherRow.WindPower1 = weatherData.Substring(weatherData.IndexOf("風力")+"風力".Length,weatherData.IndexOf(tommorow)-(weatherData.IndexOf("風力")+"風力".Length)); weatherRow.Date2 = DateTime.Today.AddDays(1).ToLongDateString(); weatherRow.Weather2 = weatherData.Substring(weatherData.LastIndexOf("天氣")+"天氣".Length,weatherData.LastIndexOf("氣溫")-(weatherData.LastIndexOf("天氣")+"天氣".Length)); weatherRow.Temp2 = weatherData.Substring(weatherData.LastIndexOf("氣溫")+"氣溫".Length,weatherData.LastIndexOf("風力")-(weatherData.LastIndexOf("氣溫")+"氣溫".Length)).Replace("℃-","℃/"); weatherRow.WindPower2 = weatherData.Substring(weatherData.LastIndexOf("風力")+"風力".Length); return weatherRow; #endregion #region GetPageString 獲取QQ的天氣服務 //private string xx=""; [WebMethod(Description="天氣預報")] public string GetPageString(string cityName) private static string GetPage(string url,string cityName) //獲得流內容 res = (HttpWebResponse)req.GetResponse(); strResult=strResult.Remove(0,strResult.IndexOf("●")); if( cityName != "北京" ) strResult=strResult.Trim(); while(strResult.IndexOf(@" ") != -1) string x = Encoding.UTF8.GetString(new Byte[]{10}); while(strResult.IndexOf(x) != -1) while(strResult.IndexOf(y) != -1) #endregion 記得將在Web.Config文件加入以下節點,使得WebService能被外部訪問 <!-- WebService 獲取的途徑 -->
<xs:schema id="WeatherDataSet" targetNamespace="Ezhi.Services.WeatherService" elementFormDefault="qualified"
attributeFormDefault="qualified" xmlns="Ezhi.Services.WeatherService" xmlns:mstns="Ezhi.Services.WeatherService"
xmlns:xs="
<xs:complexType>
?。紉s:choice maxOccurs="unbounded">
?。紉s:element name="WeatherDS">
<xs:complexType>
?。紉s:sequence>
?。紉s:element name="CityName" type="xs:string" minOccurs="0" />
<xs:element name="Date1" type="xs:string" minOccurs="0" />
?。紉s:element name="Weather1" type="xs:string" minOccurs="0" />
<xs:element name="Temp1" type="xs:string" minOccurs="0" />
?。紉s:element name="WindPower1" type="xs:string" minOccurs="0" />
?。紉s:element name="Date2" type="xs:string" minOccurs="0" />
<xs:element name="Weather2" type="xs:string" minOccurs="0" />
?。紉s:element name="Temp2" type="xs:string" minOccurs="0" />
?。紉s:element name="WindPower2" type="xs:string" minOccurs="0" />
</xs:sequence>
?。?xs:complexType>
</xs:element>
?。?xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.IO;
using System.Net;
using System.Text;
{
/// <summary>
/// Service1 的摘要說明。
/// </summary>
{
#region Variable
PRivate string tommorow;
#endregion
{
InitializeComponent();
{
tommorow= "0"+DateTime.Today.AddDays(1).Month.ToString()+"月" +
DateTime.Today.AddDays(1).Day.ToString()+"日";
}
else
{
tommorow= DateTime.Today.AddDays(1).Month.ToString()+"月" +
DateTime.Today.AddDays(1).Day.ToString()+"日";
}
}
/// 設計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
{}
/// 清理所有正在使用的資源。
/// </summary>
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
{
string url=@"http://appnews.qq.com/cgi-bin/news_qq_search";
string weatherData="";
{
weatherData = GetPage(url,cityName).Replace(" ","").Trim();
}
catch(Exception)
{
throw new Exception("對不起,沒有這個城市的天氣信息!");
}
//System.Diagnostics.Trace.WriteLine( weatherData );
weatherDs.WeatherDS.AddWeatherDSRow(GetWeatherRow(ref weatherDs,weatherData,cityName) );
return weatherDs;
}
{
WeatherDataSet.WeatherDSRow weatherRow = weatherDs.WeatherDS.NewWeatherDSRow();
weatherRow.CityName = weatherData.Substring(weatherData.IndexOf("●")+1,cityName.Length);
}
{
string url=@"http://appnews.qq.com/cgi-bin/news_qq_search";
return GetPage(url,cityName);
}
{
HttpWebResponse res = null;
string strResult = "";
try
{
string postData = "city=" + HttpUtility.UrlEncode(cityName,System.Text.Encoding.GetEncoding("GB2312"));
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.KeepAlive = true;
req.ContentType = "application/x-www-form-urlencoded";
StringBuilder UrlEncoded = new StringBuilder();
byte[] SomeBytes = Encoding.ASCII.GetBytes(postData);
req.ContentLength = SomeBytes.Length;
Stream newStream = req.GetRequestStream();
newStream.Write(SomeBytes, 0, SomeBytes.Length);
newStream.Close();
System.IO.Stream s=res.GetResponseStream();
StreamReader reader = new StreamReader(s,System.Text.Encoding.Default);
strResult=reader.ReadToEnd();
}
catch(Exception e)
{
strResult = e.ToString();
}
finally
{
if ( res != null )
{
res.Close();
}
}
{
strResult=strResult.Remove(strResult.IndexOf("北京"),strResult.Length-strResult.IndexOf("北京"));
}
else
{
strResult=strResult.Remove(strResult.LastIndexOf("北京"),strResult.Length-strResult.LastIndexOf("北京"));
}
while(strResult.IndexOf(@"<") != -1)
{
strResult=strResult.Remove(strResult.IndexOf(@"<"),strResult.IndexOf(@">")-strResult.IndexOf(@"<")+1);
}
{
strResult=strResult.Replace(" ","");
}
string y = Encoding.UTF8.GetString(new Byte[]{9});
{
strResult=strResult.Replace(x,"");
}
{
strResult=strResult.Replace(y,"");
}
return strResult;
}
}
}
<webServices>
<protocols>
<add name="HttpSoap"/>
<add name="HttpPost"/>
<add name="HttpGet"/>
<add name="HttpPostLocalhost"/?
<add name="Documentation"/>
</protocols>
</webServices>
三、新建手機應用程序項目
1、新建一個智能設備應用程序,在主面板上拖放如圖2所示的幾個控件,其中timer是用來檢查是否數據已經下載完畢的。
圖1-新建智能設備應用程序
圖2-界面設計
2、引用建好的WebService
圖3-引用WebService
3、WeatherService智能手機上運行的程序源代碼using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
namespace WeatherService
{
/// <summary>
/// Summary description for MainForm.
/// </summary>
public class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.ComboBox comboBox_City;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.Label txt_Weather1;
private System.Windows.Forms.Label txt_Date1;
private System.Windows.Forms.Label txt_Temp1;
private System.Windows.Forms.Label txt_WindPower1;
private System.Windows.Forms.Label txt_Temp2;
private System.Windows.Forms.Label txt_WindPower2;
private System.Windows.Forms.Label txt_Date2;
private System.Windows.Forms.Label txt_Weather2;
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuItem_Menu;
private System.Windows.Forms.MenuItem menuItem_Exit;
private System.Windows.Forms.Label label_City;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuItem3;
public string[] cityList = new string[]
{
"北京",
"上海",
"天津",
"石家莊",
"哈爾濱",
"沈陽",
"長春",
"太原",
"濟南",
"鄭州",
"天津",
"呼和浩特",
"西安",
"銀川",
"蘭州",
"西寧",
"烏魯木齊",
"合肥",
"南昌",
"南京",
"杭州",
"武漢",
"長沙",
"廣州",
"深圳",
"福州",
"廈門",
"南寧",
"桂林",
"海口",
"重慶",
"成都",
"貴陽",
"昆明",
"拉薩",
"香港",
"澳門",
"臺北",
};
public MainForm()
{
InitializeComponent();
foreach( string x in cityList)
{
this.comboBox_City.Items.Add(x);
}
this.comboBox_City.SelectedIndex = 0;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem_Menu = new System.Windows.Forms.MenuItem();
this.menuItem_Exit = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.comboBox_City = new System.Windows.Forms.ComboBox();
this.label_City = new System.Windows.Forms.Label();
this.txt_Weather1 = new System.Windows.Forms.Label();
this.txt_Date1 = new System.Windows.Forms.Label();
this.txt_Temp1 = new System.Windows.Forms.Label();
this.txt_WindPower1 = new System.Windows.Forms.Label();
this.txt_Temp2 = new System.Windows.Forms.Label();
this.txt_WindPower2 = new System.Windows.Forms.Label();
this.txt_Date2 = new System.Windows.Forms.Label();
this.txt_Weather2 = new System.Windows.Forms.Label();
this.timer1 = new System.Windows.Forms.Timer();
//
// mainMenu1
//
this.mainMenu1.MenuItems.Add(this.menuItem1);
this.mainMenu1.MenuItems.Add(this.menuItem_Menu);
//
// menuItem1
//
this.menuItem1.Text = "確定";
this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
//
// menuItem_Menu
//
this.menuItem_Menu.MenuItems.Add(this.menuItem_Exit);
this.menuItem_Menu.MenuItems.Add(this.menuItem3);
this.menuItem_Menu.MenuItems.Add(this.menuItem2);
this.menuItem_Menu.Text = "菜單";
//
// menuItem_Exit
//
this.menuItem_Exit.Text = "退出";
this.menuItem_Exit.Click += new System.EventHandler(this.menuItem_Exit_Click);
//
// menuItem3
//
this.menuItem3.Text = "-";
//
// menuItem2
//
this.menuItem2.Text = "關于";
this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
//
// comboBox_City
//
this.comboBox_City.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.comboBox_City.Location = new System.Drawing.Point(52, 8);
this.comboBox_City.Size = new System.Drawing.Size(114, 22);
//
// label_City
//
this.label_City.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Bold);
this.label_City.Location = new System.Drawing.Point(4, 12);
this.label_City.Size = new System.Drawing.Size(52, 16);
this.label_City.Text = "城市:";
this.label_City.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// txt_Weather1
//
this.txt_Weather1.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_Weather1.Location = new System.Drawing.Point(12, 50);
this.txt_Weather1.Size = new System.Drawing.Size(152, 14);
this.txt_Weather1.Text = "天氣:";
//
// txt_Date1
//
this.txt_Date1.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_Date1.Location = new System.Drawing.Point(12, 34);
this.txt_Date1.Size = new System.Drawing.Size(152, 14);
this.txt_Date1.Text = "日期:";
//
// txt_Temp1
//
this.txt_Temp1.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_Temp1.Location = new System.Drawing.Point(12, 68);
this.txt_Temp1.Size = new System.Drawing.Size(152, 14);
this.txt_Temp1.Text = "氣溫:";
//
// txt_WindPower1
//
this.txt_WindPower1.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_WindPower1.Location = new System.Drawing.Point(12, 84);
this.txt_WindPower1.Size = new System.Drawing.Size(152, 14);
this.txt_WindPower1.Text = "風力:";
//
// txt_Temp2
//
this.txt_Temp2.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_Temp2.Location = new System.Drawing.Point(12, 140);
this.txt_Temp2.Size = new System.Drawing.Size(152, 14);
this.txt_Temp2.Text = "氣溫:";
//
// txt_WindPower2
//
this.txt_WindPower2.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_WindPower2.Location = new System.Drawing.Point(12, 156);
this.txt_WindPower2.Size = new System.Drawing.Size(152, 14);
this.txt_WindPower2.Text = "風力:";
//
// txt_Date2
//
this.txt_Date2.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_Date2.Location = new System.Drawing.Point(12, 108);
this.txt_Date2.Size = new System.Drawing.Size(152, 14);
this.txt_Date2.Text = "日期:";
//
// txt_Weather2
//
this.txt_Weather2.Font = new System.Drawing.Font("Nina", 9F, System.Drawing.FontStyle.Regular);
this.txt_Weather2.Location = new System.Drawing.Point(12, 124);
this.txt_Weather2.Size = new System.Drawing.Size(152, 14);
this.txt_Weather2.Text = "天氣:";
//
// timer1
//
this.timer1.Interval = 200;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// MainForm
//
this.Controls.Add(this.comboBox_City);
this.Controls.Add(this.txt_Date1);
this.Controls.Add(this.txt_Weather1);
this.Controls.Add(this.label_City);
this.Controls.Add(this.txt_Temp1);
this.Controls.Add(this.txt_WindPower1);
this.Controls.Add(this.txt_Temp2);
this.Controls.Add(this.txt_WindPower2);
this.Controls.Add(this.txt_Date2);
this.Controls.Add(this.txt_Weather2);
this.Menu = this.mainMenu1;
this.Text = "天氣預報";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new MainForm());
}
private void menuItem_Exit_Click(object sender, System.EventArgs e)
{
this.Dispose();
}
private void menuItem1_Click(object sender, System.EventArgs e)
{
SearchWeather(this.comboBox_City.Text);
}
private string[] myString = new string[]
{
"日期: ",
"溫度: ",
"天氣: ",
"風力: ",
};
public void SearchWeather(string cityName)
{
if( this.txt_Date1.Text != myString[0] )
{
ReSelect();
}
this.Text = "正在下載...";
this.timer1.Enabled = true;
WeatherService.Weather weather = new WeatherService.Weather();
DataSet myDs = weather.GetWeatherDataSet(cityName);
this.txt_Date1.Text = myString[0] + myDs.Tables[0].Rows[0]["Date1"].ToString();
this.txt_Temp1.Text = myString[1] + myDs.Tables[0].Rows[0]["Temp1"].ToString();
this.txt_Weather1.Text = myString[2] + myDs.Tables[0].Rows[0]["Weather1"].ToString();
this.txt_WindPower1.Text = myString[3] + myDs.Tables[0].Rows[0]["WindPower1"].ToString();
this.txt_Date2.Text = myString[0] + myDs.Tables[0].Rows[0]["Date2"].ToString();
this.txt_Temp2.Text = myString[1] + myDs.Tables[0].Rows[0]["Temp2"].ToString();
this.txt_Weather2.Text = myString[2] + myDs.Tables[0].Rows[0]["Weather2"].ToString();
this.txt_WindPower2.Text = myString[3] + myDs.Tables[0].Rows[0]["WindPower2"].ToString();
}
private void ReSelect()
{
this.txt_Date1.Text = myString[0];
this.txt_Temp1.Text = myString[1];
this.txt_Weather1.Text = myString[2];
this.txt_WindPower1.Text = myString[3];
this.txt_Date2.Text = myString[0];
this.txt_Temp2.Text = myString[1];
this.txt_Weather2.Text = myString[2];
this.txt_WindPower2.Text = myString[3];
}
private void timer1_Tick(object sender, System.EventArgs e)
{
if( this.txt_Date1.Text.IndexOf("月") != -1)
{
this.timer1.Enabled = false;
this.Text = "天氣預報";
}
}
private void menuItem2_Click(object sender, System.EventArgs e)
{
this.Text = "作者:賀星河";
System.Threading.Thread.Sleep(3000);
this.Text = "天氣預報";
}
}
}
1、在VS.NET2003的“解決方案WeatherService”上點擊右鍵,選擇”部署解決方案”,出現一下對話框
圖4-部署解決方案
選擇“部署”,“部署”完成后,手機上將顯示如下界面
圖5、手機界面之一-部署
因為我的PC機器上安裝了.NET Framework1.1SP1,所以會提示這個界面,選擇“確定”,繼續執行安裝部署:
圖6、手機界面之二-選擇安裝位置
選擇安裝位置為”Sotrage Card”,選擇“完成”,這個時候程序就部署完畢了,
使用Resco Explore 2003,找到安裝部署后程序所在的目錄,在 /Sorage/Program Files/WeatherService/ 目錄下面,執行程序WeatherService.exe,將出現如下畫面:
圖7、手機界面之三-開始執行程序 選擇“是”。
之所以出現這個畫面,是因為程序沒有經過系統的認證,也是微軟安全方面的一個體現,即時這個程序會正常執行,也不會冒然打出電話!
程序執行之后,會出現如下畫面,選擇需要查詢的城市名稱,點“確定”
圖8、手機界面之四-程序界面
之后程序標題會變為“正在下載…”,程序通過GPRS上網讀取部署在Internet上的WebService
圖9、手機界面之五-運行界面
稍等幾秒鐘之后,便會看到所需要的天氣信息數據
圖10、手機界面之六-運行結果
新聞熱點
疑難解答