Phone Number Formatter

When writing apps, you often re-use your code, improving it along the way. One function I’ve used in at least 4 apps (iDialer, web, Phone.com Android app, and another unannounced app) and implemented in 3 languages (Java, Javascript, C) is a phone number formatter.

My requirements for this seemingly simple function:

  1. It must use an easy to configure “dial plan” for formatting.
  2. It must be able to format a “partial” phone number, i.e. one you’re typing in right now, or a complete phone number
  3. It must be able to emulate the behavior of the very excellent iPhone dialer.

Javascript:

To see an older iteration of the function in Javascript, look at my iDialer config page, click on the dialplan “advanced” link.

C:

For an even older iteration, look at my iDialer source code.

Java:

Here is my most current solution, in JAVA:


	/**
	 * A semicolon separated list of formatting strings to format. "N"
	 * represents any single digit. [1-9()-] represents an exact digit. The
	 * underscore "_" represents a SPACE (not an underscore). These rules will
	 * be followed sequentially until one is matched.
	 */
	private static final String DIALPLAN = "+1_NNN_NNN_NNNN;1_(NNN)_NNN-NNNN;NNN-NNNN;(NNN)_NNN-NNNN";

	/**
	 * Formats a phone number according to the rules defined in
	 * {@link #DIALPLAN}.
	 * 
	 * @param number
	 *            the non-formatted number
	 * @param isPartialOk
	 *            true if the number passed in "number" are just the first few
	 *            digits of the formatted number. This might be the case on a
	 *            dialpad where the number is being inputted right now
	 * @return
	 */
	public static String formatDialplanNumber(String number, boolean isPartialOk) {
		StringBuilder output = new StringBuilder(32);

		/*
		 * k = index of "number" that we're trying to match d = index of
		 * "DIALPLAN" that we're trying to match cd = character of "DIALPLAN" at
		 * index "d" cn = character of "number" at index "k" ln = length of
		 * "number" match = does it match so far
		 */
		int k = 0;
		boolean match = true;
		int ln = number.length();
		for (int d = 0; d < DIALPLAN.length(); d++) {

			char cd = DIALPLAN.charAt(d);
			char cn = k < ln ? number.charAt(k) : 0;

			// move on to the next rule
			if (cd == ';') {
				if (match && k == ln)
					break;

				k = 0;
				match = true;
				if (output.length() > 0)
					output.delete(0, output.length());
				continue;
			}

			if (!match)
				continue;

			// next character in "number" must match exactly
			if (cd == '+' || cd == '#' || cd == '*' || cd >= '0' && cd <= '9') {
				if (k < ln && cn == cd) {
					output.append(cd);
					k++;
				} else {
					match = false;
				}
			}

			// next character in "number" must be a digit
			else if (cd == 'N') {
				if (k == ln) {
					if (isPartialOk)
						output.append(' ');
					else
						match = false;
				} else if (cn >= '0' && cn <= '9') {
					output.append(cn);
					k++;
				} else {
					match = false;
				}
			}

			// just add space to the output
			else if (cd == '_') {
				output.append(' ');
			}

			// just add the literal character to the output
			else if (cd == '(' || cd == ')' || cd == '-' || cd == '.') {
				output.append(cd);
			}
		}

		if (!match || k != ln) {
			// Didn't match anything... just rely on built-in phone number
			// formatter
			return PhoneNumberUtils.formatNumber(number);
		}

		// Remove non-numbers from the end of the string
		int end = output.length();

		int i = output.indexOf("( ");
		if (i > -1)
			end = i;

		while (end > 0
				&& (output.charAt(end - 1) == ' ' || output.charAt(end - 1) == '-')) {
			end--;
		}

		String formatted = output.substring(0, end);
		return formatted;
	}

The Android TI-8X Emulator lives on: Andie Graph

Or: why this app remains free. Free as in Free Beer, and Free as in ROM Free.

So I did talk to Peter Balyta, Director of Product Strategy from Texas Instruments, about the Andy-8X apps. The bottom line is that they want money — perhaps rightfully so, considering they wrote the 15-or-so year old code that’s embedded inside the app. The problem is, so do Google (30%), the author of AlmostTI (30%), and I. Splitting profit 4 ways (especially when it’s weighted towards those two), when I would have to do most of the maintenance, just didn’t work for me.

The alternative of course is to remove the embedded ROM code (to appease TI), and keep it free (to appease the author of AlmostTI and Google). This results in a much less user friendly app (IMHO) since you’re stuck downloading your own ROM. But hopefully I’ve reduced your burden as much as possible.

Meanwhile, enjoy this free app!

The Story of the TI-8X Emulators

