Monday, April 30, 2007

This is very sad,  but this is every single personal mobile device I have ever owned.   I may have the order a bit wrong and missed a few Nokia's along the way,   but this I think is the complete list to date:

Orange SPV E650
Imate SP5
Imate Jasjar
Orange SPV C500  
Orange SPV E200  
Orange SPV E100  
HP Ipaq 5500 
Orange SPV   
Sony Ericsson T68  
Compaq Ipaq 3600  

Nokia - can't

rember model

 
Nokia 8110   
 Cassiopeia
Orange 7100
Orange 2100
Apple Newton
MessagePad
Cambridge
Computers Z88
Psion 3c
Microwriter Agena
Sony CMH-333
Psion Organiser II

Monday, April 30, 2007 8:18:51 PM UTC  #    Comments [0]  | 

A quick tip.   When producing Mobile web-pages,  I always add an accesskey attribute to any link, like -

<html>
<body>
<a href=”news.aspx" accesskey="1" >1 - What’s New </a>
</body>
</html>

This simple addition give the ability to jump around pages just from a phone keypad.

Monday, April 30, 2007 7:43:50 PM UTC  #    Comments [0]  | 
Sunday, April 29, 2007

 

 

So in the previous post, I outlined what Geocaching Radar is.     The mobile application I'll share with you uses co-ordinates from a connected GPS to on a button press take you to the Geocaching website to find caches nearest to your current location.

We make use of the Windows Mobile 5 / 6 intermediate GPS driver for simplicity.   For Smartphone users you'll need to download the Windows Mobile 6 SDK which has a utility for setting up the intermediate driver.  Download SDK here

If you'd like the source of this application, drop me a mail and I'll happily share.

Sunday, April 29, 2007 10:41:20 AM UTC  #    Comments [0]  | 
Friday, April 27, 2007

So for a few years, I've been into Geocaching.    For those of you who never seen this amazing world wide treasure hunt look at the official website -

http://www.geocaching.com

Now here's a great way to use your Windows Mobile device,  to lookup the nearest hidden caches to you (i.e Geocaching radar).     The website lets you find the nearest co-ordinates to you.    Taking the form of a URL like -

http://www.geocaching.com/seek/nearest.aspx?lat=52.2656&lon=0.18905

So I've added a simple geocache menu option to the application I built and shared in this blog post at -

http://www.binaryrefinery.com/main/PermaLink,guid,e63c722f-5798-4fee-8764-f787b46ee29d.aspx

 

Here's the source for this, little useful button -

 

private void mnugeocache_Click(object sender, EventArgs e)
{
GpsPosition pos = gps.GetPosition();
if (!(pos.LatitudeValid || pos.LongitudeValid))
{
DialogResult ret = MessageBox.Show("Position Is Not Currently Valid, Lookup Anyway?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (ret == DialogResult.No) return;

}
string url=@"
http://www.geocaching.com/seek/nearest.aspx?lat="+position.Latitude+"&lon="+position.Longitude;

System.Diagnostics.Process.Start("iexplore.exe", url);
}

 

 

Friday, April 27, 2007 8:38:22 PM UTC  #    Comments [0]  | 

Those nice folks at Streetmap (http://www.streetmap.co.uk )  have a very handy webpage that lets you obtain the Longitude/Latitude of a UK Postcode at -

http://www.streetmap.co.uk/gridconvert.html

This is so nice for geo-encoding UK postcodes, i.e plotting customers on a map etc..   Given the flexibility of the service,   I decided to make it line-of-business friendly and wrap the postcode to long/lat lookup into a web-service.

 

The return string is of the form -

<?xml version="1.0" encoding="utf-8" ?>

<string xmlns="http://tempuri.org/">51.625128:-0.150448:Provided By www.streetmap.co.uk:http://www.streetmap.co.uk/streetmap.dll?grid2map?X=528126&Y=193432&arrow=Y&adkey="~"</string>

So we return a decimal longitude, latitude and a credit back to streetmap and a link to the streetmap, map.

Here's the source,   the string handling is a little brutal but it works great.

 

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Net;
using System.IO;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
public Service () {

//Uncomment the following line if using designed components
//InitializeComponent();
}

[WebMethod]
public string GeoEncode(string UK_Postcode) {

if (UK_Postcode == "") return "No Input"
string lookuppostcode = UK_Postcode.Replace("-", "");
lookuppostcode = lookuppostcode.Replace(" ", "");
string request = @"
http://www.streetmap.co.uk/streetmap.dll?GridConvert?type=Postcode&name=" + lookuppostcode;
string result = "ERROR"

HttpWebRequest myReq =
(HttpWebRequest)WebRequest.Create(request);

// Sends the HttpWebRequest and waits for the response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse) myReq.GetResponse();
try
{
Stream response = myHttpWebResponse.GetResponseStream();
StreamReader readStream = new StreamReader(response, System.Text.Encoding.GetEncoding("utf-8"));
string htmlresponse = readStream.ReadToEnd();
string whattofind = "Lat</strong> (WGS84) </td> <td width=\"50%\" align=\"center\" valign=\"middle\">"
int indexoflonglatbit = htmlresponse.IndexOf(whattofind);
if (indexoflonglatbit > -1)
{
htmlresponse = htmlresponse.Substring(indexoflonglatbit + whattofind.Length);
string latitude=htmlresponse.Substring(htmlresponse.IndexOf("("));
latitude=latitude.Substring(2,latitude.IndexOf(")")-3);
whattofind="Long</strong> (WGS84) </td> <td width=\"50%\" align=\"center\" valign=\"middle\">"
indexoflonglatbit = htmlresponse.IndexOf(whattofind);

if (indexoflonglatbit > -1)
{
htmlresponse = htmlresponse.Substring(indexoflonglatbit + whattofind.Length);
string longitude = htmlresponse.Substring(htmlresponse.IndexOf("("));
longitude = longitude.Substring(2, longitude.IndexOf(")")-3);

string url_to_follow = htmlresponse.Substring(htmlresponse.IndexOf( "http://www.streetmap.co.uk/streetmap.dll?grid2map"));
url_to_follow=url_to_follow.Substring(0,url_to_follow.IndexOf("\"")+3);

result = latitude + ":" + longitude+":Provided By www.streetmap.co.uk:"+url_to_follow;
}

}

}
finally
{
// Releases the resources of the response.
myHttpWebResponse.Close();
}
return result;

}
}

 

 

Friday, April 27, 2007 2:39:58 PM UTC  #    Comments [0]  | 

Ok,   re running the unlock tool again (see previous) post,  has now enabled me to Debug applications.

So I'm pretty much sorted.    Web browser, is still a bit unreliable,  but I'll put that down to living in the sticks :-)     Thanks to Jason Langridge for confirming I was following the correct procedure to unlock the phone.    In conclusion the Orange SPV E650  is a great phone and one I can now develop for... :-)

 

