I couldn't find much in the way of Android prototyping tools on the internet so I decided to create one of my own.This is for hand sketching ideas out. When printed on 8.5x11 it comes out almost the exact size of the G1 screen.
Why do we think if it's not difficult and complex then it's not worth using?
T-Mobile's only Android device, the G1, isn't as open as you would think. The device lacks root access and the bootloader requires a signed image. Older versions of the OS have had a successful jailbreak but the most recent (R30) over the air firmware upload "fixed" that.
I jumped on the G1 bandwagon the day after it was announced hoping that it would live up to the openness Android was claiming. To be fair, the SDK does allow access to quite a bit more than the iPhone's SDK does which makes for some interesting applications not do able on the iPhone (for now). But the Google/T-Mobile team has stopped a bit short when it comes to moving from one Android device to another. There's no desktop client nor is there a backup/restore client! Think about that for a moment. When the time comes that you have the option to move to another Android device or, as in my case, have to replace your current one you're out of luck.
I searched the internet and even posted in a few google read forums (groups.google.com/groups/android-developers, forums.t-mobile.com) about how to move from one to the other. I read about the jailbreaking < R30 and the R30 hacked image if you already were jailbroken. I was told that it's T-Mobile's fault and to stop complaining. I was even told by one person that they clear their phone all the time for app testing and it only takes about 10-15 minutes and isn't a big deal. That person obviously isn't really using their phone.
T-Mobile customer support isn't much better either. They say you just have to download the applications again from the market and accept the data loss or they'll tell you about the jailbreak and how R30 shut it down and it's "impossible" to hack this new version. When you try to tell them that you want T-Mobile to provide root access or unlock the boot loader they tell you that Google writes the code and HTC makes the phone. They have nothing to do with it. This is a lack of understanding on the support staff's part. Google writes the base code, but it's modified for T-Mobile and only runs as a signed image.
Basically it seems that what's happening is that Google released some software prematurely as usual with their code but this is a very different case than the web were only the Google devoted will pick up the software before it's ready for prime time. T-Mobile pushed out the G1 as a iPhone replacement when it is not because of the build quality, the hardware itself and the premature OS. Now that they actually have real users with real problems that should have been caught long before in acceptance testing, they just want to ignore them. And they'll be able to because most people using the G1 won't know any better. There's always the Google apologists (and in some cases the Android devs themselves) that will say it's not their problem. There's no way to actually get in contact with someone who actually knows something about this level of detail about the G1 at T-Mobile. And finally, we already paid and signed a contract and are well past the 14 day return period. So the only way out is to pay more money to T-Mobile.
For anyone out there looking to develop on Android and the G1, PLEASE, PLEASE just spend the extra money on the Google Dev Phone 1 (http://code.google.com/android/dev-devices.html).
To me this is what the G1 should have been. This is what Android was to represent.
There have been many, many posts through out the internet explaining why Firebug is the greatest thing ever for the web developer from the CSS editor to the AJAX transmission viewer to the javascript debugger. I'm going to throw one more thing in; javascript REPL.
REPL stands for Read, Evaluate, Print, Loop for those that don't know and basically means it's an interactive shell into your program. Most of us know about the console in Firebug but how many know about the power it gives? When you open Firebug the console tab is selected by default. You may know this as the place those console.log() messages go. At the bottom is a blank line denoted by ">>>", this is the interactive part. You can execute a line of javascript here. If you click the circle with the up arrow on the right you open the multiline console. I recommend this as the way to go. You can write multiple lines, such as functions, and execute with ctrl-enter or command-enter.
Anyway, back to that REPL. The console lets you interact with any loaded javascript on the page. You can change global variables, call functions, pretty much anything javascripty. This is where the power comes in. You can define functions meaning you can redefine functions! And it'll work when some element or function on the page calls it.
Imagine for a moment that your trying to create a new function or debug a function on your production server where you have to interact with the real data. You can't just change the code, check it in, build and deploy each time due to various issues like time and the client noticing the site going up and down. What you can do, and what I had to do recently, is open the console, paste in the fixes to the definition of the function, evaluate it, and then go about interacting with the page. It becomes a much faster solution that has a couple of benefits.
If you go about writing your javascript code with the console in mind there are some great uses for it.
Edit: Thanks to yincrash for pointing out that they changed their namespace on this object to TMO.ABPORTAL.
My friend Candice got a 1st Gen iPhone on the cheap and needed to get her numbers from T-Mobile's new online Address Manager (TAB). It does syncing to and from a regular T-Mobile phone but the iPhone isn't a regular T-Mobile Phone. The app is new and they have a note about it not syncing changes made on the website to the phone yet and either by design or evil plotting there was no way to export the contacts.
My vocation to the rescue! They were using the prototype.js library to run the app and after some digging around I found the data store.TMO.ABPORTAL.ABIHM.ContactManager is the object that manages the contacts' actions and the _datas property is an array of contact javascript objects. So in the firebug console I wrote some code to get the contacts and wrote a csv file to an empty div. I then took that div into Wordpad to get the lines to break correctly on Windows and did an import into Windows Address Book. The rest is history!
Here's the code I used:
var data = ["firstname,lastname,name,homeMobile,homePhone1,homePhone2,workMobile,workPhone1,workPhone2"];
TMO.ABPORTAL.ABIHM.contactManager._datas.each(function(person) {
var a = [];
a.push(person.firstname);
a.push(person.lastname);
a.push(person.name);
a.push(person.homeMobile);
a.push(person.homePhone1);
a.push(person.homePhone2);
a.push(person.workMobile);
a.push(person.workPhone1);
a.push(person.workPhone2);
data.push(a.join(","));
});
$('L_footer_pane').update(data.join('\r\n'));
actionMapper = DefaultActionMapper.new
dispatcher.configurationManager.configuration.container.inject(actionMapper)
require 'java'
import 'org.apache.struts2.dispatcher.Dispatcher'
import 'org.apache.struts2.dispatcher.FilterDispatcher'
import 'org.apache.struts2.dispatcher.mapper.DefaultActionMapper'
import 'org.springframework.mock.web.MockServletContext'
import 'org.springframework.mock.web.MockFilterConfig'
import 'org.springframework.mock.web.MockHttpServletRequest'
import 'org.springframework.mock.web.MockHttpServletResponse'
filterConfig = MockFilterConfig.new
servletContext = MockServletContext.new
dispatcher = Dispatcher.new(servletContext, {})
dispatcher.init
Dispatcher.instance = dispatcher
actionMapper = DefaultActionMapper.new
dispatcher.configurationManager.configuration.container.inject(actionMapper)
request = MockHttpServletRequest.new(servletContext, 'GET', '/example/other.action');
response = MockHttpServletResponse.new;
actionMapping = actionMapper.getMapping(request,dispatcher.configurationManager)
puts "Name: #{actionMapping.name}"
puts "Namespace: #{actionMapping.namespace}"
puts "Method: #{actionMapping.method}"
puts "Result: #{actionMapping.result}"