Um, I haven't touch this Blog for a while... So... just a case study.
Usually, I use FTP to find available files to update my mobile application. However,I have a client who doesn't want to install FTP but they have web server.
Therefore, I use the traditional way to update the application, "Make a http query"...
It is pretty simple to use
HttpWebRequest and
HttpWebResponse to validate the version. If the server returns a file link, then I download it and install it.
You can make a HttpWebRequest (http://yourwebsite/?version=1.0.2.0) to find available update. If server redirects you to a cab file, so we have an update.
Once user clicks "Yes", the we start to download and install the cab file.
Have a look the following example in C#. It handles downloading the cab file with progress bar.
private void backgroundWorker1_DoWork(object sender, BCD.ComponentModel.DoWorkEventArgs e)
{
HttpWebRequest myRequest = null;
HttpWebResponse myResponse = null;
string newurl = (string)e.Argument;
string fileName = "", filePath = "";
try
{
bool redirecting = true;
while (redirecting)
{
try
{
myRequest = (HttpWebRequest)WebRequest.Create(newurl);
// we accept any type of file
myRequest.Accept = "*/*";
// set the timeout to 5 seconds
myRequest.Timeout = 5000;
// casts the response
myResponse = (HttpWebResponse)myRequest.GetResponse();
// if we have redirection
if ((int)myResponse.StatusCode == 301 || (int)myResponse.StatusCode == 302)
{
string uriString = myResponse.Headers["Location"];
newurl = uriString;
// and keep going
}
else
{
// gets the final uri
fileName = Path.GetFileName(myResponse.ResponseUri.LocalPath);
// we only want CAB file
if (fileName.ToLower().EndsWith(".cab"))
{
filePath = Path.Combine(Utils.TempPath, fileName);
// gets the total lenth for progress bar
long fileLength = myResponse.ContentLength;
// start with zero
int byteTotal = 0;
// start writing file
using (FileStream fileStream = File.OpenWrite(filePath))
{
// gets the stream from response object
using (Stream remoteStream = myResponse.GetResponseStream())
{
// we make 4 MB as our buffer
byte[] inBuffer = new byte[4 * 1024];
int nRead = remoteStream.Read(inBuffer, 0,
inBuffer.Length);
// we need to put e.Cancel as user may cancel downloading
while (nRead > 0 && !e.Cancel)
{
if (nRead > 0)
fileStream.Write(inBuffer, 0, nRead);
byteTotal += nRead;
// calculate the progress out of a base "100"
double percentage =
(double)(byteTotal) / (double)fileLength;
// update the progress
backgroundWorker1.ReportProgress(
(int)(percentage * 100));
nRead = remoteStream.Read(inBuffer, 0,
inBuffer.Length);
}
myResponse.Close();
myRequest.Abort();
}
}
// if everything is fine
if (!e.Cancel)
{
// write the file time to be same as the original file time
BCD.IO.FileEx.SetCreationTime(filePath,
myResponse.LastModified);
e.Result = filePath;
}
else
{
if (File.Exists(filePath))
File.Delete(filePath);
}
}
redirecting = false;
}
}
catch (Exception ex)
{
redirecting = false;
Utils.WriteToLog(ex);
}
}
}
catch (Exception ex)
{
// if error happens on retriving map, assign the error image instead
Utils.WriteToLog(ex);
}
finally
{
if (myResponse != null)
myResponse.Close();
myRequest = null;
myResponse = null;
}
}