* I know I'm showing an HTC VOX,  but its the same as an E650 :-)

Friday, April 27, 2007 12:08:27 PM UTC  #    Comments [0]  | 
Thursday, April 26, 2007

I went through the process at -

http://spvunlock.rd.francetelecom.com/

I loaded Resco Explorer and the registry editor at (nice bit of kit) -

http://www.resco.net/smartphone/explorer/downloads.asp

I then set the 2 registry keys in hklm\security\policies\policies on the phone

to

00001001 value= 1
00001005 value=40

Rebooted the phone and hey presto...

I am pleased to report Live Search Mobile now installs - not sure if the above is related or not,  but it certainly is working,

 

Next mission, is to get Visual Studio 2005 able to debug on the device.   I'm currently getting the following

Error 2 The device security configuration disallowed the connection. Ensure that you have the appropriate certificates on your device for development. Review your SDK documentation for proper security settings for connecting to this device. Device Connectivity Component

 

 Will keep you posted. 

 

Thursday, April 26, 2007 8:42:51 PM UTC  #    Comments [0]  | 

So after last nights   unbox-it quick glee of getting a new phone.     I thought I'd give you an update on experiences of Windows Mobile 6, on Orange UK.   

Web browsing still a problem - its perfect for email,  but IE mobile still doesn't seem to work.   Its loaded one or two pages. 

I Installed MS Deepfish, without an issue, Deepfish seems to load web-pages slightly more reliably than Pocket IE Mobile.

On a positive,  device is very responsive.    Pairing with car-kit, worked really simply.

Soti Pocket Controller Installed no problem.

I tried a sample hello world application from Visual Studio.   I couldn't get it to deploy.   So I'm now on the search for how to unlock the device, 

I tried all the unlock methods on this page

http://wiki.spv-developers.com/index.php/HTC_Application_Unlock_Guide

Windows Live Search Mobile,   doesn't seem to install to a storage card, it just hangs on the installer.    I have a feeling it's to do with the device unlock issue again.

I'll let you know how I get on with unlocking...   I'm itching to test some of my applications...

Thursday, April 26, 2007 2:37:35 PM UTC  #    Comments [0]  | 
Wednesday, April 25, 2007

So its arrived.    Three attempts to call Orange (UK) to get the phone registered (about 45 minutes later) and we're set.   

So first impressions -

  • Where Is Live Messenger?  - can't find it anywhere.
  • Active Sync easy to setup,   email syncing really easily.
  • Internet explorer not loading any pages (!!!!),   can't work this one out  (???) given the above.
  • Little slide out keyboard - fab.
  • Form factor - phone is very THICK, surprised at chunkiness.
  • Man - the screen is amazing,   font a little too big I thought.
  • It has the GREEN colour scheme - great...
  • GPS Intermediate driver control panel not switched on by default.
  • WIFI connection a bit hit and miss,   couldn't work out if I was using WIFI or phone network.
  • Device seems, very fast....   
  • Keypad, is V.small.
  • I thought Live Search Mobile was pre-installed?
  • Tried to use Word Mobile,   how the hell can I create a new document...
  • It ain't doing EDGE where I am,  I'm just getting the G GPRS icon.
  • Internet Explorer not working - I'll say it again.

