<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Tristan Waddington</title>
	
	<link>http://www.tristanwaddington.com</link>
	<description>Web Development and Strategic Communication</description>
	<lastBuildDate>Thu, 02 Feb 2012 05:10:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4-alpha-19620</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/twaddington" /><feedburner:info uri="twaddington" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>The iPad bias and the Samsung Galaxy Tab</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/SIatQVESTFQ/</link>
		<comments>http://www.tristanwaddington.com/2011/09/ipad-vs-the-samsung-galaxy-tab/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 05:09:50 +0000</pubDate>
		<dc:creator>tristan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[android apple ios]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=1107</guid>
		<description><![CDATA[Samsung recently announced the release of their new mid-sized 8.9-inch Samsung Galaxy Tab (starting at $469 for the 16GB model). Personally, this is a device I&#8217;m very excited about. As an Android developer I&#8217;ve been dismayed by the lack of a good Android tablet, one that I actually want to own myself. The Motorola Xoom [...]]]></description>
			<content:encoded><![CDATA[<p>Samsung <a href="http://www.engadget.com/2011/09/19/samsung-galaxy-tab-8-9-wifi-gets-us-pricing-16-gig-model-starts/">recently announced</a> the release of their new mid-sized <a href="http://www.samsung.com/us/mobile/galaxy-tab/GT-P7310MAAXAR">8.9-inch Samsung Galaxy Tab</a> (starting at $469 for the 16GB model). Personally, this is a device I&#8217;m very excited about. As an Android developer I&#8217;ve been dismayed by the lack of a good Android tablet, one that I actually want to own myself. The Motorola Xoom is powerful, but it&#8217;s ugly and unwieldy. The 10.1-inch Galaxy Tab looks promising, but like the Xoom, it&#8217;s just a bit too big for my liking.</p>
<p>Enter, the 8.9-inch tablet. Just a bit smaller than the Galaxy Tab, but packing the same hardware, it&#8217;s amazing they could fit all that into such a small package. Sounds like just the right size for me.</p>
<p>Now, here&#8217;s the disgusting part, the media coverage. The Galaxy Tab has been lambasted by bloggers for being too expensive. Ricardo Bilton over at ZDNet <a href="http://www.zdnet.com/blog/gadgetreviews/samsung-to-price-galaxy-tab-89-wifi-starting-at-469/27537">says this about the new 8.9-inch tab</a>:</p>
<blockquote><p>
Interested in picking one up? We didn’t think so. With a screen size smaller than that of the iPad, Samsung’s asking price for its 8.9-inch tablet is a hair short of absurd.
</p></blockquote>
<p>Absurd, really? Since when does bigger equal better in the tech world. Has miniaturization not always been the goal of hardware engineers? Let&#8217;s look at the specs.</p>
<p>Surprisingly (or maybe not) the two devices have very similar hardware. Both tablets are available in a 16GB and a 32GB model; both run a 1GHz dual-core processor; both have equivalent WiFi support; both have a front and rear facing camera; both have bluetooth support and both can play full 1080p video and most of your favorite audio and video formats. Seeing a trend here?</p>
<p>Now, some of the major differences. The iPad 2 has a 9.7-inch (diagonal) screen with a 1024 by 768-pixel resolution, while the Galaxy Tab 8.9 has an 8.9-inch (diagonal) screen with a 1280 by 800-pixel resolution. The devices are both about the same thickness 8.8mm for the iPad 2 and 8.6mm for the 8.9-inch tab, but the tab is much lighter at 447 grams versus 601 grams for the iPad 2. The iPad 2 of course runs Apple&#8217;s iOS operating system while the 8.9-inch tab runs a skinned version of Google&#8217;s Android 3.1 (Honeycomb) tablet OS.</p>
<p>So here&#8217;s my question. Why on earth would anyone expect an .8-inch difference in screen size to equal a discount of several hundred dollars? This is not a discount tablet and in this case the size is more of a feature than anything. The 8.9-inch galaxy tab is absolutely as high-end a tablet as the iPad 2. It packs almost exactly the same hardware into a slightly smaller, slightly different form-factor. It runs a different, though equally capable and complex Operating System (Android) and offers an alternative to Apple&#8217;s walled garden app-store.</p>
<p>Seriously people, can&#8217;t we all just be civilized and have an adult conversation about our toys? Both devices obviously appeal to different sets of consumers. It&#8217;s about damn time we had a high-end piece of hardware in a svelte package running Google&#8217;s latest and greatest. Now if only we could get Samsung to offer a TouchWiz free model.</p>
<p><strong>Sources</strong></p>
<ul>
<li><a href="http://www.apple.com/ipad/specs/">iPad 2 Specs</a></li>
<li><a href="http://www.samsung.com/us/mobile/galaxy-tab/GT-P7310MAAXAR-specs">Galaxy Tab 8.9 Specs</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/SIatQVESTFQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2011/09/ipad-vs-the-samsung-galaxy-tab/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2011/09/ipad-vs-the-samsung-galaxy-tab/</feedburner:origLink></item>
		<item>
		<title>Add mercurial or git changeset id to your Android app</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/HK_hhASFHvA/</link>
		<comments>http://www.tristanwaddington.com/2011/07/update-hg-or-git-changest-during-android-build/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 19:29:55 +0000</pubDate>
		<dc:creator>tristan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=1086</guid>
		<description><![CDATA[We recently automated the debug builds of our Android app. As a result, we wanted to include the Mercurial changeset id in our app settings, so we could quickly tell what version of the app someone was running. What we ended up doing was writing the changset id to a custom properties file that was [...]]]></description>
			<content:encoded><![CDATA[<p>We recently <a href="http://www.tristanwaddington.com/2011/06/automated-android-builds-with-jenkins/">automated the debug builds</a> of our Android app. As a result, we wanted to include the Mercurial changeset id in our app settings, so we could quickly tell what version of the app someone was running.</p>
<p>What we ended up doing was writing the changset id to a custom properties file that was then copied into the raw directory during a build. That properties file could then be read by our PreferencesActivity on runtime.</p>
<p>In order to do this we wrote a custom build.xml file for ant. Simply copy and paste the following into your build.xml file:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;">&lt;!-- Require the hg.revision task during pre-build --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;-pre-build&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;hg.revision&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- Check to see if a mercurial repository exists in the source dir --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;available</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;.hg&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;dir&quot;</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;hg.present&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- Get the mercurial changeset id for tip --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;hg.revision&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Store mercurial revision in ${repository.version}&quot;</span> <span style="color: #000066;">if</span>=<span style="color: #ff0000;">&quot;hg.present&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec</span> <span style="color: #000066;">executable</span>=<span style="color: #ff0000;">&quot;hg&quot;</span> <span style="color: #000066;">outputproperty</span>=<span style="color: #ff0000;">&quot;hg.revision&quot;</span> <span style="color: #000066;">failifexecutionfails</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000066;">errorproperty</span>=<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;id&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;-i&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;-n&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;-r&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;tip&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/exec<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;echo</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">&quot;Repository version is ${hg.revision}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Create property file containing mercurial changeset id --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;propertyfile</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;version.properties&quot;</span> <span style="color: #000066;">comment</span>=<span style="color: #ff0000;">&quot;The changset id that this app was built from.&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;entry</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;changeset&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;${hg.revision}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/propertyfile<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Move property file to app accessible res/raw/ directory --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;move</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;version.properties&quot;</span> <span style="color: #000066;">todir</span>=<span style="color: #ff0000;">&quot;res/raw/&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Essentially this creates an executable task that calls <code>hg id -i -n -r tip</code> in the build workspace. It then adds the result of that command to a propertyfile called <code>version.properties</code>. That file is then copied to the <code>res/raw/</code> directory.</p>
<p>Our app code is even more straightforward. We simply wrote a function to retrieve the changeset id from the properties file in the raw resources directory. We then take the output of this function and update the preference item.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    @Override
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> onCreate<span style="color: #009900;">&#40;</span>Bundle savedInstanceState<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onCreate</span><span style="color: #009900;">&#40;</span>savedInstanceState<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        addPreferencesFromResource<span style="color: #009900;">&#40;</span>R.<span style="color: #006633;">xml</span>.<span style="color: #006633;">settings</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Display app_build in settings as set in the app.version properties file at build time</span>
        Preference build <span style="color: #339933;">=</span> findPreference<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;app_build&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        build.<span style="color: #006633;">setSummary</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getAppChangsetFromPropertiesFile</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getAppChangsetFromPropertiesFile<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        Resources resources <span style="color: #339933;">=</span> getResources<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">InputStream</span> rawResource <span style="color: #339933;">=</span> resources.<span style="color: #006633;">openRawResource</span><span style="color: #009900;">&#40;</span>R.<span style="color: #006633;">raw</span>.<span style="color: #006633;">version</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #003399;">Properties</span> properties <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Properties</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            properties.<span style="color: #006633;">load</span><span style="color: #009900;">&#40;</span>rawResource<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">return</span> properties.<span style="color: #006633;">getProperty</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;changeset&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            Log.<span style="color: #006633;">e</span><span style="color: #009900;">&#40;</span>TAG, <span style="color: #0000ff;">&quot;Cannot load app version properties file&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<img src="http://feeds.feedburner.com/~r/twaddington/~4/HK_hhASFHvA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2011/07/update-hg-or-git-changest-during-android-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2011/07/update-hg-or-git-changest-during-android-build/</feedburner:origLink></item>
		<item>
		<title>OS X Lion Time Machine backup to Debian</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/ibG0KLX7Xdg/</link>
		<comments>http://www.tristanwaddington.com/2011/07/debian-time-machine-server-os-x-lion/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 05:53:25 +0000</pubDate>
		<dc:creator>tristan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[os x]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=1090</guid>
		<description><![CDATA[When OS X Lion was released I was eager to try out the updated FileVault and Time Machine features. Moving from an encrypted home directory to true full-disk encryption was a dream. I was also quite excited to find out if the new implementation of FileVault would work well with Time Machine. I&#8217;d previously set [...]]]></description>
			<content:encoded><![CDATA[<p>When OS X Lion was released I was eager to try out the updated FileVault and Time Machine features. Moving from an encrypted home directory to true full-disk encryption was a dream. I was also quite excited to find out if the new implementation of FileVault would work well with Time Machine.</p>
<p>I&#8217;d previously set up a Time Machine volume on my Debian file-server by <a href="http://www.kremalicious.com/2008/06/ubuntu-as-mac-file-server-and-time-machine-volume/">installing netatalk and avahi</a>.</p>
<p>Unfortunately, it seems OS 10.7 (Lion) requires netatalk 2.2, which is currently in beta. However, it&#8217;s quite simple to install the beta version of the package and it seems to run just fine.</p>
<p>To install netatalk 2.2~beta4-1 you&#8217;ll need to add the following line to your <code>/etc/apt/sources.list</code> file:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">deb http:<span style="color: #000000; font-weight: bold;">//</span>debian.oregonstate.edu<span style="color: #000000; font-weight: bold;">/</span>debian sid main</pre></div></div>

<p>You can also use any of the <a href="http://packages.debian.org/sid/amd64/netatalk/download">mirrors listed here</a> if they&#8217;re closer.</p>
<p>Then run the following commands to install or upgrade netatalk:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> update
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> netatalk</pre></div></div>

<p>If you had a previous install of netatalk it may detect changes to your local configuration files. By default the installer will keep the local copies of your files. This behavior is fine in this case.</p>
<p>After the install has finished run <code>$ dpkg -s netatalk | grep -i version</code> to ensure it was successful.</p>
<p>The netatalk service will be restarted by the installer after it completes. You may need to give it a few seconds to spin back up before trying to connect to it.</p>
<p>Your Time Machine backups in OS X Lion should now work correctly!</p>
<p>At this point you may want to comment out or remove the line you added to <code>/etc/apt/sources.list</code> so that you don&#8217;t inadvertently upgrade other packages to an unstable branch. After removing the line simply run <code>$ sudo apt-get update</code> one more time.</p>
<p><strong>Update:</strong> Found the <a href="http://netatalk.sourceforge.net/2.2/htmldocs/configuration.html">official Netatalk documentation</a>.</p>
<p><strong>Update 2:</strong> Here is the contents of both my <code>afpd.conf</code> and <code>AppleVolumes.default</code> files.</p>
<p><script src="https://gist.github.com/1098759.js?file=AppleVolumes.default"></script></p>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/ibG0KLX7Xdg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2011/07/debian-time-machine-server-os-x-lion/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2011/07/debian-time-machine-server-os-x-lion/</feedburner:origLink></item>
		<item>
		<title>Android app build automation with Hudson</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/4ZftxjDuvIE/</link>
		<comments>http://www.tristanwaddington.com/2011/06/automated-android-builds-with-jenkins/#comments</comments>
		<pubDate>Fri, 24 Jun 2011 06:46:27 +0000</pubDate>
		<dc:creator>tristan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jenkins]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=1053</guid>
		<description><![CDATA[In a nutshell, Jenkins provides an easy-to-use so-called continuous integration system, making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build. This post assumes you have a working ci server running Hudson (or Jenkins). First download and install the Android SDK to your [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
In a nutshell, Jenkins provides an easy-to-use so-called continuous integration system, making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build.
</p></blockquote>
<p>This post assumes you have a working <abbr title="continuous integration">ci</abbr> server running <a href="http://hudson-ci.org/">Hudson</a> (or <a href="http://jenkins-ci.org/">Jenkins</a>).</p>
<p>First download and install the <a href="http://developer.android.com/sdk/index.html">Android SDK</a> to your Hudson server. Make sure it&#8217;s in a directory that&#8217;s accessible by your Hudson user.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">su</span> hudson
$ <span style="color: #7a0874; font-weight: bold;">cd</span> ~<span style="color: #000000; font-weight: bold;">/</span>
$ curl <span style="color: #660033;">-lO</span> http:<span style="color: #000000; font-weight: bold;">//</span>dl.google.com<span style="color: #000000; font-weight: bold;">/</span>android<span style="color: #000000; font-weight: bold;">/</span>android-sdk_r11-mac_x86.zip
$ <span style="color: #c20cb9; font-weight: bold;">unzip</span> android-sdk_r11-mac_x86.zip</pre></div></div>

<p>After unpacking the SDK you&#8217;ll need to install the individual Android platforms.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> android-sdk-mac_x86<span style="color: #000000; font-weight: bold;">/</span>
$ android update sdk <span style="color: #660033;">--no-ui</span></pre></div></div>

<p>Now go get some coffee or take a smoke break, this is going to take a while.</p>
<p>Phew. Okay, now that&#8217;s done we can configure our new Hudson task. I&#8217;m going to assume you&#8217;re somewhat familiar with boot strapping a new project in Hudson, so I&#8217;m going to gloss over some of the details. Just make sure it&#8217;s pointed at your Android app&#8217;s source code repository.</p>
<p>In the build section of the project config you&#8217;ll want to specify a new &#8220;Execute Shell&#8221; build step with the following script.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Ensure the SDK is in the Hudson user's system path</span>
<span style="color: #007800;">PATH</span>=<span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>hudson<span style="color: #000000; font-weight: bold;">/</span>android-sdk-mac_x86<span style="color: #000000; font-weight: bold;">/</span>tools<span style="color: #000000; font-weight: bold;">/</span>:<span style="color: #007800;">$PATH</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Change to the Hudson workspace directory</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$WORKSPACE</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Create the required build files in the workspace</span>
android <span style="color: #660033;">--verbose</span> update project <span style="color: #660033;">--path</span> .
&nbsp;
<span style="color: #666666; font-style: italic;"># Execute the build</span>
ant clean debug
&nbsp;
<span style="color: #666666; font-style: italic;"># Copy the apk out of the workspace so your testers can get at your fresh build</span>
<span style="color: #c20cb9; font-weight: bold;">scp</span> bin<span style="color: #000000; font-weight: bold;">/</span>YourAppName-debug.apk foo:bar<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p><b>Pro Tip:</b> Add this build script to your code repository and simply execute that script from Hudson. That way you can track your changes.</p>
<p>Note that if you&#8217;ve bundled extra libraries into your app you may see a build error when running this code. If so, try executing the ant build with the <code>-lib</code> option like so.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ ant clean debug <span style="color: #660033;">-lib</span> foo<span style="color: #000000; font-weight: bold;">/</span>bar<span style="color: #000000; font-weight: bold;">/</span>libdir<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>If you get into trouble, know that you can execute this build from the console as the Hudson user. Try running through the script manually first so you can identify any errors.</p>
<p><b>Update (2012-02-01):</b> After living with this set up for a few months we started to run into some issues. It turns out, running your Ant builds from a shell script means Jenkins won&#8217;t always notice that your builds are failing. We also started running JUnit tests that, when a test failed, did not also trigger a build failure.</p>
<p>As a result we discovered that it was far better to run your Android builds using the Jenkin&#8217;s <a href="https://wiki.jenkins-ci.org/display/JENKINS/Ant+Plugin">Ant Plugin</a>. This allows you to invoke a series of Ant commands like <code>clean debug</code> or <code>clean release</code>. Jenkins will also format the Ant output and properly mark your build as failed or successful.</p>
<p>You can also take advantage of the <a href="http://wiki.hudson-ci.org/display/HUDSON/Post+build+task">Post Build Task plugin</a> to run a script after your build is successful. This is useful for copying your <code>.apk</code> files elsewhere.</p>
<p>Don&#8217;t forget to run <code>$ android update project --path .</code> before your Ant commands are invoked, or your Android SDK folder may not be properly linked to your project.</p>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/4ZftxjDuvIE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2011/06/automated-android-builds-with-jenkins/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2011/06/automated-android-builds-with-jenkins/</feedburner:origLink></item>
		<item>
		<title>Localized Javascript countdown</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/opFvwtSTgOs/</link>
		<comments>http://www.tristanwaddington.com/2011/06/localized-javascript-countdown/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 07:25:08 +0000</pubDate>
		<dc:creator>tristan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[timezone]]></category>
		<category><![CDATA[utc]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=1031</guid>
		<description><![CDATA[These days many websites use a simple Javascript countdown clock to help promote the launch of a new service. Because many web applications are international, it&#8217;s important to ensure that your countdown is localized for all visitors. Let me give you an example. Say you&#8217;re in Portland, OR and you&#8217;re launching a new web app [...]]]></description>
			<content:encoded><![CDATA[<p>These days many websites use a simple Javascript countdown clock to help promote the launch of a new service. Because many web applications are international, it&#8217;s important to ensure that your countdown is localized for all visitors.</p>
<p>Let me give you an example. Say you&#8217;re in Portland, OR and you&#8217;re launching a new web app on April 27, 2011 at 5:00 p.m. PST. Not only are you launching a new web service, but you&#8217;re also coordinating an iOS and an Android app launch. So it&#8217;s important to be precise. You want to ensure your Hong Kong visitors don&#8217;t expect your product to be launching at 5:00 p.m. <abbr title="Hong Kong Time">HKT</abbr>. Instead, you want them to know that your product is actually launching at April 28, 2011 at 8 a.m. local time. </p>
<p>One good way to do this is using the <code>Date.UTC</code> Javascript method.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Get the current local time</span>
<span style="color: #003366; font-weight: bold;">var</span> now <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Get the localized end date for your countdown</span>
<span style="color: #003366; font-weight: bold;">var</span> end <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>Date.<span style="color: #660066;">UTC</span><span style="color: #009900;">&#40;</span>
    <span style="color: #CC0000;">2037</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// Year</span>
    <span style="color: #CC0000;">3</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>  <span style="color: #006600; font-style: italic;">// Month (0 is January, so 3 minus 1 is 2, which is March)</span>
    <span style="color: #CC0000;">31</span><span style="color: #339933;">,</span>   <span style="color: #006600; font-style: italic;">// Day</span>
    <span style="color: #CC0000;">19</span><span style="color: #339933;">,</span>   <span style="color: #006600; font-style: italic;">// Hour</span>
    <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>    <span style="color: #006600; font-style: italic;">// Minutes</span>
    <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>    <span style="color: #006600; font-style: italic;">// Seconds</span>
    <span style="color: #CC0000;">0</span>     <span style="color: #006600; font-style: italic;">// Milliseconds</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Toggle countdown</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>now <span style="color: #339933;">&lt;</span> end<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Show countdown</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>now <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; &lt; &quot;</span> <span style="color: #339933;">+</span> end<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Yay! We launched!</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Launch day!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>If you run the script above, you&#8217;ll notice that while <code>now</code> is always increasing, <code>end</code> should stay constant. The only reason the value of <code>end</code> should change is if you change your computer&#8217;s local timezone.</p>
<p>You can now take these variables and pass them into a nice Javascript countdown script. I&#8217;ve used Keith Wood&#8217;s <a href="http://keith-wood.name/countdown.html">jquery.countdown.js</a> jQuery plugin in the past, but I leave that decision up to you.</p>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/opFvwtSTgOs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2011/06/localized-javascript-countdown/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2011/06/localized-javascript-countdown/</feedburner:origLink></item>
		<item>
		<title>T.J. Porte Precision Edge</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/0BR4o0HQb5Y/</link>
		<comments>http://www.tristanwaddington.com/2011/05/tj-porte-precision-edge/#comments</comments>
		<pubDate>Mon, 16 May 2011 05:21:46 +0000</pubDate>
		<dc:creator>tristan</dc:creator>
				<category><![CDATA[Portfolio]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=1040</guid>
		<description><![CDATA[A custom theme built on Drupal 6 and Ubercart.]]></description>
			<content:encoded><![CDATA[<p>A custom theme built on Drupal 6 and Ubercart.</p>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/0BR4o0HQb5Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2011/05/tj-porte-precision-edge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2011/05/tj-porte-precision-edge/</feedburner:origLink></item>
		<item>
		<title>Multiple Base Templates in Django</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/znLvfa3FEaw/</link>
		<comments>http://www.tristanwaddington.com/2010/12/django-templates-conditional-extends/#comments</comments>
		<pubDate>Sun, 19 Dec 2010 01:30:19 +0000</pubDate>
		<dc:creator>tristan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=1005</guid>
		<description><![CDATA[I&#8217;ve been working on a pretty big project at work that&#8217;s heavily oriented towards mobile devices. We have a Django site running with a lot of custom ecommerce code, but wanted to serve up an optimized experience for mobile devices. There are a lot of ways to do this, but ultimately we wanted to serve [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a pretty big project at work that&#8217;s heavily oriented towards mobile devices. We have a Django site running with a lot of custom ecommerce code, but wanted to serve up an optimized experience for mobile devices.</p>
<p>There are a lot of ways to do this, but ultimately we wanted to serve up a different base template for visitors on small-screen mobile devices. We wrote a piece custom view middleware that sets <code>request['is_mobile'] = True</code>. Unfortunately, Django currently requires any <code>{% extends %}</code> template tag to be the first tag in your template. This means you can&#8217;t do something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">{% if request.is_mobile %}
    {% extends 'mobile_base.html' %}
{% else %}
    {% extends 'default_base.html' %}
{% endif %}</pre></div></div>

<p>After racking my brain all day my coworker suggested trying the <a href="http://docs.djangoproject.com/en/1.2/ref/templates/builtins/#yesno"><code>yesno</code></a> template filter. It worked like a charm!</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">{% extends request.is_mobile|yesno:&quot;mobile_base.html,default_base.html&quot; %}</pre></div></div>

<p>So in our view templates we now do <code>{% extends 'base.html' %}</code> which then loads the proper base template depending on the status of <code>is_mobile</code>.</p>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/znLvfa3FEaw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2010/12/django-templates-conditional-extends/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2010/12/django-templates-conditional-extends/</feedburner:origLink></item>
		<item>
		<title>Simple clock using standard Javascript</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/-1r2XAAIJcE/</link>
		<comments>http://www.tristanwaddington.com/2010/08/javascript-clock/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 03:06:18 +0000</pubDate>
		<dc:creator>Tristan Waddington</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=993</guid>
		<description><![CDATA[Ah the challenge for making your first clock in Javascript, I remember those days. It seems like such a daunting task at first, but it&#8217;s really quite simple. This code creates a fully functional clock using only Javascript and HTML. I&#8217;ve only checked it in Firefox and Chrome, but it&#8217;s simple enough it should work [...]]]></description>
			<content:encoded><![CDATA[<p>Ah the challenge for making your first clock in Javascript, I remember those days. It seems like such a daunting task at first, but it&#8217;s really quite simple.<span id="more-993"></span></p>
<p>This code creates a fully functional clock using only Javascript and HTML. I&#8217;ve only checked it in Firefox and Chrome, but it&#8217;s simple enough it should work in most major browsers. It will output the hours, minutes and seconds in a 24-hour time format.</p>
<p>Try challenging yourself and modifying the code to output a 12-hour clock with AM/PM instead.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;The Time&lt;/title&gt;
        <span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
            <span style="color: #006600; font-style: italic;">// This function gets the current time and injects it into the DOM</span>
            <span style="color: #003366; font-weight: bold;">function</span> updateClock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #006600; font-style: italic;">// Gets the current time</span>
                <span style="color: #003366; font-weight: bold;">var</span> now <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #006600; font-style: italic;">// Get the hours, minutes and seconds from the current time</span>
                <span style="color: #003366; font-weight: bold;">var</span> hours <span style="color: #339933;">=</span> now.<span style="color: #660066;">getHours</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #003366; font-weight: bold;">var</span> minutes <span style="color: #339933;">=</span> now.<span style="color: #660066;">getMinutes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #003366; font-weight: bold;">var</span> seconds <span style="color: #339933;">=</span> now.<span style="color: #660066;">getSeconds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #006600; font-style: italic;">// Format hours, minutes and seconds</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>hours <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    hours <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;0&quot;</span> <span style="color: #339933;">+</span> hours<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>minutes <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    minutes <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;0&quot;</span> <span style="color: #339933;">+</span> minutes<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>seconds <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    seconds <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;0&quot;</span> <span style="color: #339933;">+</span> seconds<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
                <span style="color: #006600; font-style: italic;">// Gets the element we want to inject the clock into</span>
                <span style="color: #003366; font-weight: bold;">var</span> elem <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'clock'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #006600; font-style: italic;">// Sets the elements inner HTML value to our clock data</span>
                elem.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> hours <span style="color: #339933;">+</span> <span style="color: #3366CC;">':'</span> <span style="color: #339933;">+</span> minutes <span style="color: #339933;">+</span> <span style="color: #3366CC;">':'</span> <span style="color: #339933;">+</span> seconds<span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
    &lt;/head&gt;
    &lt;!--
        This is the key to making the clock function.
        When the page loads, it calls the javascript function &quot;setInterval()&quot;,
        which will call our function &quot;updateClock()&quot; once every 200 milliseconds.
    --&gt;
    &lt;body onload=&quot;setInterval('updateClock()', 200);&quot;&gt;
        &lt;!-- This is the container for our clock, it can be any HTML element. --&gt;
        &lt;h1 id=&quot;clock&quot;&gt;&lt;/h1&gt;
    &lt;/body&gt;
&lt;/html&gt;</pre></div></div>

<img src="http://feeds.feedburner.com/~r/twaddington/~4/-1r2XAAIJcE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2010/08/javascript-clock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2010/08/javascript-clock/</feedburner:origLink></item>
		<item>
		<title>Detecting mobile devices with Javascript</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/oPiB5v1hyKc/</link>
		<comments>http://www.tristanwaddington.com/2010/06/detecting-mobile-devices-with-javascript/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 02:49:19 +0000</pubDate>
		<dc:creator>Tristan Waddington</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=978</guid>
		<description><![CDATA[Today at work we were struggling with a way to detect the iPad and similar devices without relying on the browser user agent string. We ended up checking the value of window.onorientationchange like so: function is_mobile_device&#40;&#41; &#123; if &#40;typeof window.onorientationchange != &#34;undefined&#34;&#41; &#123; return true; &#125; else &#123; return false; &#125; &#125; This function will [...]]]></description>
			<content:encoded><![CDATA[<p>Today at work we were struggling with a way to detect the iPad and similar devices without relying on the browser user agent string.</p>
<p>We ended up checking the value of <code>window.onorientationchange</code> like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> is_mobile_device<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> window.<span style="color: #660066;">onorientationchange</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;undefined&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This function will return false in all current desktop browsers because <code>typeof window.onorientationchange</code> is &#8220;undefined.&#8221; On the iPad and other mobile devices it will return a type of &#8220;object.&#8221;</p>
<p>What other ways are you using to detect mobile devices?</p>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/oPiB5v1hyKc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2010/06/detecting-mobile-devices-with-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2010/06/detecting-mobile-devices-with-javascript/</feedburner:origLink></item>
		<item>
		<title>Mount your ntfs drive on boot in Ubuntu</title>
		<link>http://feedproxy.google.com/~r/twaddington/~3/WPhPhdlvWgI/</link>
		<comments>http://www.tristanwaddington.com/2010/06/mount-your-ntfs-drive-on-boot-in-ubuntu/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 18:11:56 +0000</pubDate>
		<dc:creator>Tristan Waddington</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.tristanwaddington.com/?p=972</guid>
		<description><![CDATA[So you&#8217;ve got an NTFS drive you want mounted when your Ubuntu machine boots? Time to pull up your favorite editor and modify /etc/fstab. This is what I ended up with: /dev/mapper/sil_aiaiahddacai1 /media/Storage ntfs-3g defaults,gid=1000,uid=1000,locale=en_US.UTF-8 0 0 Replace the gid and uid values with the ids of your group and user. Run id to get [...]]]></description>
			<content:encoded><![CDATA[<p>So you&#8217;ve got an NTFS drive you want mounted when your Ubuntu machine boots? Time to pull up your favorite editor and modify <code>/etc/fstab</code>.</p>
<p>This is what I ended up with:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>mapper<span style="color: #000000; font-weight: bold;">/</span>sil_aiaiahddacai1 <span style="color: #000000; font-weight: bold;">/</span>media<span style="color: #000000; font-weight: bold;">/</span>Storage ntfs-3g defaults,<span style="color: #007800;">gid</span>=<span style="color: #000000;">1000</span>,<span style="color: #007800;">uid</span>=<span style="color: #000000;">1000</span>,<span style="color: #007800;">locale</span>=en_US.UTF-<span style="color: #000000;">8</span> <span style="color: #000000;">0</span> <span style="color: #000000;">0</span></pre></div></div>

<p>Replace the <code>gid</code> and <code>uid</code> values with the ids of your group and user. Run <code>id</code> to get these values.</p>
<p>I also had to make sure I created the mount point, otherwise it would fail:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>media<span style="color: #000000; font-weight: bold;">/</span>Storage</pre></div></div>

<p>Anything I&#8217;m missing? So far it seems to work just fine.</p>
<img src="http://feeds.feedburner.com/~r/twaddington/~4/WPhPhdlvWgI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tristanwaddington.com/2010/06/mount-your-ntfs-drive-on-boot-in-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tristanwaddington.com/2010/06/mount-your-ntfs-drive-on-boot-in-ubuntu/</feedburner:origLink></item>
	</channel>
</rss>

