gabehabe Cool blog, bro.

30Oct/090

Arnold Schwarzenegger WIN!

I lol’d.

Arnold Schwazenegger "Fuck You"

To the Members of the California State Assembly:

I am returning Assembly Bill 1176 without my signature.

For some time now I have lamented the fact that major issues are overlooked while many
unnecessary bills come to me for consideration. Water reform, prison reform, and health
care are major issues my Administration has brought to the table, but the Legislature just
kicks the can down the alley.

Yet another legislative year has come and gone without the major reforms Californians
overwhelmingly deserve. In light of this, and after careful consideration, I believe it is
unnecessary to sign this measure at this time.

Sincerely,
Arnold Schwarzenegger

(Via TechCrunch)

Filed under: General No Comments
26Oct/0943

Post a comment – Win a Google Wave invite!

Google Wave is awesome. And as of today, I have some invites to dish out. So here’s a contest to win one.

Simple stuff really. Just post a comment. It asks for your email address, enter the email address you want the invite to go to. Subscribe to this post, and I’ll announce the winners in a comment on Friday 13th November, 2009.

One entry per email address. 3 up for grabs. Get commenting. :)

24Oct/090

Uncharted 2: Pure awesome.

Since this is more a tech blog than a game blog, I’m not going to go really in-depth about the game. If you want loads of in-depth and galleries, check out joystiq, a great blog dedicated to gaming.

What I will say, is that this game is insanely good. I’d even go so far as to say it was better than the first, something rarely achieved by a sequel, especially a sequel to something so awesome as Uncharted.

