First thoughts on the BlackBerry Pearl
Wednesday, March 07, 2007 11:30:48 AM (GMT Standard Time, UTC+00:00)
I’ve always been adverse to getting a BlackBerry for a few of reasons:
- I don’t get away from work much as it is so I felt having emails on my BlackBerry on the go all the time would be one step too far.
- The size of the BlackBerry –they’re ridiculous, I like my phone to be as small as possible so it interferes with my life as little as possible.
- I’ve heard horror stories about the increase in bandwidths to manage the email push.
Then while we were looking at new contracts over Christmas Stacey picked up the BlackBerry Pearl which was small and sleek and suggested I gave it a go. As she didn’t want to change from her V3 we agreed I’d give it a go for a month and if I didn’t like it I’d have her free upgrade (a Sony Ericsson w810i).
I’ve had the BlackBerry Pearl for well over a month now so I thought I’d share my findings in case anyone else is thinking of getting one.
How does the BlackBerry “work”?
There are plenty of tutorials for the BlackBerry and far more advanced information on how the BlackBerry actually works but I thought it may be worth over viewing how it’s configured and the basic concepts.
BlackBerrys use something called “Push” Technology to retrieve emails, your email client (Outlook, Eudora, Thunderbird etc) classically collects email from a server by contacting the server and getting a list of emails and then downloading the emails. BlackBerrys on the other hand have the email sent to it from the server.
When you first get your BlackBerry you have to configure your email accounts with your BlackBerry’s ISP (in my case O2), you supply them with server details for your mail account (POP3 settings). Your ISP will then periodically check your email account and collect the new email messages which are then encrypted and sent (or pushed) to your BlackBerry (in a similar way to an SMS message). The BlackBerry then decrypts the email and allows you to read it. Simple eh :)
My thoughts on the BlackBerry Pearl
Things I like about the BlackBerry Pearl:
- It’s size –it’s no larger than a lot of the other phones out there at the moment, in fact it’s smaller than my old Motorola V3 while it was closed (though it’s about 5mm longer)
- It’s synchronisation with Outlook. I used to have a Palm LifeDrive to manage my calander, address book and tasks etc and a separate address book on my V3 which didn’t sync correctly with Outlook so the three were nearly always different –that and I hated having to carry around the LifeDrive as it was just extra bulk... The BlackBerry Pearl however seamlessly manages it all which has meant that I’ve started managing my to-do list a lot more efficiently as well as my address book.
- The size and clarity of the screen.
- Today Plus theme –an extra download but well worth it as it summarises all the info you need to know at a glance on the home screen.
- Battery life –quoted at around 8½ hours talk time I’m certainly getting at least this. A lot of the time I plug it in via USB while I’m working which charges it but I’ve had a couple of weekends away recently which has meant it’s not got charged and it happily coped with the (for me) heavy use without an issue.
- The complete call log of all incoming and out going calls on a user basis –this is great for me if I need to know how long I spent speaking to a client etc (I tend to use my mobile for most outgoing calls as they’re all free ;)).
- The degree of customisation (though this is also a downside as it is somewhat complicated).
- The fact you can customise what the side buttons do.
- The standby button –why it has a keylock I don’t know as it gets in the way of the standby button.
- The voice dialler –that’s awesome.
- VoiceRecorder+ (a voice memo recorder for the BlackBerry Pearl from ShapeServices – www.shapeservices.com)
- The fact you can add delays into the number dialling to quickly and automatically navigate the IVR options for systems you regularly use.
Things I dislike about the BlackBerry Pearl:
- It’s pretty complicated. Unlike most phones these days each application has it’s own settings and finding where they are is sometimes a real PITA.
- You can’t set ringing profiles to activate at certain times of the day.
- You can’t send SMS messages from it through your computer.
- It doesn’t ring and vibrate at the same time.
- The ringer is a little quiet at times (though people suggest drilling holes in the back of the casing sorts this).
- The key lock which sometimes gets in the way of taking the phone out of standby –I expect there’s a way of turning it off but I’ve not found it yet.
All in all I think the BlackBerry Pearl is a superb phone and I’ll certainly be keeping it. I’ve setup a filter to ensure I don’t get spam coming through on it but I still get between 10 and 50 emails a day on it, the data transfer is still low (it’s still under 100KB) but I don’t surf the web etc.
O2 offer a deal at the moment where you can have unlimited data for £10pm on top of your bill, my thinking is if I start to use more than £10 of data a month I’ll upgrade but atm it’s all good. In regards the additional load on our mail server I’ve not noticed anything significant but I’ll analyse this in a couple of months as the calls should be clear. To avoid spam emails I’ve setup a separate mail account that the O2 server collects from, then from my main email accounts I forward any that are sent directly to me and without my spam filter’s headers added to my GMail account which then filters pretty much everything else missed by my server’s filter before forwarding it onto my BlackBerry account. I realise this is a slightly long winded method of managing it but it has meant that 99.9% of all spam has been ignored. There have been a couple of emails missed (i.e. where I’ve been CC’d) but I can live without having those on the go ;)
I had an issue when I first got the BlackBerry Pearl that all numbers would be dialled with the prefix of +44 and the leading 0. As it happens, the fix is pretty simple:
- Open the call log
- Press the menu key (the BlackBerry icon)
- Choose “General Options”
- Choose “Smart Dialing”
- Change the country code to +44
Why didn’t you pick up the phone?
Monday, March 05, 2007 10:02:29 AM (GMT Standard Time, UTC+00:00)
** WARNING ** this post is most definitely a rant
A couple of weeks ago Stacey and I were hit with some really nasty flu like bug (not man flu :P), I don’t think I’ve ever had flu before so I’m not sure if it was flu but this was nasty, I was (among other things) hallucinating the duvet wanted me to join a cult but that’s a whole other story!
I like talking to people and running my own business I tend to have my phone on me wherever I go, very infrequently do I not answer within a couple of rings. A couple of days before I was hit with this bug, I said I would get back to one of the guys that passes us a little work every now and again about a potential client he had.
Being ill however (and I mean bed-ridden) I didn’t manage it so he gave my mobile a call –great, only it was in the other room and I really couldn’t be bothered to get up and get it so I left it. A couple of minutes later I get an SMS through (which turned out to be from my answer phone) just before the house phone started ringing. As it was within arms length I answered to a very grumpy git bitching on about how I was ignoring him and why didn’t I answer my mobile –was it because I didn’t have caller id on that line etc.
As it turns out, we do have caller id on all phones and I did know it was him and it wasn’t that I was avoiding him, it was merely that I was too ill to answer. FWIW I never ignore people when they call, if it’s you and you’re after something and I don’t want to talk to you I’ll just tell you so, I don’t have the time to arse around playing games so grow up!
SQL Server SP2 quirks
Wednesday, February 28, 2007 6:35:40 PM (GMT Standard Time, UTC+00:00)
Ok, as sad as it sounds I've been looking forward to the latest SQL Server service pack since I heard about some of the issues it fixed as there was two "glitches" in particular that seriously bugged me, namely:
- Loading a SQL file into the query editor on a live connection would ask you to log in again -this bugged the hell out of me because I have a number of routines saved on my disk as SQL files that manage client's servers and so I don't always have the password to easily hand which would just delay development (ok all be it by 30seconds or so but that's not the point)
- It would never remember my password in the initial splash screen, again see why above.
Anyway, it's great to see that these two points were fixed as well as a load of other issues but I couldn't help but chuckle when I saw the new context menus, I don't know about you but when editing this table I didn't know which one I needed to choose:

FWIW you need "Design" to open the design view and "Edit" to generate a SQL CREATE Script. Genius!
Employing someone 101
Tuesday, February 27, 2007 9:22:48 AM (GMT Standard Time, UTC+00:00)
Stacey recently wrote an excellent brief on the pro's and con's of employing someone however this morning when I came to post it online I realised that it was deleted when I formatted the laptop for a system demonstration last week. Luckily however I have a hard copy so I'll have it re-typed and put online ASAP.
In the meantime however I shall reflect with this classic (which I’m looking to implement in The Site Doctor ASAP)…
Attire
It is advised that you come to work dressed according to your salary. If we see you wearing Prada sneakers and carrying a Gucci bag, we assume you are doing well financially and therefore you do not need a raise.
If you dress poorly, you need to learn to manage your money better, and therefore you do not need a raise. If you dress in-between, you are right where you need to be and therefore you do not need a raise.
Personal Days
Each employee will receive 104 personal days a year. They are called Saturday and Sunday.
Lunch Break
Skinny people get 30 minutes for lunch as they need to eat more so that they can look healthy.
Normal size people get 15 minutes for lunch to g et a balanced meal to maintain their average figure.
Sick Days
We will no longer accept a doctor statement as proof of sickness. If you are able to go to the doctor, you are able to come to work.
Restroom Use
Entirely too much time is being spent in the restroom. There is now a strict 3-minute time limit in the stalls. At the end of three minutes, an alarm will sound, the toilet paper roll will retract, the stall door will open and a picture will be taken. After your second offence, your picture will be posted on the company bulletin board under the "Chronic Offenders" category.
Surgery
As long as you are an employee here, you need all your organs. You should not consider removing anything. We hired you intact. To have something removed constitutes a breach of employment.
Thank you for your loyalty to our company. We are here to provide a positive employment experience. Therefore, all questions, comments, concerns, complaints, frustrations, irritations, aggravations, insinuations, allegations, accusations, contemplation, consternation and input should be directed to the State Unemployment Offices.
DasBlog RSS Feed Macro
Saturday, February 24, 2007 2:39:04 PM (GMT Standard Time, UTC+00:00)
As part of my blog’s re-design I wanted to integrate my statistics from Last.FM which monitors what music you’re listening to and generates a stack of statistics about your listening habit (see About Last FM for more information).
Anyways, I started writing my own RSS macro when I came across one already developed by John Forsythe (http://www.jforsythe.com/) which did pretty much exactly what I was planning on developing, the only difference though was that his was hard-coded to preset node names whereas I was planning on using an XSL file to format mine to offer maximum flexibility in the long run so I updated his with the use of reflector (thanks to John Forsythe though!!).
There are a couple of difference to note with this code and John Forsythe's:
- The RSS retrieval is no longer handled by an external library -in this instance I wanted to keep this as simple and stand-alone as possible.
- There is no max item count at present -this is mainly because I didn't need it for the Last.FM Feed, I may alter that later.
Source code for a dasBlog XSL based RSS reader
using System;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Text;
using System.Web;
using System.Web.UI;

using newtelligence.DasBlog.Runtime;
using newtelligence.DasBlog.Web.Core;

namespace TSDMacros
{...}

{
public class TheSiteDoctor
{...}

{
protected SharedBasePage requestPage;
protected Entry currentEntry;

public TheSiteDoctor(SharedBasePage page, Entry entry)
{...}

{

requestPage = page;

currentEntry = entry;

}

/// <summary>
/// A dasBlog macro to retrieve an RSS feed and apply XSL to
/// it before caching it for x minutes
/// </summary>
/// <param name="xslVPath">The virtual path of the XSL file</param>
/// <param name="rssPath">The RSS feed URL</param>
/// <param name="minutesToCache">Number of minutes to cache the file for</param>
/// <param name="debugMode">Output the debug information</param>
/// <returns>A control that can be inserted into a dasBlog template</returns>
public virtual Control GetRSS(
string xslVPath,
string rssPath,
int minutesToCache,
bool debugMode)
{...}

{
string cacheVDir =
"./content/getrsscache/";
string cachedFileLoc =
String.Empty;

StringBuilder output =
new StringBuilder();

bool writeToCache =
false;
bool cacheExpired =
false;
bool cacheExists =
false;
Debug output
#region Debug output
if (debugMode)
{...}

{

output.Append(
"<strong><start debug></strong><hr />\r\n");

output.AppendFormat(
"<i>RssPath</i>: {0}<br />\r\n", rssPath);

output.AppendFormat(
"<i>minutesToCache</i>: {0}<br />\r\n", minutesToCache);

output.AppendFormat(
"<i>CacheStorageFolder</i>: {0}<br />\r\n", cacheVDir);

output.Append(
"<hr />\r\n");

}
#endregion
Check whether we need to cache or not
#region Check whether we need to cache or not
if (minutesToCache >
0)
{...}

{

writeToCache =
true;
//Find the cache directory
string cacheDir =
HttpContext.Current.Server.MapPath(cacheVDir);
//Work out what the file would be called based on the RSS URL
cachedFileLoc = Path.Combine(cacheDir, HttpUtility.UrlEncode(TheSiteDoctor.GetMd5Sum(rssPath)) +
".cache");
Debug output
#region Debug output
if (debugMode)
{...}

{

output.AppendFormat(
"<i>cache file</i>: {0}\r\n", cachedFileLoc);

}
#endregion
if (!File.Exists(cachedFileLoc))
{...}

{

cacheExpired =
true;
Debug output
#region Debug output
if (debugMode)
{...}

{

output.Append(
"<i>cache age</i>: no file exists<br />");

}
#endregion
}
else
{...}

{

FileInfo info1 =
new FileInfo(cachedFileLoc);

TimeSpan span1 = (TimeSpan)(DateTime.Now - info1.LastWriteTime);
if (span1.TotalMinutes > minutesToCache)
{...}

{

cacheExists =
true;

cacheExpired =
true;

}
Debug output
#region Debug output
if (debugMode)
{...}

{

output.AppendFormat(
"<i>cache age</i>: : {0} min old <br />\r\n", span1.TotalMinutes);

}
#endregion
}

}
else
{...}

{
Debug output
#region Debug output
if (debugMode)
{...}

{

output.Append(
"<strong>caching disabled - CacheStorageAgeLimit=0</strong><br /><span style=\"color:red; font-weight: bold;\">FYI: All requests to this page will cause a new server request to the RssPath</span><br />");

}
#endregion
cacheExpired =
true;

}

#endregion
Debug output
#region Debug output
if (debugMode)
{...}

{

output.Append(
"<hr />");

}
#endregion
//Check whether or not the cache has expired
if (cacheExpired)
{...}

{
Debug output
#region Debug output
if (cacheExists & debugMode)
{...}

{

output.Append(
"<strong>file cache is expired, getting a new copy right now</strong><br />");

}
else if (debugMode)
{...}

{

output.Append(
"<strong>no cache, getting file</strong><br />");

}
#endregion
//The cache has expired so retrieve a new copy
output.Append(TheSiteDoctor.delegateRss(xslVPath, rssPath,
0, writeToCache, cachedFileLoc, debugMode));

}
else
{...}

{
Debug output
#region Debug output
if (debugMode)
{...}

{

output.Append(
"<strong>cool, we got the file from cache</strong><br />");

}
#endregion
//The cache still exists and is valid
StreamReader reader1 = File.OpenText(cachedFileLoc);

output.Append(reader1.ReadToEnd());

reader1.Close();

}
Debug output
#region Debug output
if (debugMode)
{...}

{

output.Append(
"<hr /><strong><end debug></strong>");

}
#endregion

output.Append(
"\r\n<!-- \r\ndasBlog RSS feed produced using the macro from Tim Gaunt\r\nhttp://blogs.thesitedoctor.co.uk/tim/\r\n-->");

return new LiteralControl(output.ToString());

}

/// <summary>
/// RSS feed retrieval worker method. Retrieves the RSS feed
/// and applies the specified XSL document to it before caching
/// a copy to the disk -this should be called after it has been
/// established the cache is out of date.
/// </summary>
/// <param name="xslVPath">The virtual path of the XSL file</param>
/// <param name="rssPath">The RSS feed URL</param>
/// <param name="timeoutSeconds">Number of seconds before the request should timeout</param>
/// <param name="writeCache">Whether to cache a copy on disk</param>
/// <param name="xmlPath">Physical path of the XML file on the disk</param>
/// <param name="debugMode">Output the debug information</param>
/// <returns>An XML document as a string</returns>
private static string delegateRss(
string xslVPath,
string rssPath,
int timeoutSeconds,
bool writeCache,
string xmlPath,
bool debugMode)
{...}

{

StringBuilder output =
new StringBuilder();
bool errorThrown =
false;
string cacheVDir =
"./content/getrsscache/";
string xslPath =
HttpContext.Current.Server.MapPath(xslVPath);

try
{...}

{
//TODO: Replace this with a HttpRequest and timeout to ensure the visitor is not left waiting for the file to load
//Load the XML
System.Xml.XmlDocument xmlDoc =
new System.Xml.XmlDocument();

xmlDoc.Load(rssPath);

//Load the XSL
System.Xml.Xsl.XslTransform xslDoc =
new System.Xml.Xsl.XslTransform();

xslDoc.Load(xslPath);

StringBuilder sb =
new StringBuilder();

StringWriter sw =
new StringWriter(sb);

//Apply the XSL to the XML document
xslDoc.Transform(xmlDoc,
null, sw);

//Append the resulting code to the output file
output.Append(sb.ToString());

}
catch (
Exception ex)
{...}

{

errorThrown =
true;
Debug output
#region Debug output