OK, so mostly good.    We'll see if in the cold light of day if my list changes.

Wednesday, April 25, 2007 10:39:47 PM UTC  #    Comments [1]  | 

This is an interesting and still relevant document on supporting different types of barcode readers generically from within a .Net Compact Framework application.

Its .Net CF 1.0 article but the concepts still very much hold true today.

http://msdn2.microsoft.com/en-us/library/aa446489.aspx

 

Wednesday, April 25, 2007 10:45:01 AM UTC  #    Comments [0]  | 
Tuesday, April 24, 2007

So how old school is this....   This is syncing to a SQL Compact database from a desktop console application.

All I need now is an application....   

This is the class that draws the nice little progress bar...   Note in a change to our published program this is a full framework C# (rather than our usual compact framework)

 

using System;
using System.Collections.Generic;
using System.Text;

namespace CompactFrameWorkConsole
{
public class ProgressBar
{
// draws a progress bar
int intmax = 100;

int intbarlength = 20;
ConsoleColor colend = ConsoleColor.Green;
ConsoleColor colbar = ConsoleColor.Red;
char barchar = '.';
int drawat = -1;

public int DrawAt
{
set
{
drawat = value;
}
}

// properties
public int BarLength
{
set
{
if (value < 0 || value > 80) throw new Exception("Bar Length Out Of Bounds");
intbarlength = value;
}
}

public char BarChar
{
set
{
barchar = value;
}
}

public ConsoleColor ColEnd
{
set
{
colend = value;
}
}

public ConsoleColor ColBar
{
set
{
colbar = value;
}
}

// constructors
public ProgressBar(int intmax)
{
if (intmax <= 0) return;

this.intmax = intmax;

}

public ProgressBar()
{

}
public void Hit(int val)
{

if (drawat > -1)
Console.CursorTop = drawat;

Console.CursorLeft = 0;
Console.ForegroundColor = colend;
Console.Write("[");
Console.ResetColor();

decimal barsize = (decimal) intbarlength / (decimal) intmax;
int strlen =(int) ((decimal) val * barsize);
if (strlen == 0)
Console.Write(" ".PadRight(intbarlength));
else
Console.Write(barchar.ToString().PadRight(strlen, barchar).PadRight(intbarlength));

Console.ForegroundColor = colend;

Console.Write("]");
Console.ResetColor();

}

}
}

Tuesday, April 24, 2007 9:00:05 PM UTC  #    Comments [0]  | 

Here's something todo with your GPS.    Use your home co-ordinates to make a nice sundial for your garden or an outside wall...

Those sundials you buy from the garden centre don't factor where you are in the world.  So I've found a nice bit of software that dows all this for you.

 

Quote from the Sun Shadows website -

This software does all the calculations to allow you to build a wall mounted dial for a wall that faces up to 60 degrees away from due South.  It takes into account your latitude and longitude to provide you with a highly accurate and unique timepiece.  It is not possible to design a more accurate sundial.

http://www.sunshadow.co.uk/index.html

 

Technorati tags:
Tuesday, April 24, 2007 6:50:08 PM UTC  #    Comments [0]  | 

Strangely I get asked lots about setting the clock on a Windows Mobile device.     I use this bit Compact Framework C#  code all the time,   remember it sets the base GMT date/time of the device.   To use copy and paste the below and simply call  SetBaseTime(<your datetime>)

[StructLayout(LayoutKind.Sequential)]
private struct SYSTEMTIME
{
public short year;
public short month;
public short dayOfWeek;
public short day;
public short hour;
public short minute;
public short second;
public short milliseconds;
}

[DllImport("coredll.dll")]
private extern static bool SetSystemTime(ref SYSTEMTIME lpSystemTime);

public static void SetBaseTime(DateTime ourtime)
{
SYSTEMTIME st = new SYSTEMTIME();
st.year = (short)ourtime.Year;
st.month = (short)ourtime.Month;
st.dayOfWeek = (short)ourtime.DayOfWeek;
st.day = (short)ourtime.Day;
st.hour = (short)ourtime.Hour;
st.minute = (short)ourtime.Minute;
st.second = (short)ourtime.Second;
st.milliseconds = (short)ourtime.Millisecond;
if (!SetSystemTime(ref st))
{
throw new Exception("Time Not Set");
}

}

Tuesday, April 24, 2007 9:31:39 AM UTC  #    Comments [0]  | 
Monday, April 23, 2007

Rob Tiffany (MS) is setting up an amazing SQL Mobile replication extravaganza for MEDC next week, which looks great.

http://blogs.msdn.com/robtiffany/default.aspx

One of Rob's screenshots shows some Windows Console applications syncing back to the 4 tier SQL Mobile environment.      That got me thinking, up until now I'd never tried building a proper .Net desktop application that will synchronise  just like a mobile device.