The game overall is actually fairly short. I managed to complete the game in around 6-7 hours gameplay. Though it has a great replay factor, and I barely found any of the 100 hidden treasures. :(

The scenery in-game really makes up for the short gameplay, there really are some breathtaking visuals.

I think the thing that makes Uncharted 2 so good is the fact that it’s much more real than other games. Characters tend to react how you’d expect them to react to demon sasquatches coming charging at them, as opposed to running in, guns blazing.

And yes, Nate even seems to find the time to draw a picture of them and explain that they’re scarier than Sully’s moustache and a slippery naked guy in his notebook.



22Oct/091

Monarch Recruitment: lolwut?

Got an email from Monarch Recruitment today, epic fail from a guy named Luke Osborne. (Yes, I’m hoping to get his name tied to the word “fail” in google)

First up, a bit of background:
About a year ago, I was looking for a job in IT. I tried everything, even putting my CV on some recruitment sites: bad idea.

I received a hell of a lot of spam, and have been added to agency spammailing lists. But generally, they will send them out to just one person at a time.

Not Monarch. They’ve outdone themselves as a fail agency this time.

Received an email which was addressed to 810 people. I’d also like to point out that I don’t recall getting my name changed to FIRST_NAME by Deed Poll.

This’ll do a damage to the vscroll on this site for a while, but it’s so worth it.

All email addresses have been changed to x@domain.com for privacy. (regex ftw!)

Original email:

x@gmail.com
Received: by 10.216.59.212 with SMTP id s62cs200799wec;
Thu, 22 Oct 2009 10:14:34 -0700 (PDT)
Received: by 10.210.7.23 with SMTP id 23mr10862003ebg.27.1256231673349;
Thu, 22 Oct 2009 10:14:33 -0700 (PDT)
x@monarchrecruitment.co.uk>
Received: from service37.mimecast.com (service37.mimecast.com [213.235.63.87])
by mx.google.com with SMTP id 28si6642383ewy.88.2009.10.22.10.14.32;
Thu, 22 Oct 2009 10:14:33 -0700 (PDT)
x@monarchrecruitment.co.uk) client-ip=213.235.63.87;
x@monarchrecruitment.co.uk
Received: from bhammail-srv01.monarch.local (78-33-40-66.static.enta.net [78.33.40.66])
by service37.mimecast.com;
Thu, 22 Oct 2009 18:14:21 +0100
X-MimeOLE: Produced By Microsoft Exchange V6.5
Content-class: urn:content-classes:message
MIME-Version: 1.0
Subject: Senior .Net developer role
Date: Thu, 22 Oct 2009 18:13:34 +0100
x@bhammail-srv01.monarch.local>
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
Thread-Topic: Senior .Net developer role
thread-index: AcpTOv9pBHq7tlj0SgOJGBOSWSvH+A==
x@monarchrecruitment.co.uk>
x@BTInternet.com>,
<x@igsoftwaresolutions.co.uk>,
<x@militantsouth.com>,
<x@btinternet.com>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@MSN.COM>,
<x@computerscienceltd.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@fastmail.fm>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@GoogleMail.com>,
<x@gmail.com>,
<x@dacservices.co.uk>,
<x@btinternet.com>,
<x@yahoo.com>,
<x@procensol.co.uk>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@yahoo.co.in>,
<x@blueyonder.co.uk>,
<x@ICTConsultant.co.uk>,
<x@yahoo.co.in>,
<x@hotmail.com>,
<x@jdw-techmanagement.co.uk>,
<x@softchrome.co.uk>,
<x@yahoo.com>,
<x@hotmail.co.uk>,
<x@btinternet.com>,
<x@blueyonder.co.uk>,
<x@swproj.com>,
<x@hotmail.com>,
<x@tiscali.co.uk>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@swproj.com>,
<x@symtex.co.uk>,
<x@calidra.co.uk>,
<x@gmail.com>,
<x@freenet.co.uk>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@gayeshan.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@kitcat.f9.co.uk>,
<x@qpltd.com>,
<x@oomagic.com>,
<x@frequency7.co.uk>,
<x@hotmail.com>,
<x@sendo.co.uk>,
<x@btinternet.com>,
<x@blueyonder.co.uk>,
<x@btinternet.com>,
<x@hotmail.com>,
<x@stuartmassey.com>,
<x@tinyworld.co.uk>,
<x@authorsoftware.com>,
<x@hotmail.com>,
<x@btinternet.com>,
<x@vaudin.net>,
<x@mwbcomputing.co.uk>,
<x@yahoo.com>,
<x@blueyonder.co.uk>,
<x@cometx.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@gavinsullivan.net>,
<x@vaudin.net>,
<x@gmail.com>,
<x@radas.co.uk>,
<x@yahoo.com>,
<x@bulldoghome.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@gmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@mvps.org>,
<x@infotech.com.pk>,
<x@twoswans.f9.co.uk>,
<x@bcs.org>,
<x@yahoo.co.uk>,
<x@pwcsoftware.com>,
<x@retcorp.net>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@xansa.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@btinternet.com>,
<x@yahoo.co.uk>,
<x@hotmail.co.uk>,
<x@gmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@sitescraper.co.uk>,
<x@USA.NET>,
<x@googlemail.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@wendtel.co.uk>,
<x@hotmail.co.uk>,
<x@jethwas.com>,
<x@live.co.uk>,
<x@btinternet.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@toucansurf.com>,
<x@blueyonder.co.uk>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@aol.com>,
<x@yahoo.co.uk>,
<x@yahoo.co.uk>,
<x@virgin.net>,
<x@hancock14.freeserve.co.uk>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@centricore.co.uk>,
<x@wavecrestsoftware.co.uk>,
<x@btinternet.com>,
<x@phoenix3.co.uk>,
<x@ajmerphull.com>,
<x@microspherelimited.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@webcite.co.uk>,
<x@auglobal.com>,
<x@woodstown.co.uk>,
<x@talk21.com>,
<x@gmail.com>,
<x@blueyonder.co.uk>,
<x@bt.com>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@rediffmail.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@tonyhales.co.uk>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@davejsmith.co.uk>,
<x@bcs.org.uk>,
<x@gmail.com>,
<x@lineone.net>,
<x@gmail.com>,
<x@davefield.org.uk>,
<x@gmail.com>,
<x@warriorsoftware.co.uk>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@rediffmail.com>,
<x@yahoo.com>,
<x@rediffmail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@googlemail.com>,
<x@yahoo.co.uk>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@yahoo.co.in>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@gmail.com>,
<x@yahoo.co.in>,
<x@3rdPlanetMedia.co.uk>,
<x@gmail.com>,
<x@gold-code.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@3rdplanetmedia.co.uk>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@yahoo.co.uk>,
<x@yahoo.com>,
<x@quickweb.co.uk>,
<x@yahoo.com>,
<x@googlemail.com>,
<x@hotmail.co.uk>,
<x@yahoo.co.uk>,
<x@yahoo.co.uk>,
<x@yahoo.com>,
<x@gmail.com>,
<x@googlemail.com>,
<x@cwassociates.fsbusiness.co.uk>,
<x@hotmail.co.uk>,
<x@googlemail.com>,
<x@googlemail.com>,
<x@googlemail.com>,
<x@btinternet.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@andrewbibby.info>,
<x@yahoo.co.uk>,
<x@wanjeet.freeserve.co.uk>,
<x@johnson-ashby.freeserve.co.uk>,
<x@btconnect.com>,
<x@hotmail.com>,
<x@sky.com>,
<x@matrixss.f9.co.uk>,
<x@nurvsoftware.co.uk>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@yahoo.co.uk>,
<x@sheerclass.net>,
<x@hotmail.com>,
<x@fallingdusk.f2s.com>,
<x@blueyonder.co.uk>,
<x@btinternet.com>,
<x@kidd.org.uk>,
<x@gothictech.co.uk>,
<x@xcoda.com>,
<x@psmason.com>,
<x@worcestershire.gov.uk>,
<x@hotmail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@googlemail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@csharp-architect.com>,
<x@lineone.net>,
<x@virgin.net>,
<x@talk21.com>,
<x@nuttwood.co.uk>,
<x@gmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@Hotmail.Com>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@dna-solutions.com>,
<x@liquidjelly.co.uk>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
“x@monarchrecruitment.co.uk>,
<x@hotmail.com>,
<x@lineone.net>,
<x@creationof.net>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@fastmail.fm>,
<x@hotmail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@ukonline.co.uk>,
<x@yahoo.co.in>,
<x@robparker.me.uk>,
<x@yahoo.co.uk>,
<x@btinternet.com>,
<x@yahoo.co.uk>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@bcs.org.uk>,
<x@rediffmail.com>,
<x@gmail.com>,
<x@talk21.com>,
<x@fastmail.fm>,
<x@papermill-farm.com>,
<x@blueyonder.co.uk>,
<x@msn.com>,
<x@guoping.net>,
<x@blueyonder.co.uk>,
<x@evesham.com>,
<x@GMAIL.COM>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@ntlworld.com>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@kibble.me.uk>,
<x@yasar.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@dsl.pipex.com>,
<x@ntlworld.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@btinternet.com>,
<x@watkins.eclipse.co.uk>,
<x@blueyonder.co.uk>,
<x@yahoo.co.uk>,
<x@sympatico.ca>,
<x@googlemail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@yahoo.co.uk>,
<x@blueyonder.co.uk>,
<x@tiscali.co.uk>,
<x@360software.co.uk>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@exservices.co.uk>,
<x@ntlworld.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@sheerclass.net>,
<x@ntlworld.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@googlemail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@googlemail.com>,
<x@yahoo.com>,
<x@hotmail.co.uk>,
<x@theheads.demon.co.uk>,
<x@gmail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@btinternet.com>,
<x@yahoo.com>,
<x@btinternet.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@rdeeson.com>,
<x@btinternet.com>,
<x@hotmail.com>,
<x@antonyclark.net>,
<x@mrsajidmahmood.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@runbox.com>,
<x@msn.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@coolestbananas.co.uk>,
<x@Blueyonder.co.uk>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@dustykeyboard.co.uk>,
<x@yahoo.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@live.co.uk>,
<x@hotmail.co.uk>,
<x@yahoo.co.uk>,
<x@molloy1.plus.com>,
<x@yahoo.com>,
<x@googlemail.com>,
<x@gmail.com>,
<x@yahoo.co.in>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@roberthancock.co.uk>,
<x@gmail.com>,
<x@imnotplayinganymore.co.uk>,
<x@hotmail.co.uk>,
<x@gmail.com>,
<x@tiscali.co.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@blueyonder.co.uk>,
<x@sjllewellyn.com>,
<x@yahoo.co.in>,
<x@gmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@hotmail.co.uk>,
<x@googlemail.com>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@live.co.uk>,
<x@hotmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@btinternet.com>,
<x@yahoo.com>,
<x@aol.com>,
<x@sheerclass.net>,
<x@hotmail.co.uk>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@rediffmail.com>,
<x@tesco.net>,
<x@gmail.com>,
<x@btconnect.com>,
<x@thebigbluehouse.co.uk>,
<x@iname.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@ThreeLionsConsulting.com>,
<x@fsmail.net>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@blueyonder.co.uk>,
<x@gmail.com>,
<x@gridbag.co.uk>,
<x@gmail.com>,
<x@hotmail.com>,
<x@googlemail.com>,
<x@gmail.com>,
<x@ishware.co.uk>,
<x@zoom.co.uk>,
<x@think-uk.biz>,
<x@gofree.co.uk>,
<x@mcgovern.co.uk>,
<x@usa.net>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@sky.com>,
<x@bigfoot.com>,
<x@esdaniel.com>,
<x@hotmail.com>,
<x@adlz.co.uk>,
<x@googlemail.com>,
<x@gecko.org.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@northfieldbham.freeserve.co.uk>,
<x@Blueyonder.co.uk>,
<x@hotmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@dialstart.net>,
<x@aol.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@f2s.com>,
<x@mail.com>,
<x@hotmail.com>,
<x@homesyte.co.uk>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@yahoo.co.uk>,
<x@register-software.net>,
<x@blueyonder.co.uk>,
<x@dsherman.fsnet.co.uk>,
<x@hotmail.com>,
<x@uwclub.net>,
<x@blueyonder.co.uk>,
<x@blueyonder.co.uk>,
<x@yahoo.co.uk>,
<x@btinternet.com>,
<x@makeitdynamic.com>,
<x@hotmail.com>,
<x@HOTMAIL.COM>,
<x@pilkington.com>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@johnstone79.demon.co.uk>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@JAKS-technology.co.uk>,
<x@yahoo.com>,
<x@stmail.staffs.ac.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@yahoo.co.uk>,
<x@blueyonder.co.uk>,
<x@yahoo.co.uk>,
<x@btinternet.com>,
<x@ukonline.co.uk>,
<x@hotmail.com>,
<x@aol.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@realworldbiker.com>,
<x@yahoo.co.uk>,
<x@yahoo.com>,
<x@gmail.com>,
<x@grahamabbiss.f2s.com>,
<x@ntlworld.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@blueyonder.co.uk>,
<x@zeeb-consulting.co.uk>,
<x@hotmail.com>,
<x@lloydspharmacy.co.uk>,
<x@dan-goodwin.co.uk>,
<x@huwbristow.co.uk>,
<x@rosandpete.co.uk>,
<x@neilbarnwell.co.uk>,
<x@londonmet.ac.uk>,
<x@bryth.com>,
<x@hotmail.co.uk>,
<x@austin1984.freeserve.co.uk>,
<x@hotmail.com>,
<x@wlv.ac.uk>,
<x@talk21.com>,
<x@aol.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@aim.com>,
<x@btinternet.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@yahoo.com>,
<x@hotmail.co.uk>,
<x@tiscali.co.uk>,
<x@blueyonder.co.uk>,
<x@googlemail.com>,
<x@yahoo.co.uk>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@hotmail.co.uk>,
<x@gavinlilley.com>,
<x@yahoo.com>,
<x@dreamz.worldonline.co.uk>,
<x@technologist.com>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@googlemail.com>,
<x@gmail.com>,
<x@googlemail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@googlemail.com>,
<x@oxborrow.biz>,
<x@blueyonder.co.uk>,
<x@rajvansh.co.uk>,
<x@hotmail.co.uk>,
<x@extreme-europe.com>,
<x@hotmail.com>,
<x@tiscali.co.uk>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@yahoo.co.uk>,
<x@mhcs.org.uk>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@aston.ac.uk>,
<x@hotmail.com>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@live.co.uk>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@wormpurple.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@jonathanandmary.co.uk>,
<x@blueyonder.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@alexjoyce.com>,
<x@hotmail.co.uk>,
<x@jamesdodd.com>,
<x@mcgraynor.freeserve.co.uk>,
<x@gmail.com>,
<x@hotmail.com>,
<x@hotmmail.com>,
<x@yahoo.com>,
<x@triolink.co.uk>,
<x@abs.me.uk>,
<x@blueyonder.co.uk>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@hotmail.co.uk>,
<x@costatek.com>,
<x@sky.com>,
<x@hairthieves.com>,
<x@hotmail.com>,
<x@ntlworld.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@yahoo.co.in>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.co.in>,
<x@googlemail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@googlemail.com>,
<x@targettesting.co.uk>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@student.staffs.ac.uk>,
<x@tiscali.co.uk>,
<x@hotmail.co.uk>,
<x@googlemail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@googlemail.com>,
<x@hotmail.com>,
<x@acfdesign.com>,
<x@yahoo.com>,
<x@mslancashire.plus.com>,
<x@googlemail.com>,
<x@btinternet.com>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@hastilow.com>,
<x@blueyonder.co.uk>,
<x@hotmail.co.uk>,
<x@hotmail.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@f2s.com>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@HOTMAIL.CO.UK>,
<x@Yahoo.co.uk>,
<x@hotmail.com>,
<x@YAHOO.COM>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@googlemail.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@gmail.com>,
<x@sskosborn.co.uk>,
<x@blueyonder.co.uk>,
<x@gmail.com>,
<x@yahoo.co.in>,
<x@hotmail.com>,
<x@fastermail.com>,
<x@gmail.com>,
<x@goladderless.com>,
<x@wedontbyte.com>,
<x@tiscali.co.uk>,
<x@yahoo.com>,
<x@yahoo.com>,
<x@gmail.com>,
<x@googlemail.com>,
<x@hotmail.com>,
<x@yahoo.co.uk>,
<x@hotmail.com>,
<x@hotmail.com>,
<x@poyner.me.uk>,
<x@yahoo.co.uk>,
<x@gmail.com>,
<x@blueyonder.co.uk>,
<x@gmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@msn.com>,
<x@ryanaldred.co.uk>,
<x@gmail.com>,
<x@hotmail.com>,
<x@blueyonder.co.uk>,
<x@gmail.com>,
<x@designdotworks.co.uk>,
<x@hotmail.com>,
<x@googlemail.com>,
<x@gmail.com>,
<x@hotmail.com>,
<x@gmail.com>,
<x@gmail.com>,
<x@yahoo.com>,
<x@hotmail.com>,
<x@rediffmail.com>,
<x@dpfoc.com>,
<x@gmail.com>,
<x@hotmail.co.uk>,
<x@yahoo.co.uk>,
<x@googlemail.com>,
<x@hotmail.com>,
<x@yahoo.com>,
<x@hotmail.co.uk>,
<x@hotmail.com>
X-MC-Unique: 109102218142100201
Content-Type: multipart/mixed;
boundary=”—-_=_NextPart_001_01CA533A.FF69C750″

