<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>iQuit</title>
	<atom:link href="http://blog.hawkey.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.hawkey.org</link>
	<description>My experience in iPhone development and entrepreneurship, owning and operating Stormtap Studios.</description>
	<lastBuildDate>Wed, 18 Aug 2010 21:35:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>How long does it take to make a ton of iPhones?  Come on already&#8230;</title>
		<link>http://blog.hawkey.org/?p=463</link>
		<comments>http://blog.hawkey.org/?p=463#comments</comments>
		<pubDate>Wed, 18 Aug 2010 21:33:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=463</guid>
		<description><![CDATA[Dear Apple, What&#8217;s the point of working your offshore manufacturing employees to the brink of suicide if you still can&#8217;t satisfy the demand for your product?  I just got off the phone with a Rogers employee who wouldn&#8217;t even estimate how long it would take for him to be able to sell me an iPhone.  [...]]]></description>
			<content:encoded><![CDATA[<p>Dear Apple,</p>
<p>What&#8217;s the point of working your offshore manufacturing employees to the brink of suicide if you still can&#8217;t satisfy the demand for your product?  I just got off the phone with a Rogers employee who wouldn&#8217;t even estimate how long it would take for him to be able to sell me an iPhone.  I asked for a rough estimate, in the form of &#8220;weeks, months or years&#8221; and he wouldn&#8217;t do it.  He said he had a waiting list but with such a snide tone I knew there was no point adding my name to it.  You know like &#8220;you <em>COULD</em> go on the waiting list *snicker*&#8221;.</p>
<p>Why are you releasing the <a href="http://news.cnet.com/8301-13506_3-20013830-17.html">iPhone 4 in China next month</a> if you haven&#8217;t got one in the hands of all your greedy North American fans first?  At least hook your North American developers up first!  We&#8217;re too busy making apps that make you rich to camp outside overnight.  We&#8217;re also not the ones flooding your store with junk apps.  Well, for the most part.</p>
<p>Anyways, be nice and just send me one for free.</p>
<p>Signed,</p>
<p>Me</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=463</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A view into what I&#8217;m working on now</title>
		<link>http://blog.hawkey.org/?p=459</link>
		<comments>http://blog.hawkey.org/?p=459#comments</comments>
		<pubDate>Mon, 19 Jul 2010 17:24:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=459</guid>
		<description><![CDATA[This is a screenshot of the project I&#8217;ve been working on since the Android port of Prescriber&#8217;s Letter: The name Retro Radio isn&#8217;t set in stone yet, but describes the app well.  Retro Radio will simulate the behaviour of a real antique radio.  The user will be able to tune the channel dial and will [...]]]></description>
			<content:encoded><![CDATA[<p>This is a screenshot of the project I&#8217;ve been working on since the Android port of Prescriber&#8217;s Letter:</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/07/radioscreenshot.png"><img class="aligncenter size-full wp-image-460" title="radioscreenshot" src="http://blog.hawkey.org/wp-content/uploads/2010/07/radioscreenshot.png" alt="" width="320" height="480" /></a></p>
<p>The name Retro Radio isn&#8217;t set in stone yet, but describes the app well.  Retro Radio will simulate the behaviour of a real antique radio.  The user will be able to tune the channel dial and will hear the normal sounds of a radio as you move between channels.  There will be two kinds of stations placed throughout the dial, music stations that play music from the 1920s and story channels that play old radio shows.  The dials are tuned just like a real radio, the user uses two fingers and &#8220;pinches&#8221; the dial and turns it, this moves the needles and of course changes what the radio plays.</p>
<p>The user will be able to configure how they want the radio to work.  They can set it so that shows air at a regularly scheduled time in order to experience the real feeling of being back in time eagerly awaiting the next episode of your favourite show, or they can configure it so that when they tune into a particular show&#8217;s channel they&#8217;re played the next show they haven&#8217;t listened to yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=459</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open source is awesome</title>
		<link>http://blog.hawkey.org/?p=457</link>
		<comments>http://blog.hawkey.org/?p=457#comments</comments>
		<pubDate>Thu, 24 Jun 2010 23:35:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=457</guid>
		<description><![CDATA[I love open source software.  I love that there are people out there with such a love of programming that they&#8217;re willing to spend countless hours of their own time to build cool things that people find extremely useful on a day to day basis.  For iPhone development one of the best open source things [...]]]></description>
			<content:encoded><![CDATA[<p>I love open source software.  I love that there are people out there with such a love of programming that they&#8217;re willing to spend countless hours of their own time to build cool things that people find extremely useful on a day to day basis.  For iPhone development one of the best open source things around is Cocos2D.  Here was a package originally made for Python that riq went and converted to Objective-C and now is used in all kinds of iPhone games, and by me for my current project.  When you read the forums you see all kinds of cool stuff happening.  The community works together to support each other&#8217;s efforts, to further develop the library and quickly fix bugs that come up.</p>
<p>Every now and then you even get to see financial success based around the open source project, whether it&#8217;s by supporting users of the software, or building addons to the software.  In the case of Cocos2D for iPhone check out <a href="http://particledesigner.71squared.com/index.html">Particle Designer</a> by 71 Squared.  This thing is amazing.  I&#8217;ve developed games for 10 years and every game I&#8217;ve worked on used particles in one way or another and none of them ever had a programmer with the time to build as nice of a particle design tool as this, and here&#8217;s one you can buy for $8 that works with an open source engine.  That&#8217;s so awesome it blows my mind.  I&#8217;ll be buying it straight away and putting it to good use.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=457</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trying to figure out how to work bandwidth costs into the cost of my app</title>
		<link>http://blog.hawkey.org/?p=454</link>
		<comments>http://blog.hawkey.org/?p=454#comments</comments>
		<pubDate>Mon, 21 Jun 2010 22:36:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=454</guid>
		<description><![CDATA[After checking it out, and messing around some more with an updated ASIHTTPRequest library I&#8217;ve decided to use Amazon&#8217;s S3 storage service to host the media my new app will stream.  This means I need to figure out how to incorporate the costs of bandwidth into the price of the app, as well as ensure [...]]]></description>
			<content:encoded><![CDATA[<p>After checking it out, and messing around some more with an updated ASIHTTPRequest library I&#8217;ve decided to use Amazon&#8217;s S3 storage service to host the media my new app will stream.  This means I need to figure out how to incorporate the costs of bandwidth into the price of the app, as well as ensure that ongoing use of the app doesn&#8217;t bankrupt me.</p>
<p>Right now the plan is to charge an upfront fee to the user (the price of the app) which entitles the user to X hours of use.  Once the hours run out the user won&#8217;t be able to stream anymore media from the S3 service.  Then I&#8217;ll incorporate in-app purchase which will allow the user to purchase more listening time.  I&#8217;m worried about the nature of this, I&#8217;m scared about the extra barrier this puts on the purchase decision.</p>
<p>Other options would be just to increase the overall price of the app, and then assume that some users will use the app a lot, and some will use it very little.  This is a dangerous move I think, users could decide they love the app so much and use it constantly which would kill my profits of course.  I also thought about adding ads to the app, but I don&#8217;t think that would generate much revenue due to the nature of the app.  People will turn it on, tune into a stream and then lock the screen and put their iPhone in their pocket.  They&#8217;re not going to stare at it and tap ads.</p>
<p>Even if I go with the purchased time approach, I&#8217;ve still got the pirates to worry about.  Lots to think about with this issue that&#8217;s for sure.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=454</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prescriber&#8217;s Letter finally up on Android Marketplace</title>
		<link>http://blog.hawkey.org/?p=450</link>
		<comments>http://blog.hawkey.org/?p=450#comments</comments>
		<pubDate>Fri, 11 Jun 2010 21:15:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Android Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=450</guid>
		<description><![CDATA[Well after lots of trouble with a nasty bunch of issues on one device (the HTC Incredible, which should be called the HTC Incredibly Crappy) Prescriber&#8217;s Letter is now up on Android Marketplace. The HTC Incredible had all kinds of weird issues.  When we enabled zoom on all the WebViews that caused the WebView to [...]]]></description>
			<content:encoded><![CDATA[<p>Well after lots of trouble with a nasty bunch of issues on one device (the HTC Incredible, which should be called the HTC Incredibly Crappy) Prescriber&#8217;s Letter is now up on Android Marketplace.</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/06/prlandroid.png"><img class="aligncenter size-medium wp-image-451" title="prlandroid" src="http://blog.hawkey.org/wp-content/uploads/2010/06/prlandroid-180x300.png" alt="" width="180" height="300" /></a>The HTC Incredible had all kinds of weird issues.  When we enabled zoom on all the WebViews that caused the WebView to crash on that device only.  We had to check the device model and disable zoom for the Incredible.  Then we had all sorts of strange issues with respect to leaving the app (either by the back button or the home button) and then coming back into the app.  On every device but the incredible we would get one pattern of resume calls for activities, but on the HTC Incredible it seemed to want to recreate the default activity every time, which sort of left the existing stack of activities orphaned.  I had to do a bunch of custom work for the Incredible to work around this.</p>
<p>So, if you&#8217;re doing any Android work try to get yourself an HTC Incredible to test with.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=450</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evaluating Amazon S3 storage service</title>
		<link>http://blog.hawkey.org/?p=447</link>
		<comments>http://blog.hawkey.org/?p=447#comments</comments>
		<pubDate>Tue, 08 Jun 2010 17:10:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[iPhone Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=447</guid>
		<description><![CDATA[My next project will require streaming media which I need to host somewhere.  I have a website (stormtapstudios.com) which I&#8217;ve paid for unlimited storage/bandwidth, but I&#8217;m positive for the amount I pay that bandwidth pipe can&#8217;t be all that wide.  So I&#8217;m currently checking into things like Amazon&#8217;s S3 storage service to determine whether I [...]]]></description>
			<content:encoded><![CDATA[<p>My next project will require streaming media which I need to host somewhere.  I have a website (stormtapstudios.com) which I&#8217;ve paid for unlimited storage/bandwidth, but I&#8217;m positive for the amount I pay that bandwidth pipe can&#8217;t be all that wide.  So I&#8217;m currently checking into things like Amazon&#8217;s S3 storage service to determine whether I can make it work economics-wise.  Essentially what I need to do is estimate the amount of user my app will get by the average user, and then incorporate the bandwidth/storage costs of that use into the price of my app.  This will be pretty tricky to do, if I guess wrong then I&#8217;ve got an app on the store that costs me money rather than makes me money!  Not exactly my goal as a successful entrepreneur. <img src='http://blog.hawkey.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=447</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking for the next contract, continuing work on my own apps</title>
		<link>http://blog.hawkey.org/?p=444</link>
		<comments>http://blog.hawkey.org/?p=444#comments</comments>
		<pubDate>Mon, 31 May 2010 20:27:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Entrepreneurship]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=444</guid>
		<description><![CDATA[Well after completing the Android port for Prescriber&#8217;s Letter I&#8217;m now pursuing other opportunities for contract work.  I&#8217;ve been chasing leads here and there, some more promising than others, but the good news is that there does seem to be work out there.  It&#8217;s interesting, so far every time I&#8217;ve finished or come close to [...]]]></description>
			<content:encoded><![CDATA[<p>Well after completing the Android port for Prescriber&#8217;s Letter I&#8217;m now pursuing other opportunities for contract work.  I&#8217;ve been chasing leads here and there, some more promising than others, but the good news is that there does seem to be work out there.  It&#8217;s interesting, so far every time I&#8217;ve finished or come close to finishing a project something has popped up to pursue.  The ones I&#8217;m after right now are long shots, but that&#8217;s ok.  It gives me time to focus on my own apps again.</p>
<p>As for which of my numerous ideas that all seem like gold mines to pursue, that&#8217;s the tough part isn&#8217;t it.  Time to do research, figure out which one I can do in the least amount of time with the best guess at chance for reward.  I need to approach the next app I make differently, I need to bake in all the tricks for attracting attention to it right from the start (Facebook, Twitter, etc&#8230;) and also just take the app development in steps.  I&#8217;ll build something simple first and get it on the store to test the waters.  Then I&#8217;ll look into expanding features and beefing it up when I see whether it&#8217;s a potential seller.  I can&#8217;t just put my head in the sand like with Photo Resize and pop up after 3 months only to sell a few copies a week.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=444</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prescriber&#8217;s Letter Android Port Post Mortem</title>
		<link>http://blog.hawkey.org/?p=434</link>
		<comments>http://blog.hawkey.org/?p=434#comments</comments>
		<pubDate>Wed, 19 May 2010 17:20:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Android Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=434</guid>
		<description><![CDATA[I thought I would follow up my post mortem of the iPhone version of Prescriber&#8217;s Letter with a discussion about the complexities involved in porting the app to the Android OS. This will be a long blog post, so continue reading only if interested in the technical details involved with Android development. If you haven&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I would follow up my post mortem of the iPhone version of Prescriber&#8217;s Letter with a discussion about the complexities involved in porting the app to the Android OS.  This will be a long blog post, so continue reading only if interested in the technical details involved with Android development.</p>
<p><span id="more-434"></span>If you haven&#8217;t already read the <a href="http://blog.hawkey.org/?p=371">iPhone post mortem</a> you should probably do that first as this post will largely be discussing the differences of the platforms and how I solved the Prescriber&#8217;s Letter (PRL) requirements on Android.</p>
<p>The first thing I did was hit the books.  I purchased these <a href="http://commonsware.com/">e-books from Mark Murphy</a> , and they proved invaluable.  If you&#8217;ve asked a question on the Android beginners or Android developers Google groups then you know who Mark Murphy is, he seems to answer all of them.  I read over all of the Android developer guide (glossing over stuff that would have saved me time if I&#8217;d read more thoroughly that&#8217;s for sure).</p>
<h1>Activity Design</h1>
<p>Most Android applications are centered on the concept of the Activity.  An Activity is a class that is launched with an intent to display a GUI that allows the user to perform a task.  It is the interface between your code and the OS (file resources, device information, network connectivity, really everything hardware goes through the Activity).  When I first planned out how the app would work I went with a design that looked like this:</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/05/firstactivitydesign.png"><img class="aligncenter size-full wp-image-435" title="firstactivitydesign" src="http://blog.hawkey.org/wp-content/uploads/2010/05/firstactivitydesign.png" alt="" width="300" height="300" /></a></p>
<p>The original design had the “Main” activity (set as the default in the manifest for the app) launching the login screen, the login screen would do its work, launch the main menu screen and then invoke finish().   The main menu activity would then invoke all the sub-activities of the app (Issue screens, articles, detail documents, etc&#8230;).  This original design was flawed in that it was ignorant of the life cycle of Android applications.  When developing Android apps you need to plan for how your activities will react to being created, resumed, paused and stopped.  You need to incorporate what will happen when the user presses the back button.  If you&#8217;re used to iPhone programming you&#8217;re used to a home button press shutting your application down completely.  On the Android hitting the back button, even on your root activity doesn&#8217;t shut anything down.  The Android model wants all applications to be running all the time (in a perfect unlimited resources world).  Your applications are only closed when the system determines it needs to free up resources for the current highest priority applications, and your apps are the lowest priority apps (because they&#8217;re in the background and not currently the focus of the user&#8217;s attention).  So about midway into production I ended up having to do a lot of rearranging and revising my plan for the way activities were launched and how each activity would react when it was resumed.  I came up with this design:</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/05/secondactivitydesign.png"><img class="aligncenter size-full wp-image-436" title="secondactivitydesign" src="http://blog.hawkey.org/wp-content/uploads/2010/05/secondactivitydesign.png" alt="" width="300" height="300" /></a></p>
<p>In this design the main activity is the root, and it launches either the login screen or the main menu depending on what state the application is in.  When it launches activities it uses the startActivityForResult() method, and waits for a response.  When the login screen finishes its work it will respond with instructions to the main activity to display the main menu.  When the main menu finishes its work it will respond with instructions to load the login screen (and either start an automatic login, or just sit there).  This system carried forward to the other activities as well, the main menu would launch sub activities and wait for responses (and sub activities would do the same).  Each activity from the main menu and up could respond with several control instructions like “pop to the main menu”, or “Close everything down and go to the login screen”.  This created a very flexible system that let me jump around as needed and fit the Android activity life-cycle much better.</p>
<h1>Application Persistence Problem</h1>
<p>The persistent nature of the app on Android presented a major problem to us.  The app was designed on the iPhone to do a bunch of preliminary work at the beginning:  authenticate the user, upload stored quiz results from when they answered quiz questions while offline, check for and download new content bundles and check the expiry date on the user&#8217;s account.  Because we could no longer rely on the app having done all of these things before use we needed to come up with a plan to periodically perform these tasks.  I wrote a class that fires up a thread that goes to sleep immediately and wakes up every few hours.  When it wakes up it performs all the startup operations, and if it finds any issues that need to be addressed it sends a message to the current activity.  The current activity can then make use of the Activity response system to tell the app how to handle the event.  For example if a new content bundle becomes available, the updating thread will detect it, inform the activity and the activity will then ask the user if they want to download the new bundle.  If they chose yes, the activity finishes with a response to drop all the way to the main activity and fire up the login screen with an automatic content download attempt.  Very handy!</p>
<h1>AsyncTask, it&#8217;s good, use it.</h1>
<p>For all of the thread work I needed to write for the app I used the AsyncTask class rather than write my own thread.  I am enjoying the philosophy of these new platforms to create wrappers for thread management.  The iPhone has the same thing with the NSOperationQueue and NSOperation objects.  AsyncTask takes the trouble out of communicating between the thread launching the task and the task itself.  It also protects you from performing GUI operations outside of the main UI thread.  All you do is figure out classes for parameters to the task, and return values from the task and then implement the doInBackground() and the various onPostExecute(), onProcessUpdate(), etc. methods.  Execute the task from the main thread and away you go.</p>
<p>I thought I was leaking threads for the longest time while watching the debugger and when I finally went to address it, I found out by searching around that what actually is happening is that the AsyncTask class makes use of an internal pool of threads to do your jobs.  They do stick around, but that&#8217;s intentional.  Seems efficient to me too.</p>
<h1>Porting Core Database Logic</h1>
<p>Porting the core database logic was extremely straight forward.  On the iPhone project we designed all of the database work so that it would be easy to port to Android or the Blackberry.  All of the functions were straight C functions executing SQL with SQLite3.  Since Android has an SQLite library porting all of this logic was no problem.  There was a lot of code to port over and switch to Java, but no real complexity involved since the logic was most implemented via SQL.</p>
<h1>SD Card vs. ROM Storage</h1>
<p>When you&#8217;re storing data in an Android app you need to decide between storing on the built-in ROM or the mini-SD card most of the devices come with.  The conventional theory is that if you have a lot of data you should store it on the SD card.  The problem with storing data on the SD card though is that there is no security to it, and the data is not uninstalled when the app is uninstalled.  These two points led us to prefer storing data on the ROM, but also writing code to use the SD card if there is insufficient space on the ROM.</p>
<h1>ListViews</h1>
<p>One pleasant surprise to me was the much easier way you create and manage ListView widgets on Android.  By using the methods described in the Commonsware book I was usually able to get the data/view create logic up to speed quickly.  Some were more complex than others but overall it went quite smoothly.  For each screen that had a list I would write a class that extended BaseAdapter.  By overriding the inherited methods from that and setting an instance of the class as the ListView&#8217;s adapter I had full control over what types of views would show up in the list, generating views for each cell, and configuring the contents of each cell&#8217;s view.  From there it was a simple matter of inflating XML layouts into the cells on demand.  This made things very flexible and adjustable at runtime, whereas I find the iPhone&#8217;s ListView not so flexible.  The iPhone version really wants to have everything sorted out when the List is being created.  It wants to know exactly how big every cell is going to be, what&#8217;s going to be in the cells, etc&#8230;  Because you can inflate XML-based layouts in the Android version and those layouts can include flexible containers and widgets that adjust based on the content you put in them at runtime, everything sort of just works.  I think that this obviously has some tradeoffs.  Luckily our app doesn&#8217;t require any lists that have hundreds and hundreds of cells or I&#8217;m sure it would all come crashing down, in the end though for our app the experience is much better and the lists themselves look and feel better.  Well, certainly they were a lot easier to code up.</p>
<h1>Screen Resolution / Pixel Density / Orientation Issues</h1>
<p>While ListView objects were easier to get right, I can&#8217;t say the same for the rest of the GUI. This project as a whole took a lot longer than it should have given that I had all the hard parts already figured out from the iPhone project.  A big part of that reason was layout programming.  Building GUIs by hand through XML is not my opinion of a pleasant way to spend several months.  There&#8217;s a lot of guesswork involved, and the platform itself is still immature and luckily for you it&#8217;s your fun experience to find out where the holes are and work around them.  For example, on one particular ListView we had a problem where the cells would not grow to wrap their content, but only when testing on Android 1.5 in the emulator.  It took a long time to figure out that for some reason Android 1.5 just didn&#8217;t like the use of the RelativeLayout group in that scenario.  When I changed things around to use a LinearLayout voila everything worked perfectly.  This was not the only instance of this kind of craziness I got to enjoy throughout development.  I spent a lot of time scouring posts on the Internet, tutorials, the Commonsware book, etc.. to navigate the quirks of laying out the GUI in such a way that it would work on every device for every version of the OS.</p>
<p>There are a ton of Android devices out there, their screen resolutions and pixel density are all over the map.  When you decide to make an Android application this needs to be front and center in your design right from the very beginning. You have to make promises to yourself that you aren&#8217;t going to take any shortcuts in how you implement your layouts.  No using AbsoluteLayout.  No using fixed pixel dimensions or text sizes.  It&#8217;s a very strange thing, but it has to be done.  Basically you&#8217;re programming for the web, except some people are running your app on wrist watch sized screens, and some guys are running it on huge 480&#215;854 resolution smart phones.</p>
<p>The majority of our layouts grow and stretch perfectly.  Midway through I switched over to using “Xdp” measurements for any padding or margins for GUI components and that took care of the pixel density issues.  The login screen was the biggest hassle because it has the most text and controls to interact with of all the other screens.  The other screens tended to be large fullscreen controls that just got smaller or bigger.  For the login screen I had to even go so far as to define an alternate layout file for landscape.</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/05/loginlandscape.png"><img class="aligncenter size-medium wp-image-437" title="loginlandscape" src="http://blog.hawkey.org/wp-content/uploads/2010/05/loginlandscape-300x200.png" alt="" width="300" height="200" /></a></p>
<h1>The IDE, debugger, Emulator and Build Environment</h1>
<p>This by far was the most frustrating part of the Android port experience.  I found the Eclipse IDE extremely slow, buggy and mainly just a general pain in the butt.  The emulators supplied with the Android SDK are slow and unresponsive.  The build system is a pain as well but that&#8217;s Java&#8217;s fault not Eclipse or Android.  I have yet to determine where the performance fault lies, whether it&#8217;s my Macbook Pro with 4GB of RAM, my Android Dev Phone 2 or just the way Eclipse and the Android tools were written.  I could never leave Eclipse running for long periods of time.  If I left it running overnight I would come back to an extremely slow program that would take 15 – 20 seconds to switch between files, or up to 2 minutes to rebuild the workspace when I save a layout file.  I&#8217;d investigate and see that Eclipse was operating with a 6GB pagefile on my machine.  Rebuilding the workspace constantly was fine some of the time, but really a pain when you forget that it&#8217;s turned on.  If you want to make a few small changes to a bunch of layout files you have to be smart and save them all at once when you&#8217;re done or else if you save them one at a time you have to wait for the build to complete each time.  It was the culmination of these points listed and another million little things that just made dealing with the IDE and the Android tools just a general poor experience on a daily basis.</p>
<p>Towards the end of the project I had to tackle the task of turning the generic code base into 5 different apps, each targeting the 5 different publications offered by my client (Therapeutic Research Center).  On the iPhone this was a very simple process, I used #defines to section off any platform specific code, and I made use of the target system for defining certain resources as belonging to one publication or another.  To build all of the apps it was a simple matter of a making a group target that depended on each publication target.  Since Java does not have a precompiler, and due to the way the R resource class is built and an integral part of everything you do on the Android this old way of doing things wasn&#8217;t going to fly.</p>
<p>I ended up having to use the method described by all of the developers on the Google groups who&#8217;ve attempted to make “lite” versions of their apps.  Here&#8217;s the steps I followed:</p>
<ul>
<li>I used the 	command-line project building tool to generate an empty project.</li>
<li>I took all of 	the build files out of that project in order to get a base set of 	build files (local.properties, build.properties, default.properties 	and the build.xml file).</li>
<li>I placed the 	build files into my project&#8217;s folder and then renamed them all 	except for default.properties.  I fixed all the references to refer 	to the new names.</li>
<li>I then wrote 	a large Ant script that would essentially build one project at a 	time:
<ul>
<li>First it 		built the default project that I used all throughout development 		(targeting Prescriber&#8217;s Letter).</li>
<li>It then 		renamed the src and res folders to src_orig and res_orig, as well 		as the manifest.</li>
<li>For each 		publication after that:
<ul>
<li>I would 			copy all the files from src_orig to src, and res_orig to res.</li>
<li>I&#8217;d iterate 			through every java file under src, and every XML file under res 			and replace the package for the base app (trc.prl) with the 			current publication (trc.pl, trc.plc, trc.prlc, trc.ptl).</li>
<li>I&#8217;d then do 			the same thing in the manifest file.</li>
<li>Once the 			replacements were made I could then execute a normal build, so I&#8217;d 			do an ant call out to the other normal build file and it would 			build the existing state of the project folder as if the project 			had been developed that way to begin with.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>At the end of the script all the original stuff gets put back where it was and the copies are all cleaned up.  Basically everything above is a summary of what was generally what you would do by hand if you had a set of source code and you were changing it from one app to another but you wanted all the code to pretty much stay the same.  The way I get around the apps performing differently was I had a single constant in a singleton class that also was string replaced to be one value or another.  The code then references that constant to decide which assets to load (for background images, or string files), and which publication URLs to target for downloading content, authenticating and uploading quiz results.  This process worked very well in the end.  I even upgraded the script to do my entire build process for me.  It signs the final apps, zipaligns them and will even install them on the current device if you call the install target.  This process turned out quite well but it took a couple of days to implement, I&#8217;d trade it all in an instant for #ifdef.</p>
<h1>Summary</h1>
<p>Well, all complaining aside I can&#8217;t say that working with Android was all horrible.  Some things were nice, and overall it was fun to learn yet another platform and all the complexities involved.  I must say that I&#8217;ve become quite the expert at jumping into new platforms.  The more I do it the more I see all the similarities an it becomes just a matter of “How did they solve this problem that always comes up, oh they went this direction, or that direction, ok I know how that works.”  It is definitely getting easier that&#8217;s for sure.</p>
<p>The following are some screenshots from the end Android product.  As you can see we strived to have the application look identical to the iPhone version as much as possible.</p>
<p>Main Menu:</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/05/mainmenu.png"><img class="aligncenter size-medium wp-image-438" title="mainmenu" src="http://blog.hawkey.org/wp-content/uploads/2010/05/mainmenu-200x300.png" alt="" width="200" height="300" /></a></p>
<p>Issue:</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/05/issue.png"><img class="aligncenter size-medium wp-image-439" title="issue" src="http://blog.hawkey.org/wp-content/uploads/2010/05/issue-200x300.png" alt="" width="200" height="300" /></a>Article:</p>
<p><a href="http://blog.hawkey.org/wp-content/uploads/2010/05/article.png"><img class="aligncenter size-medium wp-image-440" title="article" src="http://blog.hawkey.org/wp-content/uploads/2010/05/article-200x300.png" alt="" width="200" height="300" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=434</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working downtown at the library today</title>
		<link>http://blog.hawkey.org/?p=432</link>
		<comments>http://blog.hawkey.org/?p=432#comments</comments>
		<pubDate>Tue, 04 May 2010 17:26:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=432</guid>
		<description><![CDATA[I&#8217;m going to try to make an effort to work outside of the house, just to get out and see other people and environments and prevent the hermit syndrome from sinking in. Luckily Vancouver has a great library downtown with free WiFi and nice seats/tables to work from. Sometimes I&#8217;ll go to my wife&#8217;s University [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m going to try to make an effort to work outside of the house, just to get out and see other people and environments and prevent the hermit syndrome from sinking in.  Luckily Vancouver has a great library downtown with free WiFi and nice seats/tables to work from.  Sometimes I&#8217;ll go to my wife&#8217;s University which also has Internet access and good places to work.</p>
<p>I still prefer working at home, but I think it&#8217;s good to get out.  For example every time I come downtown lately I see a new skyscraper that wasn&#8217;t there before.  Vancouver has nowhere to build but up, so that&#8217;s understandable, I just thought I came downtown more often than the speed of skyscraper building.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=432</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Damn, plugin killed the site for the weekend, sorry about that.</title>
		<link>http://blog.hawkey.org/?p=430</link>
		<comments>http://blog.hawkey.org/?p=430#comments</comments>
		<pubDate>Mon, 26 Apr 2010 18:38:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Android Development]]></category>

		<guid isPermaLink="false">http://blog.hawkey.org/?p=430</guid>
		<description><![CDATA[It appears the Tweetable plugin I was using to push notices to my Twitter followers of new blog posts died on its own over the weekend and made it so every page on the blog was coming up blank. Not cool! Besides putting out blog fires I&#8217;ve just finished Milestone 2 for the Android project [...]]]></description>
			<content:encoded><![CDATA[<p>It appears the Tweetable plugin I was using to push notices to my Twitter followers of new blog posts died on its own over the weekend and made it so every page on the blog was coming up blank.  Not cool!</p>
<p>Besides putting out blog fires I&#8217;ve just finished Milestone 2 for the Android project and I&#8217;m moving on to Milestone 3.  Milestone 2 taught lots of GUI creation lessons for Android.  The lesson being that it takes a LONG time to make GUIs on the Android compared to the iPhone.  The one thing I like better on the Android though is that since you&#8217;re coding the GUI by hand with XML you&#8217;re already thinking of screen &#8220;scalability&#8221;, i.e. you&#8217;re already factoring in different resolutions and orientations.  I&#8217;ve had rotating the app working since day one.  So far on my iPhone projects multiple orientations have been afterthoughts (even though they shouldn&#8217;t be).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.hawkey.org/?feed=rss2&amp;p=430</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