So today I thought I would give it a try.     After installing SQL Compact from

http://www.microsoft.com/downloads/details.aspx?FamilyID=e9aa3f8d-363d-49f3-ae89-64e1d149e09b&DisplayLang=en

I had a go at porting a mobile app. just to test the concept

15 minutes later,   I got it all working.    It works so, so well...

 

I'm now thinking about using a SQL Compact data-source for a Web-site.   It will be much cheaper to do this than pay for a hosted SQL Server.  Hmmm possibilities...

Monday, April 23, 2007 8:56:38 PM UTC  #    Comments [0]  | 

I've just switched over from Vodafone to Orange (I have no loyalties where new devices are concerned).

Order process was a bit of a nightmare.   Lots of postcodes have changed in the Cambridge (UK) area, so Orange didn't believe that my credit card was registered to my home address.  This was I think due to their credit card fraud checking system being out of step with their bank details system.

So extended order process aside on Wednesday I'll get some Windows Mobile 6 goodness in my life with one of these -

http://shop.orange.co.uk/shop/show/handset/orange_spv_e650/detail/pay_monthly

Monday, April 23, 2007 3:24:44 PM UTC  #    Comments [0]  | 
Sunday, April 22, 2007

So I'm about to embark on a new mobile project tomorrow.  Wow, fresh start new Visual Studio Solution,  don't you just love it...

The solution I am putting in place is a mobile field service application for a client.    We're currently looking at hardware but I suspect it will be something from the Symbol range.   

So the interesting thing about this project is that it requires an absolute network connection back to a base ERP system.    The reason this is is so critical is that as the mobile user enters values business decisions need to be made in almost realtime to allocate product into lots and organise onwards manufacturer and distribution down the supply chain.   Additionally their is interplay between mobile users, so updates from one mobile device needs to cause menus and things to change on all of the other devices in this solution.

So for this architecture to work, we're looking at either -

  1. Compact Framework app calling into secured web-service.
  2. Browser Based (Mobile AJAX - of course).

The other interesting element of this, is that mobile printing is required (printing of barcode labels).

This would appear to rule out option 2 (the browser solution).     However given that this is a large scale deployment than this may be the best route.     The mobile printing 'could' be triggered from a native code Active X - although I'm personally a little scared by this.

The other key aspect is that this solution needs to work over the public phone network, with bluetooth attached printers.   Back to option 1, winning again, as we can minimise network traffic (and cost) by using something running on the device.

Its amazing that mobile technology still provokes such interesting technical challenges.   Although the work this week on Mobile AJAX is fun,    there are still many an instance where writing code that runs on the device is the way to go...

Sunday, April 22, 2007 6:45:06 PM UTC  #    Comments [2]  | 
Saturday, April 21, 2007

Ok,   so here is a quick guide to how I produced the mobile AJAX RSS news reader at-

http://www.binaryrefinery.com/mobile

The design goal was to present a quick summary of my news feed so that it can be easily browsed from a mobile device.   I figured AJAX would make a good choice as it allowed the relatively large file size (compared to the home page) of the RSS feed to load in the background while still presenting the home page to the user.

OK first up,   I wrote this AJAX feed reader with notepad (well actually I used Textpad , which is a great editor), so this is literally simplicity itself.  The AJAX feed reader is just one single HTML page and a single GIF89 for the feed loading icon (i.e ).

So lets walk through the code behind the page -

Step 1 - this is the top part of the page,   note when the page loads in the onload it calls the function to go abd pull out the RSS feed.    Also see at the bottom we have a variable g_request to store the AJAX request.    g_feedXML will store the XML document that is the RSS feed.

<html>
<head>
<title>Richard Jones</title>
</head>

<body onload='requestRSSFromServer()'>

<script type="text/javascript">

var g_request; // XMLHTTP request object
var g_feedXML; // XML document object

 

Steb 2 - So this is where the action all happens.    The first step, is we work out the URL of the RSS feed.   This URL is derived from window.location.href .   This variable gives the fulll path of the page you are requesting, i.e the mobile home page.    The reason I do this is that when I'm debugging I'm using a different URL to the one that will go into production.   This means that I don't have to change any code when I roll out into live (a good move in my book).

With me so far?   Next bit is to actually go and asynchronously get the RSS feed at the URL, we have just established.    Just before this we set a couple of controls on the main page to invisible until the feed has been downloaded.   Interestingly to switch form elements on and off,  you have to resort to programmatically setting their style,  like -

document.all.morelink.style.visibility = 'hidden';    // or 'visible'

The next line is where the action is, is -

g_request.onreadystatechange = processResponseArticles;

this is the event handler that will fire, when we get some form of response back from sending our request for the RSS feed.   processResponseArticles    is where we handle asynchronously when we get the page back.