This is a multi-part message in MIME format.

——_=_NextPart_001_01CA533A.FF69C750
Content-Type: multipart/related;
type=”multipart/alternative”;
boundary=”—-_=_NextPart_002_01CA533A.FF69C750″

——_=_NextPart_002_01CA533A.FF69C750
Content-Type: multipart/alternative;
boundary=”—-_=_NextPart_003_01CA533A.FF69C750″

——_=_NextPart_003_01CA533A.FF69C750
Content-Type: text/plain; charset=WINDOWS-1252
Content-Transfer-Encoding: quoted-printable

Dear FIRST_NAME,
=20
You have previously registered your CV with monarch as looking for role. An=
opportunity has arisen for an experienced senior .Net developer based in t=
he West Midlands, requiring extensive .Net, Vb.net, Asp.net and SQL experie=
nce. Should this role be of interest to you, and should you meet the requir=
ements and have the necessary experience, please do not hesitate to send me=
an updated CV, and state your interest in applying for this role.
=20
I look forward to hearing from you
=20
Kindest Regards=20
=20
Luke
=20
Luke Osborne
Recruitment Consultant
Monarch Recruitment Ltd
=20
Direct Dial 0121 237 3233
x@monarchrecruitment.co.uk x@monarchrecruitment.co.uk>=20
=20
=20
=20
=20
“Established in 1992 and employing 140+ consultants, we provide a fast recr=
uitment service tailored across the SME & corporate market place supplying =
permanent and contract I.T. professionals”
=20
Monarch Recruitment is an ISO9001:2000 certified company
=20
——_=_NextPart_003_01CA533A.FF69C750
Content-Type: text/html; charset=WINDOWS-1252
Content-Transfer-Encoding: quoted-printable