Back on January 16, 2011, I released a series of apps into the wilds of the Android Market that were met with much fanfare, racking up almost 0.25M downloads in less than 2 months. These of course are my TI-83, TI-85, and TI-86 emulators.

The response for these apps has been way beyond what I expected. I’ve received many, many thank you’s from teachers, students, scientists, fanbois. The apps have some of the highest ratings on the entire market. They were consistently on the top downloads on my favorite non-official market site, AppBrain (until they got yanked–more on that in a moment).

These emulators were first released with the obvious names for such apps: “TI-83″, “TI-85″, and “TI-86″. Well, a few days later, on January 21st (one day after the birth of my daughter, incidentally), I got an email from TI about these:

…You are free to make applications that emulate Texas Instruments products and you are free to compare them to Texas Instruments products but it is our position that naming your products TI-XX, where XX is the Texas Instruments product model, is an infringement on Texas Instruments trademarks….

So I understood that to mean that they were cool with my emulators so long as I changed the names. Hence why they were renamed to a less obvious, “Andy-83″, “Andy-85″, and “Andy-86″. Not too big a deal. Not bad, a confirmation from TI that these emulators were A-OK in their book.

Well another bit of time goes by and I get another email, this one with not such good news:

…Distribution of TI copyrighted code without our written permission is an infringement of our intellectual property.  It was not until we had completed our technical review that became aware that your emulations included TI copyrighted code…

But not terrible news either, I thought. I could just get written permission to continue these apps. I immediately responded asking for written permission. I received no response except for another email a week later asking again for me to take the apps down. So I had to comply. This is why the apps are no longer on the market.

But they will be back, for sure, in some form. I’ve received news that TI is still considering my request to license these apps specifically. Cross your fingers for that to go through! If it doesn’t, though, I’m already at work on another series of emulators without the aforementioned copyrighted ROM code inside. These will work just the same but will require everybody to extract the ROM from his calculator; not the easiest thing to do. Here’s a writeup from my favorite TI calc site on how to do it.

Meanwhile, I’m still working on new features for these apps. I added a TI-82 emulator. I added a commonly requested feature: “Wake Lock – keep phone screen on until calculator goes to sleep”. I started working on a pro version that would allow you to supply your own roms (with support for any of the 4 models). So you can look forward to all of that in the near future.

What’s up with WP7?

I was recently asked why I moved to Android development from Windows Mobile.

Well, I feel like MS slapped us in the face when they announced WP7. No access to the SD card? No 3rd party apps? No UI replacements? Sure the UI is new, but it won’t take long before it feels outdated too. I not a big fan of the Metro UI look either. No compatibility with older apps, like all the ones I’ve written? No background threads? No copy/paste? You have to use Zune? (really?) The fact that you have to use iTunes is the #1 worst problem with the iPhone. So WM6.5 is dying and WM7 is completely different and completely closed (and completely like iPhone). Odd as it sounds, to me Android feels like the next (giant) step up from WM6.5, whereas WP7 is at best the next step up from iPhone.

As far as my existing WM apps go, none of them really translate usefully to WP7. GreenButton will be totally irrelevant on WP7, as will iContact and Avatar. iDialer might not be, if the Windows Marketplace allows it.

Antennagate

Certainly you’ve heard of “Antennagate” by now. It’s all the hype surrounding the fatal flaw in the iPhone 4′s genius new antenna design that causes it to lose quite a bit of signal strength when you hold the phone. I haven’t tried it myself, but I have tried holding a couple of my other phones in a way that would consistently make them lose signal strength.

Interesting fact #1: No matter what I do, I cannot get the iPhone 3GS to lose signal strenth. Even if I completely surround the phone with both of my hands.

Interesting fact #2: I can cause my HTC EVO 4G to lose signal strength consistently, by holding it in a way that I would never actually hold it. Holding it in this position also disables the camera. Good thing there’s a backup camera up front :)

Welcome!

If you’ve visited my site before, you may recognize a major overhaul. While I like to think that my site was clean and simple and easy enough to navigate before, I know that it was also a little lacking in the style department. I hope this new look adds some style and improves your ability to browse my apps.

But I also have some other reasons for this overhaul: I want a site that can let me post more than just 140 characters. You’ll notice my Tweets show up in here too, but occasionally I’d like to share a product review, or an interesting code snippet, the result of a weekend’s (or more) work. I want to post pictures, code, videos. I want an RSS feed, so those who are interested can follow along.

My day job is Product & Technical Manager of Mobile Products at Phone.com (a mouthful, right?). I’m lucky enough to be pursuing the dream I’ve had since before the mobile web existed (see my first mobile apps: Quad83 and ZCasino). So as part of my job, I get to play with lots of new toys all the time, and dream up new uses for them. I always love to talk about it too, so if you want to talk, don’t be shy!