function requestRSSFromServer()
{

var feedurl = "";

var sPage=window.location.href;
sPage = sPage.substring(0,sPage.lastIndexOf('/') );
sPage = sPage.substring(0,sPage.lastIndexOf('/') );
feedurl=sPage+"/main/SyndicationService.asmx/GetRss" ; // RSS feed url

document.all.articleList.style.visibility = 'hidden'; // Hide some controls on the form until we get the feed
document.all.morelink.style.visibility = 'hidden';

// Cancel any outstanding requests.
if (g_request)
{
g_request.abort();
}
g_request = new ActiveXObject("Msxml2.XMLHTTP");
g_request.onreadystatechange = processResponseArticles; // go asynchronously get the feed
g_request.open("GET", feedurl, true);
g_request.send();

}

Step 3 - This bit handles receiving the response back, when we get something back from requesting the RSS feed.     I think this is fairly self explanatory.

Note that when we have got the full document downloaded we can go, populate the drop down list of available news articles.

function processResponseArticles()
{

// Done getting response.
if (g_request.readystate == 4)
{
// Success.
if (g_request.status == 200)
{
// Treat as a plain-text reply.
g_feedXML = new ActiveXObject("Msxml2.DOMDocument");
g_feedXML.loadXML(g_request.responseText);

// Display the list of articles.
loadarticleList();

// display our selected article
populatearticlebox();
}
else
{
alert("Could not get requested feed from server.");
}

}
}

</script>

Step 4 (almost there) - this is the function that populates the dropdown list from the XML RSS feed we have downloaded.   Note it also switches on, the forms controls to indicate that the feed has loaded (and switches off the spinner graphic).    We loop around the 'item' XML elements in our RSS feed.    The title of each feed is held in an XML element called 'title'.

// Initialize the first dropdown (categories) from the XML.
function loadarticleList()
{
// Get all the categories.
items = g_feedXML.getElementsByTagName('item');
document.all.articleList.length = 0;

for (g = 0; g < items.length; g++)
{

titles=items[g].getElementsByTagName('title')
option = new Option();
var ourtext=titles[0].text;
option.text = ourtext;
option.value = ourtext;
document.all.articleList.options.add(option);
}
document.all.statustext.innerHTML='Latest Articles:'; // this also switches off spinner image
document.all.articleList.style.visibility = 'visible';
document.all.morelink.style.visibility = 'visible';
}

 

Step 5 -   This is the body of the HTML page itself.    Note how minimal it is.    When a user makes a selection from the dropdown list,  we populate our article.

<body>

<b>R i c h a r d&nbsp;&nbsp;&nbsp;J o n e s</b><br>
-- Mobile Lob Blog --

<form id='myForm'>

<div id='statustext'><img src='images/spinner.gif'>&nbsp;&nbsp;Loading Feeds...</div>
<select id='articleList' onchange='populatearticlebox()'></select>
<hr>
<div id='bodytext'></div>

<a href="" id='morelink'>More...</a>
</form>

</body>
</html>

 

Step 6 (final bit, honest) -   Here we paint the body of the article onto the web-form.   We pull out the relevant bit of the XML RSS feed based on which line we have selected on our drop down list of articles.   We also set the 'more' link to the source URL of the article

function populatearticlebox()
{
selectedIndex = document.all.articleList.options.selectedIndex;
categoryName = document.all.articleList.options[selectedIndex].value;

// Search the XML for the selected category.
items = g_feedXML.getElementsByTagName('item');
descriptions = items[selectedIndex].getElementsByTagName('description');
document.all.bodytext.innerHTML ="<strong>"+categoryName+"</strong><br>"+descriptions[0].text;

try
{
links = items[selectedIndex].getElementsByTagName('link');
document.all.morelink.href=links[0].text;
}
catch(e)

{

}

}

 

So that's just about it.   Obviously this is a fairly simple sample.   The write up took way longer than actually writing the code (the usual story).   Next week we'll have a go at using this for some real Mobile LOB work pulling business information in realtime out of a database or somethink like that :-)  

Saturday, April 21, 2007 5:17:54 PM UTC  #    Comments [0]  | 
Friday, April 20, 2007

In the days of old when we were building LOB mobile applications on SQL CE 2.0 (it seems like only the year before last (and it was) ).    We had the restriction of only a single connection to the database open at any time.

Our applications had to be written to ensure with ruthless efficiency that only one connection was open at any one time.       We coded that into our applications to ensure that we explicitly created, opened, closed and disposed a connection pretty much every time we issued a SQL command

Since we're now in the world where in SQL Compact, we can have multiple connections open to the database we don't have to be as rigid.    So to bring things up to date and change to using a singleton class for our database connection object,  we're even going for most cases keep the database connection open (how brave is that).      Our singleton class that keeps the database connection, will implement IDispose so we can clear up resources if things go wrong.