=20

Dear =3D”FIRST_NAME”>FIRST_NAME,
 
You have previously re=
gistered your CV with monarch as looking for role. An opportunity has arise=
n for an experienced senior .Net developer based in the West Midlands, requ=
iring extensive .Net, Vb.net, Asp.net and SQL experience. Should this role =
be of interest to you, and should you meet the requirements and have the ne=
cessary experience, please do not hesitate to send me an updated CV, and st=
ate your interest in applying for this role.
 
I look forward to hear=
ing from you
 
Kindest Regards >
 
Luke
 
ibri” size=3D3 color=3D”black”>Luke Osborne
i” size=3D3 color=3D”black”>Recruitment Consultant
i” size=3D3 color=3D”black”>Monarch Recruitment Ltd
 
i” size=3D3 color=3D”black”>Direct Dial      =
            &nb=
sp;     0121 237 3233
i” size=3D3 color=3D”black”>Email       =
            &nb=
sp;            =
:x@monarchrecru=
itment.co.uk
 
 
i” size=3D3 color=3D”black”>   th:2.07in;height:1.02in;”/>        =
      eight:1.02in;”/>
 
i” size=3D3 color=3D”gray”>"Established in 1992 and employing 140+ cons=
ultants, we provide a fast recruitment service tailored across the SME &amp=
; corporate market place supplying permanent and contract  I.T. profes=
sionals"
 
i” size=3D3 color=3D”gray”>Monarch Recruitment is an ISO9001:2000 certified=
company
 





tyle=3D”color: rgb(102, 102, 102);”>This message is intended solely for the=
use of the individual or organisation to whom it is addressed. It may cont=
ain privileged or confidential information.=20
If you have received this message in error, please notify the originator im=
mediately. If you are not the intended recipient, you should not use, copy,=
alter, or disclose the contents of this message.
All information or opinions expressed in this message and/or any attachment=
s are those of the author and are not necessarily those of Monarch Recruitm=
ent Ltd or its affiliates.=20
Monarch Recruitment Ltd accepts no responsibility for loss or damage arisin=
g from its use, including damage from virus.
If you wish to be removed from the database or feel this email has no busin=
ess with yourself, then please click on the following removal link to be re=
moved from our database. lick?account=3DC18A8&code=3Dddea0d311ecf4d3b78c6ee9298e82a0d”> =3D”font-family: Arial,Helvetica,sans-serif;” size=3D”2″>remove
<=
/font>

tyle=3D”color: rgb(102, 102, 102);”>Monarch Recruitment Ltd. 8th Floor, 1 M=
artineau Place, 44-80 Corporation Street,Birmingham, B2 4UW. Company Reg No=
: 2774106, VAT No. 806 6627 20.
=20




18Oct/090

Google Wave!

ZOMG I GOT MY INVITE TODAY!

I actually got it last night at about 3am when I went to bed, so I decided to wait until today to play with it. And… I luffs it!

In fact, you’ve probably noticed the widget on the right, which shows a wave that I set up just for my blog.

In case you can’t see it yet (you have to have a wave account, though the wave is public so I don’t need to add you for you to see it), here’s a screenshot of how it will look when you get on. (Note I said when, not if. There’s a bloody huge hype about this, I expect a hell of a lot of people, especially the type that read all my ramblings here, to have an account eventually!) ;)

google wave wordpress widget

In case you’re wondering how I did it, I added “embeddy@appspot.com” to the wave, and it gave me the code to embed the wave. Simple as that. :)

Now I’m just waiting to get the ability to send out invites. Can’t do it yet, but apparently you only get 8 and I’ve promised most of them to friends already, so no giveaways here I’m afraid!

Quick screenshot, nothing in-depth since I’m too lazy to do a massive writeup. :\

gabehabe google wave

If you have google wave, this is the wave on the right, just a bit bigger:




16Oct/090

Why is there a dead Pakistani on my couch?

…well? I certainly didn’t put it there.

Actually, I’ve heard it’s from Lost. Which is a terrible show.

I just found this amusing and thought I’d share.

Tagged as: , No Comments
16Oct/091

Office space to rent in Burntwood

what is this i dont even
office space to rent in burntwood

I’ve never posted anything like that here. If it was AmmNet, at work, I might understand since we do have office space to rent. But how has that reached my site? O.o

Though I realise that I’m now going to have a permalink with this text in, header tags and image alts, I will understand if I get those hits in the future.

Tagged as: , 1 Comment
10Oct/090

Developing for Android, Part V

Publishing your apps

No code in this tutorial… and this is actually the last in the series. But never fear! I’ll be writing more tutorials, I’ve simply written these 5 to get you familiarised with android. Hopefully, you’re feeling quite confident on some of the aspects now, and you could well be on your way to developing the next killer app!

With that said, I’m going to explain how you can publish your app. It’s a simple process, but you also have to sign your apk before you can publish it to the market.

First off, we need to create a keystore. To do this, you’ll need the JDK installed. Open up a command prompt, and change to whereever you want to save the keystore. Then, type the following:
keytool -genkey -v -keystore mykeystore.keystore -alias my_alias -keyalg RSA -validity 10000
NOTES:
- Replace mykeystore.keystore with whatever_you_want_to_call_it.keystore
- Replace my_alias with whatever alias you want to use (example, android)

Also, if you get this error:
'keytool' is not recognised as an internal or external command, operable program or batch file.
You may want to set the PATH variable. You can do it in the computer properties, but since this isn’t exactly a windows tutorial, I won’t go into that much detail. Instead, let’s do this:
PATH="C:\Program Files\Java\jdk1.6.0_14\bin"
then try the first command again.
NOTE: Replace the path with the path of wherever you installed Java. (Typically you’ll find it in C:\Program Files\Java\jdk%.%.%_%%\bin)
ANOTHER NOTE: This is of course a windows path. Depending on your operating system, this may vary.