Yuri Fenyuk and Mike Holland (told you I'd mention you guys)  in my team have done some benchmarking and it looks like this is now the way to go.    The overhead on memory is negligible and certainly it seems really fast.   To hell with the safety of single connections I say....

 

Technorati tags: ,
Friday, April 20, 2007 3:13:49 PM UTC  #    Comments [0]  | 
Wednesday, April 18, 2007

I've been thinking for a while,  how I could put a summary of my news feed on a mobile version of my website.

I figured I'd have a go at doing this using AJAX.   AJAX is the bread and butter (so they tell me) of WEB 2.0.    Wikipedia gives a nice AJAX overview at -

http://en.wikipedia.org/wiki/AJAX

 

Windows Mobile 6, is marketed as supporting AJAX technology but reading this article from the IE Mobile Blog (thanks Steve Meredith), it seems like it has been supported for a while -

http://blogs.msdn.com/iemobile/archive/2006/03/16/552865.aspx

 

So what I was trying to-do is build a web-page that lets a mobile user quickly run through my latest new posts.   What better way than having AJAX automatically pull the news articles as the user scrolls through a summary of articles.

So here's the results

Try it yourself at my mobile home page at

http://www.binaryrefinery.com/mobile

or of course just point your mobile device at

http://www.binaryrefinery.com

If you do a view source on the page you can see how it works.   I'll walk through the code next time.

 

Technorati tags: , , ,
Wednesday, April 18, 2007 9:02:18 PM UTC  #    Comments [0]  | 
Tuesday, April 17, 2007

Building  mobile LOB economically is all about re-use.    This might (and I'm sure it does) sound glaringly obvious...    

The first thing to achieve was packaging all of the stuff we use repeatedly into a separate class library.   Its not on the scale of OpenNetCF, but its a set of common stuff that are appropriate to our type of LOB applications.  This applications usually consume data from an ERP system (Dynamics

NAV, SAP, JDE Edwards, MS Access :-) ).   It contains useful methods and forms like a standard SQL Compact synchronization dialog, that kind of thing...

So our built up knowledge all goes into our template class library.     The application we're building references this library.

The final part of any solution is to build a setup cab project, to enable easy peezy deployment.

So in Visual Studio we see a solution that looks like this -

This approach saves a massive amount of time and it means we can concentrate on the build process referencing any ' good stuff' we have built along the way.

Needless to say once about 10 applications were built this way the template class library has built up to contain most of the functionality we are ever asked for.

It hasn't quite left us me the easy life I thought it would; but it sure takes the ' washing up' out of having to do the monotonous stuff each time.

Technorati tags: , , ,

Tuesday, April 17, 2007 3:39:38 PM UTC  #    Comments [0]  | 

MEDC US (Microsoft Embedded Developers Conference), is running next month.

To find out what's on and what sessions are happening look at -

http://www.medc2007.com/rss/US.aspx

Its certainly interesting to see all the new stuff.

 

Technorati tags:
Tuesday, April 17, 2007 11:40:04 AM UTC  #    Comments [0]  | 
Monday, April 16, 2007

Typically in the mobility projects I build I'm targeting between 50 and 150 users.    Although there are some expectations to this project size, this is normally where I'm at.   So to target this user size,   I need to have a server infrastructure comprising of -

Exchange Server- for messaging
ISA Server - for Internet connectivity and firewall.
Sharepoint Services - always comes in handy.
SQL Server - got to be there to hold all that lovely line of business data.

Now at the 50-150 user count that list becomes an ' expensive ask' if not already in existence on a client site.     Of course its rare that the client is a complete greenfield with non of the above but it does happen.

So for the past few installations we've been using Small Business Server 2003.    Its great!.    All of the above products (with the premium version) come in the box.

The best bit, is that a 2 DVD install and its running configured, locked down and ready for action.    Just add the SQL Server Compact Server tools and your ready for line of business action...

Now I'm the wrong person to discuss user CALS and such like,  but from a developers perspective it all works like a charm.   It means I can concentrate on the application and not the plumbing.   

All the product information is here -

http://www.microsoft.com/windowsserver2003/sbs/evaluation/faq/prodinfo.mspx

Monday, April 16, 2007 7:58:25 PM UTC  #    Comments [0]  | 
Saturday, April 14, 2007

(In the words of the White Stripes)

So I'm thinking, doorbells are dumb old device, its a button and a bell...

 

So in the same vein as my Pocket PC Caller ID application, I'm looking at building a new doorbell powered by something embedded and CE or . Net MicroFramework.  

So lets look at the basics;  what could throwing a load of tech at the humble doorbell possibly add.   This is my list -

  • Ability to take photo of the person at the front door - mmmm Windows CE webcam project see (http://msdn2.microsoft.com/en-us/library/aa459161.aspx)
  • Sending remotely via email/IM who's at the door - useful for home security.
  • Not waking up the children - a popup alert on each home PC rather than an intrusive ring.
  • Get rid of that boring ding-dong,  lets play a user defined wav file
  • It would be sooo cool.

 

So I've started the ball rolling,  I've built a test harness program that does the email notification, the sound and the reading of the serial port pins, that will be used for the front door bell switch.

The eventual solution, will I be a headless device (i.e a device with no screen), connected via a serial cable to the door switch.     The headless device will be inside the bell box linked to my home network either wirelessly or with a network cable.  I know you can get X10 doorbell switches,  but I'm trying to do this as contained as possible.

 

The .Net Compact Framework 2.0  has a great event System.IO.Ports.SerialPinChanged

This should allow me to detect a simple pushbutton press, by using (and I haven't thought all this through yet) say the CTSHolding lines on the serial port.

See http://www.aggsoft.com/rs232-pinout-cable/pinout-and-signal.htm

 

We can monitor the property  serialPort1.CtsHolding  to let us know if the door switch has been pressed or not.

So, cool project, early days.   I'll race you!   You try and I'll try and we'll see what we come up with.   

Again let me know if you want the source so far.   Happy to share.

Saturday, April 14, 2007 8:55:39 PM UTC  #    Comments [0]  | 
Thursday, April 12, 2007

It seems like its all about location this week.    This is a fantastic bit of code that I keep on using again and again...     I often need to pull records out of a database ordered by proximity,  i.e a SQL stored procedure like -

 

CREATE PROCEDURE [dbo].[Get_Data]
@long_ float,
@lat_ float
AS
BEGIN
SET NOCOUNT ON;

SELECT top 3 [Address ID], dbo.udfComputeDistance(@lat_,@long_,a.lat_,a.long_) as distance from Addresses as a
order by distance
return 0
END

 

This will return 3 records nearest to a location you specify in a table of addresses that has the long and lats stored against each one.    So the magic all happens in a SQL function called udfComputeDistance  

CREATE FUNCTION [dbo].[udfComputeDistance]
(
@lat1 float,
@lon1 float,
@lat2 float,
@lon2 float
)
RETURNS float
AS
begin
-- dLong represents the differences in longitudes
-- while dLat is the difference in latitudes
declare @dLong float
declare @dLat float
-- To keep the calculation easier to understand,
-- we have simplified it by computing it by parts.
-- This value temporarily holds the value of the
-- first calculation.
declare @temp float
-- Convert the decimal degrees to radians
set @lat2 = radians(@lat2)
set @lon1 = radians(@lon1)
set @lat1 = radians(@lat1)
set @lon2 = radians(@lon2)
-- Compute the degree differences
set @dLong = @lon2 - @lon1
set @dLat = @lat1 - @lat2
-- Compute the first part of the equation
set @temp = (square(sin(@dLat/2.0))) + cos(@lat2) * cos(@lat1) * (square(sin(@dLong/2.0)))
-- Return the approximate distance in miles
-- Note that 3956 is the approximate median radius of the Earth.
return (2.0 * atn2(sqrt(@temp), sqrt(1.0-@temp)))*3956.0
end

 

Now I'm not going to take credit for this brilliant function.   It has come from Kent Tegels of SQL Junkies fame -

http://sqljunkies.com/Tutorial/21DC68CD-1A97-4909-8157-523CA249CC80.scuk

 

 Needless to say, it just does the job.   I use it all the time.

Thursday, April 12, 2007 8:43:17 PM UTC  #    Comments [0]  | 

Ok,  I've got a rudimentary tester now built to work out when we enter a GeoFence.

My maths, is only GCSE standard so,  I'm a little rusty on doing this kind of thing.    So my thoughts for a simple circular fence,   working out when we're inside is just a basic collision detection algorithm.    This bit of C# is what I've come up with  and seems to work.

 

using System;
using System.Text;

namespace GeoFenceProximity
{

 

 

public class LatLong
{

public double Latitude = 0;
public double Longitude = 0;

public LatLong(double Latitude, double Longitude)
{
this.Latitude = Latitude;
this.Longitude = Longitude;
}
}

public class GeoFence
{

private LatLong centerpoint = null;
private double radius = 0;

public double Radius
{
get { return radius; }
set { radius = value; }
}

public LatLong Centerpoint
{
get { return centerpoint; }
set { centerpoint = value; }
}

/// <summary>
/// checks if we are in our fence or not
/// </summary>
/// <param name="tescordinates"></param>
/// <returns></returns>
public bool TestProximity(LatLong tescordinates)
{
double x1,x2,y1,y2;

if (tescordinates.Longitude > centerpoint.Longitude)
{
x2=tescordinates.Longitude;
x1=centerpoint.Longitude;
}
else
{
x1=tescordinates.Longitude;
x2=centerpoint.Longitude;
}

if (tescordinates.Latitude > centerpoint.Latitude)
{
y2=tescordinates.Latitude;
y1=centerpoint.Latitude;
}
else
{
y1=tescordinates.Latitude;
y2=centerpoint.Latitude;
}
return (Math.Sqrt((x2 - x1) + (y2 - y1) ) < radius) ;
}

public GeoFence()
{
}
}
}

 

/// this is the calling bit of code - from a console application

 

 

using System;
using System.Collections.Generic;
using System.Text;

namespace GeoFenceProximity
{
class Program
{
static void Main(string[] args)
{
GeoFence gf = new GeoFence();
gf.Centerpoint = new LatLong(52.262573, 0.19683);
gf.Radius = .0005;

// outside fence
bool blret=gf.TestProximity(new LatLong(52.262573, 1.19683));

 

// inside fence
blret=gf.TestProximity(new LatLong(52.262573, 0.19683));


}
}
}

 

 

Please feel free to let me know what you think.     Obviously testing your location against lot GeoFences is going to be computationally intensive.   I suggest if this works to use some form of grid system to only do the computation for GeoFences known to be in your locality (but that's another exercise)

 

Anyway, hopefully that gives you the basic building blocks to build GeoFenced applications.   Every day's a school day they say...

Thursday, April 12, 2007 7:15:17 PM UTC  #    Comments [0]  | 
Wednesday, April 11, 2007

Ok, in small baby steps,   I've been able to plot on Virtual Earth a circular GeoFence.

As promised I've managed to surround my house (well actually its a little down the road circling the local station to make it look good) -

Have a look at results so far and feel free to view the source to see my code.

My Home Fence

Wednesday, April 11, 2007 10:39:16 PM UTC  #    Comments [0]  | 
Tuesday, April 10, 2007

So first what on earth (pun intended) is a GeoFence?   Have a look at  what I've been reading -

http://msdn2.microsoft.com/en-us/library/ms955270.aspx

and also looking at the Virtual Earth SDK

http://dev.live.com/virtualearth/sdk/

Particularly interesting on plotting polygons and stuff.

 

So I'm having a go at building an Windows Mobile application that will automatically detect when I cross into GeoFence boundaries.   I'm thinking raising events etc.  as you cross into them.  Hmmm lots of lovely code..   Will keep you posted.

 

I wonder how you weather proof a GeoFence?

Tuesday, April 10, 2007 8:08:27 PM UTC  #    Comments [0]  | 

So, this is the final part of showing how my home caller ID solution works.   We've discussed how an old dusty Pocket PC (in my case a Compaq Ipaq 3600),  seems to run just fine as a mini home server.

I guess given the roots of the Windows CE system as an embedded operating system shines through, which is why I'm feeling the benefit.   Obviously this whole set of articles is about a 'home project'   I don't really see the next missile defense system being run on such crude hardware... :-)

So onwards here is a few screenshot of the application.    

Main Screen
Ok, first screenshot shows the main screen of the caller ID application.    When the Ipaq starts up,  I have the caller ID application in the startup group so it boots straight into this.   You can see on the screenshot that I've only had one call today, from a contact who's name I haven't assigned to the phone number.    Obviously when a call is received the list expands (and a little popup balloon is displayed)

Assigning A Name To The Contact
On the Pocket PC, when can assign a name to the number and also view exactly when this number has called us over time.  As follows:

Web Management
From any web-browser on my home network,  I can view who's called and also assign names.   Yes, this is the same Pocket PC application serving up these web-pages (amazing for a little old Ipaq if you ask me)

,

Popup Alerts
On other PC's around the house,   if someone calls I have a little tiny application that pops up to tell you who's called.   This looks like the following -

 

This popup application just listens on a mutlicast TCP port that the Ipaq sends a broadcast to, on any machine on my home subnet.     A little worried when I started to this that I would multicast to the world, when I set this up :-)   However limiting to a 192.168.x.x seems to do the job.

 

Email Alerts

The application can also email me alerts of who's phoned.   Here's the same call arriving by email -

To achieve the email send,   I just using  SMTP (Simple Mail Transport Protocol) to open up a port and send the mail.   Not rocket science but does the job.

Note the phone number is Electrolux's service department,   I don't mind if you all feel the need to phone them as my dishwasher has just broken down :-(

So there you  have it,     Caller ID on an Old Pocket PC.    Let me know what you think.   

If you want the full source drop me an email and I'll share it with you.  (nice guy that I am)

Tuesday, April 10, 2007 11:15:00 AM UTC  #    Comments [0]  | 
Sunday, April 08, 2007

I can't wait for Microsoft upcoming LINQ (Language Integrated Query).

http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx

However I still haven't heard if this technology is supported by the .Net Compact Framework.

At Anglia we've been doing something similar 2005 with our DataMaker technology, see -

Watch Us - Create 3079 Lines Of Data Manipulation Code Automatically

I'd love to know if LINQ is going to do something similar and  integral to the .Net Compact Framework.

Until then,   We are able to create thousands of lines of reliable code that directly maps to SQL tables, views and stored procedures automatically in seconds.

Our home brew solution does the job but it would be great to see how Microsoft positions LINQ for the mobile developer.

Until then, have a look at www.angliabs.com where you can get a full view of how DataMaker is helping us.

Sunday, April 08, 2007 10:14:42 PM UTC  #    Comments [1]  | 
Friday, April 06, 2007

Ok, so here's the next bit.   The most important bit of the solution is the box that reads the caller ID information from the incoming phone line and squirt that data down a serial connection.

I use a box from a company called Crucible technology.    I'm using A BT (British Telecom) phone line, here in the UK.   I can only vouch for this working in this setup.