After executing the keytool command, it will ask you for various details. Simply enter the values, and it will create your keystore. Make sure you take note of your alias and password, it will ask you for it every time you come to sign an app!

For reference, the questions it will ask are:

  • Enter keystore password:
  • Re-enter new password:
  • What is your first and last name?
  • What is the name of your organisational unit?
  • What is the name of your organisation?
  • What is the name of your City or Locality?
  • What is the name of your State or Province?
  • What is the two-letter country code for this unit?

You now have your keystore. When you want to sign an apk, you will need to use the following command:
jarsigner -verbose -keystore "/path/to/mykeystore.keystore" "/path/to/myapk.apk" my_alias
Enter your password, and you will see some output similar to this:

adding: META-INF/ALIAS_NA.SF
adding: META-INF/ALIAS_NA.RSA
signing: res/drawable/icon.png
signing: res/layout/main.xml
signing: AndroidManifest.xml
signing: resources.arsc
signing: classes.dex

Your apk file is now signed! (Note that you need to sign it every time before uploading, since building will reset it)

Publishing your app

The next step is of course publishing your newly signed apk file to the android market. Simply navigate your web browser to the market home and follow the steps to register as a developer. If you want to register to sell your apps, you will also need to go through an additional process to become a “registered seller”.

Once you’ve registered and logged in, you’ll reach the page which displays all your registered apps. Of course, if you’re following this tutorial, you probably don’t yet have any, so you won’t have a list of apps to see. :)
NOTE: This page uses a hell of a lot of javascript. Make sure it’s turned on.

When you’re ready, click on “Upload Application”. You will then be presented with a form where you can upload the apk and a maximum of two screenshots, a promotional graphic, and fill in various details such as the title, description and price.

As soon as you click publish, your application will be on the market — there’s no approval system like the iPhone’s app store, so as soon as you search in the market, you should see your app.

You are now officially a dev. Make me proud. :’)

8Oct/090

Developing for Android, Part IV

Databases and Menus

Two for the price of one in this tutorial, actually. We’re going to learn about SQLite databases and menus. I’m hoping you’ll at least be slightly familiar with databases already, though SQLite is really quite simple. You can pick up the basics, of which we’ll be using in this tutorial, at the following links:

It may look a little intimidating, but once you get to grips with it, it’s actually quite close to English. :)

Let’s get to it. As usual, we’re creating a package:

package dreamincode.tutorials.dic_tut4;

…and we’ll import the usual suspects.

import android.app.Activity;
import android.os.Bundle;

Now there’s quite a lot that we’re going to import that hasn’t already been covered, but do not panic. I’ll explain it all as we go along, and it’s honestly nothing to worry about. First up, a ListView. This is just another widget, and it’s… well, it’s a list. :)

import android.widget.ListView;

Next, we’ll import the stuff related to the menu. We’ll be using a Menu, and a couple of MenuItems.

import android.view.Menu;
import android.view.MenuItem;

The next bits are related to the database. The first is self-explanatory, it’s a database. The second is a Cursor. A cursor is a way we can store temporary results from a table in memory. (We select stuff into it, explained a little later… keep reading!)

import android.database.sqlite.SQLiteDatabase;
import android.database.Cursor;

And finally, we’re going to import an ArrayList to add our results into, and an ArrayAdapter to basically plug our ArrayList into the list. Again, this will be explained later, at this point all we really have is an overview.

import android.widget.ArrayAdapter;
import java.util.ArrayList;

On to the main part of the code, now. :) First off, we’ll open up our class and add a few variables. We’ll have a ListView, an SQLiteDatabase, and a few ints for the IDs of our menu items.

public class dic_tut4 extends Activity {
	ListView list;
	SQLiteDatabase db;
 
	private static final int MENU_ADD = Menu.FIRST;
	private static final int MENU_QUIT = Menu.FIRST + 1;

You’ll see why we use these a little later. :)

This is where it gets a little different. I’ll give you one method at a time, and talk through each line.

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        this.list = new ListView(this);
        setContentView(this.list);
 
    	this.db = this.openOrCreateDatabase("dic_tut4", MODE_PRIVATE, null);
    	this.db.execSQL("CREATE TABLE IF NOT EXISTS table_of_dics(value REAL)");
    	this.update_list();
    }

So, the start is nothing new. Nothing to worry about here. Then we initialise the list. Nothing new here, either. It’s exactly the same as when we created a dynamic layout in part 3. Then we do some new things with our database. First we use openOrCreateDatabase("dic_tut4", MODE_PRIVATE, null);
– this creates a database if it doesn’t exist, or opens it if it does.
– parameter 1 is the name of the database we’re looking to create/open.
– parameter 2 is the mode, doesn’t require much explanation at this point. (Don’t want to give you an information overload) :)
– parameter 3, you don’t even need to worry about. If you’re interested, do some digging on CursorFactory.

Then another new line: this.db.execSQL("CREATE TABLE IF NOT EXISTS table_of_dics(value REAL)");
– this will create a table if it doesn’t already exist
– it will add a single field into the table, called value. It is of type REAL, which is just like a double in Java.

And finally, this.update_list(); … this is actually a custom method we’ll be writing to query the database and populate the list. More info later, for now let’s focus on the menu.

Creating a menu

Simple stuff actually. We use onCreateOptionsMenu(), which is called when the user hits the menu button.

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) {
    	menu.add(0, MENU_ADD, 0, "Add").setIcon(android.R.drawable.ic_menu_add);
    	menu.add(0, MENU_QUIT, 0, "Quit").setIcon(android.R.drawable.ic_menu_close_clear_cancel);
    	return super.onCreateOptionsMenu(menu);
    }

We’re simply adding 2 items: “Add”, and “Quit”. We also set the icons for them using some default android resources. If you want a full list, this site is pretty cool.

The next method we’ll be using is onOptionsItemSelected(), which is called when the user selects an item in the menu. We use the IDs we assigned in onCreateOptionsMenu() MENU_ADD and MENU_QUIT to decide what to do.

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch(item.getItemId()) {
    		case MENU_ADD:
	        	db.execSQL("INSERT INTO table_of_dics(value) VALUES(" + String.valueOf(Math.random()) + ")");
	        	this.update_list();
    			break;
    		case MENU_QUIT:
    			this.db.close();
    			this.finish();
    	}
 
    	return super.onOptionsItemSelected(item);
    }

So, we’re using a switch() to find the ID of the menu item which called this method. If it’s add, we’re going to perform some SQL and insert a random value into the table. Then we’ll update the list, just like we did in onCreate(). (Remember, we’re defining this method ourselves later)

If the user selected the “Quit” option, we’ll simple close the database and finish the activity. :)

NOTE: The SQL used here, INSERT INTO will insert a random value into the table. Remember to refer to the links at the beginning if you get stuck on the SQL.

Lastly, we’re going to define our method for updating the list. It’s quite simple, but the code is quite different to what we’ve done so far. If you’ve ever done any database work through software/web before, you may notice a few similarities here. We basically execute the query. Then loop through each row in the result, adding it into an ArrayList. Lastly, we set the adapter for the list to display the arraylist we created. The code looks a tad complex, but it’s really quite simple:

    private void update_list() {
    	ArrayList<string> db_results = new ArrayList><String>();
    	Cursor cursor = db.rawQuery("SELECT value FROM table_of_dics ORDER BY value", null);
	    while(cursor.moveToNext()) {
	    	db_results.add(String.valueOf(cursor.getDouble(cursor.getColumnIndex("value"))));
	    }
	    cursor.close();
 
	    this.list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, db_results));
    }

I’ll break this one up:
ArrayList db_results = new ArrayList>(); — create an ArrayList, where we’ll store the results to display in the list.

Cursor cursor = db.rawQuery("SELECT value FROM table_of_dics ORDER BY value", null); — create a cursor based on the query (this select statement will return all the values stored in the table, and order them)

while(cursor.moveToNext()) { — while there is still something in the cursor to read (while we still have another row to read)

db_results.add(String.valueOf(cursor.getDouble(cursor.getColumnIndex("value")))); — add the value from the row into the arraylist we created.

} — this is self explanatory, really. :)

cursor.close(); — close the cursor: we’re done with it now. We have all our results in the ArrayList, which we can now set as the adapter:

this.list.setAdapter(new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, db_results)); — set the adapter.
- parameter 1: the activity we want it for
- parameter 2: the layout type (we can add multiple widgets to a list item, but simple_list_item_1 is a default in android: simply a single TextView.
- parameter 3: the arraylist which we created and populated earlier.

And that’s it! Don’t forget to close off your class

}

Complete code:

package dreamincode.tutorials.dic_tut4;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.view.Menu;
import android.view.MenuItem;
import android.database.sqlite.SQLiteDatabase;
import android.database.Cursor;
import android.widget.ArrayAdapter;
import java.util.ArrayList;
 
public class dic_tut4 extends Activity {
	ListView list;
	SQLiteDatabase db;
 
	private static final int MENU_ADD = Menu.FIRST;
	private static final int MENU_QUIT = Menu.FIRST + 1;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        this.list = new ListView(this);
        this.registerForContextMenu(this.list);
 
    	this.db = this.openOrCreateDatabase("dic_tut5", MODE_PRIVATE, null);
    	this.db.execSQL("CREATE TABLE IF NOT EXISTS table_of_dics(value REAL)");
    	this.update_list();
 
        setContentView(this.list);
    }
 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) {
    	menu.add(0, MENU_ADD, 0, "Add").setIcon(android.R.drawable.ic_menu_add);
    	menu.add(0, MENU_QUIT, 0, "Quit").setIcon(android.R.drawable.ic_menu_close_clear_cancel);
    	return super.onCreateOptionsMenu(menu);
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch(item.getItemId()) {
    		case MENU_ADD:
	        	db.execSQL("INSERT INTO table_of_dics(value) VALUES(" + String.valueOf(Math.random()) + ")");
	        	this.update_list();
    			break;
    		case MENU_QUIT:
    			this.db.close();
    			this.finish();
    	}
 
    	return super.onOptionsItemSelected(item);
    }
 
    private void update_list() {
    	ArrayList<String> db_results = new ArrayList<String>();
    	Cursor cursor = db.rawQuery("SELECT value FROM table_of_dics ORDER BY value", null);
	    while(cursor.moveToNext()) {
	    	db_results.add(String.valueOf(cursor.getDouble(cursor.getColumnIndex("value"))));
	    }
	    cursor.close();
 
	    this.list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, db_results));
    }
}


7Oct/091

Developing for Android, Part III

Dynamic Layouts in Android

No XML in this tutorial! We’ll be completely designing our application in Java, and creating our layout completely dynamically. The benefits of this are that we can add an undefined amount of widgets at run time. This is a pretty useful skill, but not brilliantly documented. (Everything is ZOMG LAYOUT.XML FTW!!1!)

Okay, so let’s get started. We won’t be touching on events in this tutorial, our app won’t actually do anything, per se… it’s merely an example of adding stuff dynamically. You’ll notice how we set the properties through Java, quite similarly to how we define them in the XML.

To start off, remember we’re creating a package, as usual.

package dreamincode.tutorials.dic_tut3;

Next, we’re going to import the usual suspects… Activity and Bundle.

import android.app.Activity;
import android.os.Bundle;

The next two are new. One you may recognise from our layouts before… LinearLayout. We’re also going to use a ScrollView. The reason we’ll be using a ScrollView is that we’re going to add a hell of a lot of widgets, and they wouldn’t all fit on screen. If we don’t put our LinearLayout inside a ScrollView, it simply won’t scroll and the user won’t be able to reach all the widgets!

import android.widget.ScrollView;
import android.widget.LinearLayout;

The last things we need to import are our widgets. We’ll be using an EditText, a TextView, a Button and a CheckBox. We’ve already seen the first three in parts 1 and 2 of this tutorial, but the CheckBox is new. (And I hope the name is self-explanatory for what it is!) ;)

import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.CheckBox;

Now it’s time to get on with our code. We’re only going to extend Activity this time, remember we won’t be using events. This bit’s nothing new, so I’ll just throw in the opening of the class and the opening of the onCreate() method. (Note, if you’re not familiar with this, check part 1 and part 2)

public class dic_tut3 extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

Time to get dirty. Dynamic layouts aren’t always the most elegant of solutions, but they can be fun, and sometimes easier to implement. They’re also really useful for certain occasions (such as SmartCalc, my app: it uses a dynamic layout to decide how many textboxes are needed at runtime)

Code first, explanation afterwards.

        ScrollView sv = new ScrollView(this);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        sv.addView(ll);

LINE 1: Creates a ScrollView object, which is a part of this Activity.
LINE 2: Creates a LinearLayout object, which you hopefully remember from the layout.xml we discussed before.
LINE 3: Sets the orientation of our LinearLayout. Remember how we used android:orientation="vertical" before? Same principal applies here.
LINE 4: Adds the LinearLayout to the ScrollView. Remember, we want to be able to Scroll the LinearLayout View.
NOTE: A ScrollView can **only** have one view added to it. If you try to add more than one, your application WILL force close. If you need to reset it, use ScrollView.removeAllViews(); and re-add whatever you need. (This is why we’re going to add all our widgets to the LinearLayout as opposed to the ScrollView!)

Adding widgets dynamically
Actually, this same principal applies to all our widgets. But I’ll use a few, just to demonstrate. :) This one should look relatively familiar, since we played with TextView.setText() in part 2.

        TextView tv = new TextView(this);
        tv.setText("Dynamic layouts ftw!");
        ll.addView(tv);

Notice how we use addView() on ll, our LinearLayout, just like we added ll to sv? That’s all it takes! :)

Now, let’s do a Button and a EditText. Same principal, just like I said:

        EditText et = new EditText(this);
        et.setText("weeeeeeeeeee~!");
        ll.addView(et);
 
        Button b = new Button(this);
        b.setText("I don't do anything, but I was added dynamically. :)");
        ll.addView(b);

(Remember, when you run the application, the button won’t actually do anything: We haven’t added an OnClickListener! If you want, you may want to revisit the button at the end of this tutorial and try adding an event by yourself. (Use part 2 of this series as a reference if you get stuck)

The next is still the same principal, but I’ve added it in a loop. 20 pointless CheckBoxes, coming up!

        for(int i = 0; i < 20; i++) {
	        CheckBox cb = new CheckBox(this);
	        cb.setText("I'm dynamic!");
	        ll.addView(cb);
        }

This is really just to pad out our layout, so we can really see how useful that ScrollView is. :)

The very last thing we need to do is use setContentView() — similar to how we did before. Remember the this.setContentView(R.layout.main);? Pretty much the same, only now we’re going to use the ScrollView we created earlier instead:

this.setContentView(sv);

And lastly, close off the method and class!

    }
}

Now, if you run this, you'll get a rather crude, but biiiig layout, complete with all the widgets that we added dynamically.

Complete code:

package dreamincode.tutorials.dic_tut3;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.ScrollView;
import android.widget.LinearLayout;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.CheckBox;
 
public class dic_tut3 extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        ScrollView sv = new ScrollView(this);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        sv.addView(ll);
 
        TextView tv = new TextView(this);
        tv.setText("Dynamic layouts ftw!");
        ll.addView(tv);
 
        EditText et = new EditText(this);
        et.setText("weeeeeeeeeee~!");
        ll.addView(et);
 
        Button b = new Button(this);
        b.setText("I don't do anything, but I was added dynamically. :)");
        ll.addView(b);
 
        for(int i = 0; i < 20; i++) {
	        CheckBox cb = new CheckBox(this);
	        cb.setText("I'm dynamic!");
	        ll.addView(cb);
        }
        this.setContentView(sv);
    }
}

See if you can add an OnClickListener to the button, just have a play about with it until you feel fairly confident... I won't be explaining too much about the layouts in the coming tutorials, more on actual features such as SQLite. :)