<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5819005</id><updated>2012-01-19T03:38:57.895-08:00</updated><category term='espn'/><category term='heisman'/><category term='arcadefire'/><category term='turntable'/><category term='scheduleworld'/><category term='flash'/><category term='stax'/><category term='multitasking'/><category term='riaa'/><category term='derby'/><category term='software update'/><category term='soa'/><category term='phoenix suns'/><category term='silicon valley'/><category term='adobe'/><category term='sabermetrics'/><category term='algorithms'/><category term='galaxytab'/><category term='80211.n'/><category term='belichick'/><category term='cocoa'/><category term='picasa'/><category term='imovie'/><category term='hail'/><category term='make'/><category term='mouse'/><category term='taxes'/><category term='spaz'/><category term='vampire weekend'/><category term='mediastore'/><category term='javap'/><category term='ilike'/><category term='email'/><category term='digital photography'/><category term='myspace'/><category term='java 1.6'/><category term='c++'/><category term='closures'/><category term='fbml'/><category term='opera'/><category term='rant'/><category term='fraud'/><category term='facebook'/><category term='baseball'/><category term='american idol'/><category term='java'/><category term='svjug'/><category term='wifi'/><category term='javaee5'/><category term='birthday cake'/><category term='airlines'/><category term='elbow'/><category term='ical'/><category term='acm'/><category term='&quot;dwight howard&quot;'/><category term='the hulk'/><category term='government'/><category term='halfmeet'/><category term='concurrency'/><category term='clinton'/><category term='networking'/><category term='open social'/><category term='targus'/><category term='mvc'/><category term='vouchers'/><category term='j2me'/><category term='keynes'/><category term='barbaro'/><category term='gencon'/><category term='iphoto'/><category term='college football'/><category term='groovy'/><category term='proflowers'/><category term='flickr'/><category term='seatguru'/><category term='mac'/><category term='puzzles'/><category term='outlook2007'/><category term='informit'/><category term='unit testing'/><category term='radiohead'/><category term='vibrant'/><category term='microsft'/><category term='california'/><category term='liftweb'/><category term='blogging'/><category term='colt brennan'/><category term='extjs'/><category term='duck typing'/><category term='json'/><category term='tennis'/><category term='svn'/><category term='google'/><category term='49ers'/><category term='ruby'/><category term='silly'/><category term='priceline'/><category term='puremvc'/><category term='technology'/><category term='resolutions'/><category term='last fm'/><category term='r.e.m.'/><category term='kobe bryant'/><category term='ecto'/><category term='neon bible'/><category term='red hat'/><category term='web applications'/><category term='spring mvc'/><category term='dynamic programming'/><category term='websockets'/><category term='benchmarks'/><category term='osx'/><category term='censorship'/><category term='sync'/><category term='creativity'/><category term='rosetta'/><category term='ludi labs'/><category term='m.i.a.'/><category term='guice'/><category term='hayek'/><category term='frameworks'/><category term='michael lewis'/><category term='ios'/><category term='dumb'/><category term='pdt'/><category term='mix'/><category term='tuning'/><category term='laszlo'/><category term='ajaxworld'/><category term='cycling'/><category term='oakland a&apos;s'/><category term='horse racing'/><category term='jit'/><category term='entrepreneurs'/><category term='touch'/><category term='automator'/><category term='crimereports'/><category term='playoofs'/><category term='jsonp'/><category term='hack'/><category term='del.icio.us'/><category term='user experience'/><category term='extensions'/><category term='nlcs'/><category term='gdb'/><category term='jug'/><category term='cookies'/><category term='geronimo'/><category term='silverlight'/><category term='macbook pro'/><category term='woodstox'/><category term='howto'/><category term='comcast'/><category term='maker faire'/><category term='parepin'/><category term='bailout'/><category term='music'/><category term='scriptaculous'/><category term='desktop applications'/><category term='widgets'/><category term='netbeans'/><category term='builder'/><category term='acid2'/><category term='wsrequest'/><category term='cdt'/><category term='sql'/><category term='ipod'/><category term='webos'/><category term='twitter'/><category term='nexus one'/><category term='javaee'/><category term='jvmone'/><category term='virus'/><category term='mathematics'/><category term='ron paul'/><category term='citibank'/><category term='collegefootball'/><category term='neal gafter'/><category term='jruby'/><category term='sec'/><category term='simpledb'/><category term='jessica mah'/><category term='writing'/><category term='gmail'/><category term='mobile'/><category term='guitar hero'/><category term='commute'/><category term='spotify'/><category term='mitchell report'/><category term='federal reserve'/><category term='a-rod'/><category term='john mccain'/><category term='funny'/><category term='swc'/><category term='billy beane'/><category term='html5'/><category term='clojure'/><category term='slotted classes'/><category term='80211.g'/><category term='junit'/><category term='firebug'/><category term='ows'/><category term='lunch20'/><category term='gasoline'/><category term='lotto'/><category term='jfx'/><category term='wtf'/><category term='libertarianism'/><category term='freedom'/><category term='xmlhttprequest'/><category term='biking'/><category term='grails'/><category term='bose'/><category term='css'/><category term='uncov'/><category term='the black keys'/><category term='caltrain'/><category term='john elway'/><category term='e4x'/><category term='ilife'/><category term='a950'/><category term='bon iver'/><category term='sun'/><category term='denver broncos'/><category term='.net'/><category term='tea party'/><category term='pop culture'/><category term='performance'/><category term='review'/><category term='front row'/><category term='amy winehouse'/><category term='ie9'/><category term='alex rodriguez'/><category term='safari'/><category term='xml'/><category term='max08'/><category term='fireworks'/><category term='scala'/><category term='human race'/><category term='google maps'/><category term='mysql'/><category term='kaazing'/><category term='10K'/><category term='iraq war'/><category term='economy'/><category term='pigeonhole principle'/><category term='greenspan'/><category term='projecteuler'/><category term='march madness'/><category term='textmate'/><category term='feist'/><category term='intellij'/><category term='foreclosure'/><category term='all-star'/><category term='ie8'/><category term='dwr'/><category term='webdevelopment'/><category term='android'/><category term='eclipseworld'/><category term='iron and wine'/><category term='icefaces'/><category term='xcode'/><category term='gxt'/><category term='paulgraham'/><category term='mtom'/><category term='mike martz'/><category term='intel'/><category term='jpa'/><category term='lebron james'/><category term='fantasy sports'/><category term='software'/><category term='aspect oriented programming'/><category term='halfmarathon'/><category term='ie7'/><category term='memcached'/><category term='ria'/><category term='scam'/><category term='chess'/><category term='fbjs'/><category term='wnr2000'/><category term='pre'/><category term='itunes'/><category term='wso2'/><category term='prototype'/><category term='mike singletary'/><category term='samsung galaxy s'/><category term='weatherm sanjose'/><category term='cy young'/><category term='r2-d2'/><category term='google app engine'/><category term='yahoo'/><category term='corelib'/><category term='republicans'/><category term='design patterns'/><category term='javascript'/><category term='siliconvalley'/><category term='san francisco 49ers'/><category term='jira'/><category term='web development'/><category term='ozzieguillen'/><category term='youtube'/><category term='local search'/><category term='gorm'/><category term='http'/><category term='nlds'/><category term='jsonviewer'/><category term='steve kerr'/><category term='pixar'/><category term='new england patriots'/><category term='8830'/><category term='Marc Andreessen'/><category term='car insurance'/><category term='nfl'/><category term='basbeall'/><category term='pelosi'/><category term='developers'/><category term='mega millions'/><category term='metrics'/><category term='crime'/><category term='amazon'/><category term='ning'/><category term='aspects'/><category term='tail recursion'/><category term='windows'/><category term='french open'/><category term='mint'/><category term='football'/><category term='swt eclipse'/><category term='google calendar'/><category term='san francisco giants'/><category term='computer science'/><category term='googlebot'/><category term='nano'/><category term='php'/><category term='tss'/><category term='random'/><category term='wwdc'/><category term='metaprogramming'/><category term='Florida Gators'/><category term='caltech'/><category term='oop'/><category term='flash 10'/><category term='sanjose'/><category term='pickle'/><category term='rdio'/><category term='black friday'/><category term='comet'/><category term='bluetooth'/><category term='oodle'/><category term='economics'/><category term='red sox'/><category term='blogger'/><category term='running'/><category term='randy moss'/><category term='web2.0'/><category term='radrails'/><category term='generics'/><category term='funambol'/><category term='travelers insurance'/><category term='history'/><category term='referrer'/><category term='mozilla'/><category term='eclipseday'/><category term='monkey patching'/><category term='photostory'/><category term='whotesox'/><category term='qc3'/><category term='bcs'/><category term='google+'/><category term='white rabbits'/><category term='s3'/><category term='sms'/><category term='alds'/><category term='movies'/><category term='books'/><category term='development'/><category term='death'/><category term='election2006'/><category term='shopping'/><category term='office2007'/><category term='jigloo'/><category term='api'/><category term='jdk1.6'/><category term='mustang'/><category term='vonage'/><category term='logitech'/><category term='honeycomb'/><category term='war'/><category term='chrome'/><category term='objective-c'/><category term='san jose'/><category term='pecs'/><category term='TDD'/><category term='spam'/><category term='rails'/><category term='rss'/><category term='xss'/><category term='actionscript'/><category term='flashcamp'/><category term='mlb'/><category term='blackkeys'/><category term='2008'/><category term='feith'/><category term='linq'/><category term='flashtracer'/><category term='seam'/><category term='java puzzlers'/><category term='miami dolphins'/><category term='nfc'/><category term='nick saban'/><category term='web beans'/><category term='aop'/><category term='online video'/><category term='techcrunch'/><category term='bump'/><category term='memory'/><category term='ibook'/><category term='developerworks'/><category term='lift'/><category term='harvard'/><category term='nine inch nails'/><category term='rest'/><category term='election2008'/><category term='obama'/><category term='sabremetrics'/><category term='parallels'/><category term='problems'/><category term='barack obama'/><category term='drm'/><category term='holidays'/><category term='ringtones'/><category term='worm'/><category term='face recognition'/><category term='2006'/><category term='nexus s'/><category term='nin'/><category term='fast app switching'/><category term='mcgwire'/><category term='hotspot'/><category term='brett favre'/><category term='subversion'/><category term='windows vista'/><category term='tychay'/><category term='popfly'/><category term='greatwallofchina'/><category term='fallacies'/><category term='f8'/><category term='education'/><category term='activerecord'/><category term='sandimas'/><category term='msdn'/><category term='reflection'/><category term='dom'/><category term='headers'/><category term='0-guard'/><category term='hillary clinton'/><category term='bsod'/><category term='actors'/><category term='ebay'/><category term='xforms'/><category term='sony'/><category term='bill simmons'/><category term='circuit city'/><category term='paulson'/><category term='steroids'/><category term='joshua bloch'/><category term='a&apos;s'/><category term='tomcat'/><category term='advertising'/><category term='cyclomatic complexity'/><category term='flock'/><category term='wsdl'/><category term='year zero'/><category term='rental cars'/><category term='xul'/><category term='dunk'/><category term='mvp'/><category term='ganymede'/><category term='fantasy baseball'/><category term='excel'/><category term='webkit'/><category term='leopard'/><category term='weak dollar'/><category term='macbook'/><category term='yale'/><category term='test driven development'/><category term='final four'/><category term='effective java'/><category term='apollo'/><category term='axis2'/><category term='yankees'/><category term='usability'/><category term='hardware'/><category term='9/11'/><category term='math'/><category term='wall e'/><category term='new york times'/><category term='air'/><category term='scala. programming'/><category term='george w. bush'/><category term='cell phone'/><category term='dom4j'/><category term='alcs'/><category term='verizon'/><category term='ripoff'/><category term='hof'/><category term='google gears'/><category term='dashboard'/><category term='katrina'/><category term='battlestar galactica'/><category term='great depression'/><category term='gae'/><category term='ie'/><category term='cold war kids'/><category term='eric chavez'/><category term='gps'/><category term='arcade fire'/><category term='seo'/><category term='moveon'/><category term='ruby on rails'/><category term='blackberry'/><category term='paypal'/><category term='jcip'/><category term='fan'/><category term='nike'/><category term='gumbo'/><category term='battery life'/><category term='spanking'/><category term='netbook'/><category term='manny ramirez'/><category term='slideshow'/><category term='mobile web'/><category term='playoffs'/><category term='krugle'/><category term='numbers'/><category term='occupy wall street'/><category term='tim tebow'/><category term='mp3cd'/><category term='joost'/><category term='interest rates'/><category term='tetris'/><category term='jrockit'/><category term='xaml'/><category term='coldplay'/><category term='moneyball'/><category term='mixbook'/><category term='basketball'/><category term='finanace'/><category term='swing'/><category term='contentprovider'/><category term='recruiting'/><category term='iron man'/><category term='sfgiants'/><category term='unbounded knapsack problem'/><category term='windows phone 7'/><category term='delta airlines'/><category term='gwt'/><category term='word'/><category term='diophantine equation'/><category term='open source'/><category term='captivate'/><category term='raconteurs'/><category term='nationalization'/><category term='dvd'/><category term='db2'/><category term='java5'/><category term='quality assurance'/><category term='c#'/><category term='prop8'/><category term='firefox'/><category term='google docs'/><category term='iphone'/><category term='travel'/><category term='netflix'/><category term='tips'/><category term='spring'/><category term='software engineering'/><category term='web service'/><category term='iraq'/><category term='nintendo'/><category term='sports'/><category term='servlet'/><category term='eclipse'/><category term='auto unboxing'/><category term='directwebremoting'/><category term='startups'/><category term='flexcamp'/><category term='socialism'/><category term='java7'/><category term='constitution'/><category term='business'/><category term='vampireweekend'/><category term='threads'/><category term='reviews'/><category term='ood'/><category term='scalability'/><category term='iwork'/><category term='logic'/><category term='rock'/><category term='san francisco'/><category term='security'/><category term='theserverside'/><category term='google web toolkit'/><category term='flex'/><category term='civil rights'/><category term='oracle'/><category term='barry bonds'/><category term='hiring'/><category term='visual studio'/><category term='jay cutler'/><category term='sarah palin'/><category term='geolocation'/><category term='tracemonkey'/><category term='democrats'/><category term='html'/><category term='base'/><category term='atom'/><category term='fun'/><category term='china'/><category term='big brown'/><category term='cross site scripting'/><category term='architecture'/><category term='plugins'/><category term='jython'/><category term='powerset'/><category term='vista'/><category term='ide'/><category term='hp'/><category term='capitalism'/><category term='interceptors'/><category term='yui'/><category term='c2dm'/><category term='java university'/><category term='wiki'/><category term='aggrogator'/><category term='cache'/><category term='metallica'/><category term='apple'/><category term='travelers'/><category term='im'/><category term='ipad'/><category term='backbase'/><category term='orlando magic'/><category term='sennheiser'/><category term='nba'/><category term='star wars'/><category term='war and decision'/><category term='rick ankiel'/><category term='macworld'/><category term='ibm'/><category term='agile'/><category term='unit test'/><category term='python'/><category term='v600'/><category term='javaone'/><category term='arid'/><category term='internet'/><category term='easysaver'/><category term='bea'/><category term='sharefare'/><category term='pocketmac'/><category term='upgrades'/><category term='database'/><category term='summize'/><category term='linux'/><category term='apache'/><category term='javafx'/><category term='code golf'/><category term='hibernate'/><category term='dependency injection'/><category term='recession'/><category term='mortgages'/><category term='office'/><category term='rackspace'/><category term='soap'/><category term='pages'/><category term='cygwin'/><category term='ajax'/><category term='politics'/><category term='programming'/><category term='meebo'/><category term='madden'/><category term='sliderocket'/><category term='wii'/><category term='jvm'/><category term='terrorism'/><category term='wall street'/><category term='best of'/><category term='mode'/><category term='intellij idea'/><category term='garbage collector'/><category term='world series'/><category term='percy harvin'/><category term='jobs'/><category term='desktop search'/><category term='super bowl'/><category term='auto boxing'/><category term='food'/><category term='college basketball'/><category term='languages'/><category term='giam'/><category term='orm'/><category term='functional programming'/><category term='sharedobject'/><category term='ebaydesktop'/><category term='jboss'/><category term='friedman'/><category term='google reader'/><category term='microsoft'/><category term='amd'/><category term='kanye west'/><category term='new york yankees'/><category term='google desktop'/><category term='fail'/><category term='collections'/><category term='g++'/><category term='atlanta braves'/><category term='coca'/><category term='aptana'/><category term='money'/><title type='text'>Programming and politics</title><subtitle type='html'>Mostly technical and political -- stuff to bore everyone.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default?start-index=101&amp;max-results=100'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>672</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5819005.post-2988136191397867253</id><published>2012-01-04T07:31:00.000-08:00</published><updated>2012-01-04T07:31:44.981-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Mobile Application Architecture, Part 3</title><content type='html'>[Note: So it's taken me a long time to get this third part out. I changed jobs in the middle of writing all of this, and there's a lot to learn at the new gig. Also in case you are wondering, this is heavily based on my experiences working on &lt;a href="https://market.android.com/details?id=com.ebay.mobile" target="_blank"&gt;eBay Mobile&lt;/a&gt; for Android and &lt;a href="https://market.android.com/details?id=com.bumptech.bumpga" target="_blank"&gt;Bump&lt;/a&gt; for Android. Both apps use an event driven architecture in places, or at least they did while I was working on them. What follows is not the secret sauce from either application, but some good things that were common to both along with some ideas for improving on the patterns.]&lt;br /&gt;&lt;br /&gt;This is the third post in a series on the architecture of mobile applications. In the &lt;a href="http://fupeg.blogspot.com/2011/12/mobile-application-architecture-part-1.html" target="_blank"&gt;first post&lt;/a&gt; we looked at the classical architecture of mobile apps that evolved from web apps. In the &lt;a href="http://fupeg.blogspot.com/2011/12/mobile-application-architecture-part-2.html" target="_blank"&gt;second post&lt;/a&gt; we looked at event driven architecture and when it should be used. Now we're going to dive a little deeper into event driven architectures and in particular talk about some of the significant design decisions that must be made and the pitfalls that need to be avoided.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So you say you want an event driven architecture? I'll assume you've done your homework and aren't just doing this to because it seems like the cool thing to do. I'll assume that it really fits your application. One of the first things that you will realize as you get started is that event driven architecture does not exempt you from many important aspects. Security is a great example. You must figure out how you will authenticate with your server and how to secure any sensitive information that you send over the wire. Just because you are no longer in the world of HTTP and HTTPS does not mean that you get to send over people's credit card numbers in plain text. It's not any harder to sniff your bits and chances are that you are just as vulnerable to things like man-in-the-middle attacks. So go read up on things like TCP headers and TLS.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once the basics are in place, you can think more about the architecture of your application. Your servers are going to be sending events to your application. So what is going to receive them? Do you have each UI (controller, Activity, etc.) receive them? How about something that is more long-lived. The most important thing to remember is that whatever receives events generally has to be able to deal with any kind of event. You can never assume that just because your controller only cares about some small set of events that those will be the only events that it ever receives. Thus you probably need to have an event receiver whose lifecyle extends beyond that of any given screen in your application and can handle any and all events. Now keep in mind that it will often delegate events to other components in your application, so no need to worry about this global receiver being stuffed with knowledge of your app. On Android you could use a Service for this or even a subclass of Application. You could also create some other singleton object that is tied to your application's lifecycle.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now you might ask does this really need to be a singleton? Not necessarily. However I think that in many (most?) circumstances that a singleton will simplify things for you. What happens to those events that are not needed by the UI? Such events probably mutate some internal state of your application. If that internal state is transient, then it probably makes sense for there to be only one copy of it. If it is persistent...&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Inevitably there will be some events coming in from your server that you do care about at the UI level. These things will probably be "second-hand", i.e. the events will have been received by the longer-lived object we talked about above. Now you need to deal with how to get these events to the UI. The most accepted way to do this is to use an &lt;a href="http://en.wikipedia.org/wiki/Observer_pattern" target="_blank"&gt;Observer pattern&lt;/a&gt;. You define an interface for an object that cares about a certain event (or certain set of related events potentially.) Then the object registers itself with the central receiver. When a new event comes in from the server, the central receiver examines it and decides on who to delegate it to.&lt;br /&gt;&lt;br /&gt;I must add a few words of caution here. For each event you can easily wind up with a class for the event's data structure, an interface for the observer, and an implementation of the observer. The last of these things is often handled by having the Activity/Fragment/controller implement the interface, or by using an anonymous inner class to implement it. In any case, you wind up with multiple types being defined for each event. So if you have many types of events that your server will push to your application then you can end up with an explosion of code. Android developers should consider using Handlers and Messages as a leaner, more de-coupled solution. The big downside is that you may windup doing manual type checking and casting. This can be avoided by late binding, i.e. keep the data from the server raw as long as possible and do the parsing after the dispatch to the observer.&lt;br /&gt;&lt;br /&gt;Finally I will close this long series of posts with a brief word about server side technologies. This post in particular has focussed on how to write your mobile/client applications with an event driven architecture. There is a flip-side to this and that is how to implement an event driven architecture on your server. Just like in our classical architectures, most servers are dominated by HTTP. That is not only the default interface into them, but it is at the heart of the server's architecture. A connection is a short-lived, usually stateless object. There is generally a one-to-one mapping of HTTP requests to either threads or processes. This is a poor fit for event driven architectures where a connection is extremely long lived. It only dies when the client app dies or explicitly closes it for some reason.&lt;br /&gt;&lt;br /&gt;Fortunately there are numerous server side technologies that do not use the request-per-thread/process model. Certainly the most hyped one of these is Node.js. The Internet is chock full of benchmarks showing how Node's non-blocking out-scales Apache, Nginx, etc. However there are numerous other event driven app servers in Python, Java, Ruby, etc. Personally I have a bias towards my ex-colleague Jamie Turner's &lt;a href="https://github.com/jamwt/diesel" target="_blank"&gt;Diesel&lt;/a&gt; framework. The point is that there are many choices on the server and I expect that you will see many more moving forward.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-2988136191397867253?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/2988136191397867253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=2988136191397867253' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2988136191397867253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2988136191397867253'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2012/01/mobile-application-architecture-part-3.html' title='Mobile Application Architecture, Part 3'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3207148664010653626</id><published>2011-12-11T08:47:00.001-08:00</published><updated>2011-12-11T09:18:21.178-08:00</updated><title type='text'>Yo ho, yo ho, a startup's life for me</title><content type='html'>&lt;img alt="Pirates" border="0" height="318" src="http://lh4.ggpht.com/-AUWirOKYYzk/TuTeVukBIEI/AAAAAAAACKw/G1VZ7F69hV8/Pirates.jpeg?imgmax=800" style="float: left;" title="Pirates.jpeg" width="400" /&gt;&lt;br /&gt;Friday was my last day at Bump Technologies. It's been a little shorter ride there than I expected, but still a very rewarding one. Before Bump I had been at eBay for four years, so you might think that going to a startup was a big change for me. Actually Bump was the sixth startup that I have worked at. Of the non-startups that I worked at was a very small consulting company that was much more like a startup than not. Still I'll leave the number at six. How have those startups fared?&lt;br /&gt;&lt;br /&gt;Two burned out pretty quickly. One of those never got more than angel money, while the other got an $8M series A that it burned through more rapidly than I can understand.&lt;br /&gt;&lt;br /&gt;One was bought by Oracle and is now part of their business intelligence suite.&lt;br /&gt;&lt;br /&gt;One turned profitable, but was shut down by its board because they no longer thought "hockey stick" growth was possible.&lt;br /&gt;&lt;br /&gt;One labored for many years on minimal funding before selling its intellectual property and going out of business.&lt;br /&gt;&lt;br /&gt;The other of course is Bump.&lt;br /&gt;&lt;br /&gt;[Note: While all of the following is based on my experiences in aggregate, I had no one specific in mind while writing this little rant. In particular my comments on 'modern' startups does not reflect Bump.]&lt;br /&gt;&lt;br /&gt;My first two startups were in 2000, almost twelve years ago and during the dot-com bubble. A lot has changed in that time. The capital needed for hardware has shrunk amazingly. Commodity hardware plus the rise of virtualized hosting a la Amazon web services, has led to a world where a startup's big spend is on engineering talent. The value placed on engineering is huge. Engineering is a scarce resource, as the supply of engineers is shrinking while the demand is rising. Further the notion of "10X engineers" is widely accepted, and this essentially lifts any kind of ceiling on the value of an engineer. Now as an engineer this is mostly a Very Good Thing, at least from my perspective. However there are some weird things that this leads to.&lt;br /&gt;&lt;br /&gt;The high value of engineering can make for a strange situation in companies with non-technical founders. Just imagine a situation where you have to work hard to get something and continuously spend a lot just to keep that something, and you don't really understand what that something does. That can be hard to swallow and keep down. Now multiply that times five or ten or twenty "somethings." Yeah.&lt;br /&gt;&lt;br /&gt;Of course startups have always loved young engineering talent fresh out of school. There has always been huge appeal in such engineers because they are very cheap and have much less of a life outside of work, so they are more likely to happily work the long hours necessary in a startup. With the value of engineering going up so much, the appeal of young engineers is much greater than it was twelve years ago. Go back and read the previous paragraph and consider that such an awkward situation can be avoided with younger engineers. The net result is you have "younger" startups in general where more is asked of young, inexperienced engineers. This can lead to some amazing opportunities for talented young engineers. It can also lead to Engineering Disasters like we've never seen before.&lt;br /&gt;&lt;br /&gt;Another interesting change in the world of startups is the value of design. I attribute most of this to the amazing success of Apple and the high value they place on design. Now in Apple's case, I would say they place a higher value on user experience and design follows from that, but more on that subtle difference momentarily. The value of design has obviously lead to a greater role for designers. They are more empowered than ever before to insist on certain aspects of a product. However the value of design has also lead to a lot of "armchair designers". Everyone thinks design is important, and design is the kind of thing that everyone can form an opinion on. Of course we all think that our opinion is very valuable, so we feel strongly about our opinions on design.&lt;br /&gt;&lt;br /&gt;Think about how often you hear somebody -- doesn't matter what their job is -- talk about how some website or app or whatever is awful or looks terrible or "broken." The bigger more popular the product is, the more likely it will illicit such responses. I hear developers constantly talking about how something is ugly or beautiful. Even better, I hear developers constantly talk about how most other developers don't care about design and that they are special because they do. It's hilarious.&lt;br /&gt;&lt;br /&gt;It's at least as bad if not worse among so called product people in startups. When I was working for my first couple of startups, our product managers were people with some kind of unique experience and thus theoretically some unique perspectives into what our customers would want. Not so much today. The qualifications for being a product person in a startup is pretty minimal as best as I can tell. That doesn't stop the from waxing poetic about the aesthetics of websites and apps.&lt;br /&gt;&lt;br /&gt;These product managers and developers may all think that they have a lot in common with Steve Jobs, but as I mentioned earlier, I think Apple's approach is a little different than the approach taken by most startups. I think Apple stresses user experience first and realize that this is not the same thing as product or design. In a startup people have to wear many hats, so a lot of these competing principles get rolled together into one product person who may have some dubious credentials.&lt;br /&gt;&lt;br /&gt;The worst sin of startup product people is not their strong opinions on what looks good or bad. It's a tendency to base product decisions on their personal preferences. They think that a product should be exactly what they would find most useful or most cool. Now this is not some new and unique thing. Product managers at startups ten years ago were guilty of this too, as are product manager at big companies today. It's just the circumstances of product managers at modern startups make this situation worse, as does the form-over-function corollary that comes from the emphasis on visual design. It's a perfect storm that leads to products being designed around users with a thousand Facebook friends and 5 tumblr blogs who spend more time at speakeasies than at Target. Of course that might really be your user, but it is statistically unlikely.&lt;br /&gt;&lt;br /&gt;I've probably said too much about the current state of startups. This is my blog though, so what about me? I seriously doubt that I'll stop at six startups, though of course I hope my current job lasts for a long time. Like so many other people working in Silicon Valley, I want to work on a product that can change the world. That's what has lead me to startups six times in my career. But startups aren't the only kind of companies that can change the world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3207148664010653626?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3207148664010653626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3207148664010653626' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3207148664010653626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3207148664010653626'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/12/yo-ho-yo-ho-startups-life-for-me.html' title='Yo ho, yo ho, a startup&apos;s life for me'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-AUWirOKYYzk/TuTeVukBIEI/AAAAAAAACKw/G1VZ7F69hV8/s72-c/Pirates.jpeg?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7212832616396239255</id><published>2011-12-08T17:47:00.000-08:00</published><updated>2011-12-08T17:48:01.361-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Mobile Application Architecture, Part 2</title><content type='html'>This is the second post about mobile architecture. In the first post, I talked about how the evolution from web applications has led to architecture's centered around asynchronous access to remote resources using HTTP. I also mentioned how Android applications are able to benefit from cloud-to-device messaging (C2DM) to push new data to apps. The most common use for this is for push notifications, but C2DM is not limited to push notifications. The key to pushing data via C2DM is that it uses a persistent socket connection to the C2DM servers. So whenever any new data is sent to those servers, they can send it over this connection to mobile apps. Now you might think that there is something magical or even worse, proprietary, about using sockets within a mobile application. This is not the case at all. Any application can make use of sockets, not just ones written by Google. Actually that's not true. Any native applications on iOS and Android can use sockets. Socket support was recently added to Windows Phone 7 as well. For web apps there is the Web Socket API, but it is not yet implemented across platforms.&lt;br /&gt;&lt;br /&gt;So what are the benefits of using sockets? Well there is the data-push capability that you see in C2DM. In general you can make a much faster app by using sockets. There is a lot of wasted time and overhead in making HTTP connections to a server. This wasted time and overhead gets multiplied by the number of HTTP calls used in your application. There is also overhead in creating a socket connection to a server, but you only pay it one time. The extra speed and server push-iness allows for very interactive apps. Sounds great, but how does this affect the application architecture? Here's an updated diagram.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Event driven architecture" border="0" height="438" src="http://lh3.ggpht.com/-7YWDecVp500/TuEjHAHdfVI/AAAAAAAACF4/D1BuFzsS9sY/mobile%252520app%252520arch2.png?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="mobile app arch2.png" width="442" /&gt;&lt;br /&gt;&lt;br /&gt;The big difference here is that instead of requests and corresponding responses, we have events being sent from client to server and back again. Now obviously some of these events may be logically correlated, but our communication mechanism no longer encodes this correlation. The "response" to an event from the app does not come immediately and may not be the next event from the server. Everything is asynchronous. Now in our traditional architecture we also had "asynchronous things" but it was different. Each request/response cycle could be shoved off on their own thread or in their own AsyncTask for example. This is a lot different.&lt;br /&gt;&lt;br /&gt;Let's take a simple example. One of the first things that many applications require a user to do is to login, i.e. send a combination of name and password and get some kind of authenticated materials in response (token). In a traditional architecture you would send a login request to the server, wait for the response, and then either get the token or display an error if there was a problem with the username+password combination. In an event driven architecture, your application fires a login event that contains the username+password. There is no response per se. Instead at some point in the future the server will fire an event indicating a successful login that includes a token, or an error that may contain a reason as well. You don't know when this will happen, and you may receive other events from the server before getting a "login response" event.&lt;br /&gt;&lt;br /&gt;Logging in is just one example. There are numerous other things that are easy to think of in terms of request/response. The whole idea of &lt;a href="http://en.wikipedia.org/wiki/Representational_state_transfer"&gt;REST&lt;/a&gt; architectures are built around this request/response cycle and HTTP. Doing a search, getting user information, posting a comment, the list goes on and on. Now of course it is possible to recreate the illusion of a request/response cycle -- just fire your request event and block until you get the response event. But clearly that is Doing It Wrong.&lt;br /&gt;&lt;br /&gt;So maybe these event driven architectures are not right for all applications. Yes they are sexier, but don't try to put a square peg in a round hole. This kind of architecture is best suited for apps where you are interacting with somebody else. Let's say you are bidding on an auction. Somebody else bids on the same auction and ideally you will see this happen very quickly. Or maybe you sent a message to a friend on some type of social network, and you can't wait to see their response. Social games are also a great example of the types of apps that would benefit from an event driven architecture. Even if the game doesn't have to be real-time, it would probably still benefit from "lower latency" between moves.&lt;br /&gt;Hopefully you have a better idea now on if your application should use a traditional architecture or an event driven one. Of course there is a lot of room in between. You could easily have an architecture that uses both, picking the right interaction model depending on the use case within your app. Maybe most things use a classical model, but then on certain screens you switch to an event-driven one. Or vice versa. Either way you'll want to read my next post where I will talk about the nuances of implementing an event driven architecture.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7212832616396239255?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7212832616396239255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7212832616396239255' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7212832616396239255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7212832616396239255'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/12/mobile-application-architecture-part-2.html' title='Mobile Application Architecture, Part 2'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-7YWDecVp500/TuEjHAHdfVI/AAAAAAAACF4/D1BuFzsS9sY/s72-c/mobile%252520app%252520arch2.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3177608740400682201</id><published>2011-12-02T16:14:00.000-08:00</published><updated>2011-12-02T16:14:03.347-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Mobile Application Architecture, Part 1</title><content type='html'>The boom in mobile applications has been fueled by excellent application frameworks from Apple and Google. Cocoa Touch and Android take some very different approaches on many things, but both enable developers to create applications that end users enjoy. Of course "excellent" can be a relative term, and in this case the main comparison is web application development. For both experienced and novice developers, it takes less effort to be more productive developing a native mobile application than a web application (mobile or not.) This despite the fact that you really have to deal with a lot more complexity in a mobile app (memory, threads, etc.) than you do for web applications.&lt;br /&gt;&lt;br /&gt;Despite having significant advantages over web development, mobile applications often have some similar qualities and this often leads to similar limitations. Most mobile applications are network based. They use the network to get information and allow you to interact with other users. Before mobile applications, this was the realm of web applications. Mobile apps have shown that there is not necessary to use a browser to host an application that is network based. That's good. However the way that mobile apps interact with servers over the network has tended to resemble the way that web applications do this. Here's a picture that shows this.&lt;br /&gt;&lt;img alt="Traditional mobile app architecture" border="0" height="438" src="http://lh3.ggpht.com/-weceha52IY8/TtkutudbK8I/AAAAAAAACD0/0yxcJa3uYLA/app_arch_traditional.png?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="app_arch_traditional.png" width="546" /&gt;&lt;br /&gt;This diagram shows a traditional mobile application's architecture. In particular it shows an Android app, hence that little red box on the right saying C2DM, which we will talk more about later. Most of this is applicable to iOS as well though. Most apps get data from servers or send data to servers using HTTP, the same protocol used by web browsers. HTTP is wonderfully simple in most ways. Significantly, it is a short-lived, synchronous communication. You make a request and you wait until you get a response. You then use the response to update the state of your application, show things to the user, etc.&lt;br /&gt;&lt;br /&gt;Now since HTTP is synchronous and network access is notoriously slow (especially for mobile apps), you must inevitably banish HTTP communication to a different thread than the one where you respond to user interactions. This simple paradigm becomes the basis for how many mobile applications are built. Android provides some nice utilities for handling this scenario like AsyncTask and Loaders. Folks from the Android team have written numerous blogs and presentations on the best way to setup an application that follows this pattern, precisely because this pattern is so prevalent in mobile applications. It is the natural first step from web application to mobile application as you can often re-use much of the backend systems that you used for web applications.&lt;br /&gt;&lt;br /&gt;Before we go any further, take another look at the diagram. I promised to talk more about it. That is the cloud-to-device messaging system that is part of Android (or at least Google's version, it's not available on the Kindle Fire for example.) It provides a way for data to get to the application without the usual HTTP. Your server can send a message to C2DM servers, which will then "push" the message to the device and your app. This is done through a persistent TCP socket between the device and the C2DM servers. Now these messages are typically very small, so often it is up to your application to retrieve additional data -- which could very well go back to using HTTP. Background services on Android can makes this very simple to do.&lt;br /&gt;&lt;br /&gt;Notice that in the previous paragraph we never once used the word "notification." C2DM was seen by many as Android's equivalent to Apple's Push Notifications. They can definitely fulfill the same use cases. Once your service receives the message it can then choose to raise a notification on the device for the user to respond to. But C2DM is not limited to notifications, bot by a long shot. Publishing a notification is just one of many things that your application can do with the message that it receives from C2DM. What is most interesting about C2DM is that leads us into another type of application architecture not built around HTTP. In part 2 of this post we will take a deeper look at event-driven architectures.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3177608740400682201?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3177608740400682201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3177608740400682201' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3177608740400682201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3177608740400682201'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/12/mobile-application-architecture-part-1.html' title='Mobile Application Architecture, Part 1'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-weceha52IY8/TtkutudbK8I/AAAAAAAACD0/0yxcJa3uYLA/s72-c/app_arch_traditional.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6358955712318865462</id><published>2011-11-29T10:46:00.001-08:00</published><updated>2011-11-29T10:51:47.062-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ows'/><category scheme='http://www.blogger.com/atom/ns#' term='occupy wall street'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>An OWS Protester and a Communist Walk Into a Bar</title><content type='html'>I've commented a little on some of &lt;a href="http://fupeg.blogspot.com/2011/10/occupy-wall-street-and-tea-party.html" target="_blank"&gt;my thoughts about the Occupy Wall Street movement&lt;/a&gt;. As someone who values personal freedom and liberty, I'm at odds with many of the OWS ideas, natch. Still I can empathize on many of their complaints and desires to make our nation better. However recently someone made the statement to me that to describe OWS as class warfare was laughable. I don't think that was a very intelligent statement. Sure many Republican pundits like to use the term class warfare way too much, but that doesn't mean the term is always invalid.&lt;br /&gt;&lt;br /&gt;So is class warfare applicable to OWS? Well let's imagine a hypothetical OWS protester and a hypothetical modern Marxist. Why a Marxist? Because &lt;a href="http://en.wikipedia.org/wiki/Class_struggle"&gt;class struggle&lt;/a&gt; is a key component to Marxism. What would a Marxist think of statements like "We are the 99%" and "we are getting nothing while the 1% is getting everything"? I think the Marxist would agree with these statements. Once the Marxist realized that proletariat was an outdated term with a lot of negative connotations, I think he would be quick to switch over to saying "the 99%" instead. Who would be more likely to say "capitalism has failed democracy", the OWS protester or the Marxist? Seems like both. Who would encourage participation in general strikes? Who would be more likely to say "Join the global revolution?" Ok maybe that's too easy and meaningless. Who would favor using the force of the government to take from one group (the 1%) to give to the other group (the 99%)? Now don't get too angry about that statement. I'm not saying that this should or should not be done, just that it is a statement that I think both an OWS protester and a Marxist would agree upon.&lt;br /&gt;&lt;br /&gt;My point is that on many issues, it is impossible to distinguish between an OWS protester and a Marxist. Does that mean that OWS protesters favor class warfare? No, it does not. However it does suggest that there is plenty of room for a reasonable person to think that OWS does indeed favor class warfare. Of course OWS is notorious for its fractured message, but I've tried to pull all of the above from its main websites and events. It seems to me that everything I've quoted would be things that the majority of OWS protesters would agree with. Those just happen to be the same things that a Marxist would agree with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-6358955712318865462?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/6358955712318865462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=6358955712318865462' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6358955712318865462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6358955712318865462'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/11/ows-protester-and-communist-walk-into.html' title='An OWS Protester and a Communist Walk Into a Bar'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4888283812653552794</id><published>2011-10-16T08:45:00.000-07:00</published><updated>2011-10-16T08:45:10.113-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='contentprovider'/><category scheme='http://www.blogger.com/atom/ns#' term='mediastore'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Pictures, Thumbnails, and the MediaStore</title><content type='html'>One of the cool feature of the Android SDK is the MediaStore ContentProvider. This is basically a database with metadata about all of the photos on your device. If you are going to display some or all of the photos on a device, you will probably want to show a thumbnail version of the photo. Once again Android's got you covered. The &lt;a href="http://developer.android.com/reference/android/provider/MediaStore.Images.Thumbnails.html#getThumbnail(android.content.ContentResolver, long, int, android.graphics.BitmapFactory.Options)"&gt;MediaStore.Images.Thumbnails.getThumbnail&lt;/a&gt; function can get you a thumbnail for a given picture. But the devil's in the details here. This method will create a thumbnail if one does not already exist. That's a blocking call, but it will return quickly if the thumbnail has already been created. This is an API that any app could call, so if another app has called it for a particular image, then that thumbnail will (probably) already exist. In addition, some phones automatically create thumbnails when you take a picture. However none of these things are guaranteed, so it made me wonder just how many pictures on my phone already had thumbnails made for them. So I wrote a little app to determine this. Here's a screenshot showing the result.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/-8lNTTnps4k0/Tpm4CBNzUaI/AAAAAAAABj8/u5fGmAo-3fc/device-2011-10-15-091147.png?imgmax=800" imageanchor="1" style="float: left;"&gt;&lt;img alt="How many pics have thumbs?" border="0" height="600" src="http://lh5.ggpht.com/-8lNTTnps4k0/Tpm4CBNzUaI/AAAAAAAABj8/u5fGmAo-3fc/device-2011-10-15-091147.png?imgmax=800" title="device-2011-10-15-091147.png" width="360" /&gt;&lt;/a&gt;Tapping the first button causes all of the pics in the MediaStore to be counted. Tapping the second button causes all of the thumbnails in the MediaStore to be counted. Tapping the third button causes the thumbs to be counted and put into a HashSet, then iterate over all pics and see if they have a corresponding thumb or not. You can find &lt;a href="https://github.com/michael-galpin/ContentCounter"&gt;all of the code on GitHub&lt;/a&gt;.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-zQn6y43FC4Q/Tpr7KJQhE3I/AAAAAAAABkI/pJxSHY4lW94/s1600/img.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-zQn6y43FC4Q/Tpr7KJQhE3I/AAAAAAAABkI/pJxSHY4lW94/s1600/img.png" /&gt;&lt;/a&gt;&lt;/div&gt;The results on my phone were a bit surprising. First, the biggest number on the screen is the number of thumbnails. There are more thumbnails than photos! My guess is that photos get deleted but their thumbnails persist. Going back to the original question, it looks like about 90% of the photos on my phone have thumbnails already. So any app that uses the MediaStore thumbnails (as opposed to creating their own) will probably be very snappy. At least on my phone. I'm curious what the results would be on your phone. So here's the &lt;a href="http://dl.dropbox.com/u/6449830/ContentCounter.apk"&gt;APK&lt;/a&gt;, you can install it on your phone and let me know what are the results.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4888283812653552794?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4888283812653552794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4888283812653552794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4888283812653552794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4888283812653552794'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/10/pictures-thumbnails-and-mediastore.html' title='Pictures, Thumbnails, and the MediaStore'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-8lNTTnps4k0/Tpm4CBNzUaI/AAAAAAAABj8/u5fGmAo-3fc/s72-c/device-2011-10-15-091147.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-344657104821683785</id><published>2011-10-11T19:28:00.000-07:00</published><updated>2011-10-11T19:28:35.404-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='occupy wall street'/><category scheme='http://www.blogger.com/atom/ns#' term='tea party'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Occupy Wall Street and The Tea Party</title><content type='html'>The Occupy Wall Street movement is an interesting one to me. I have a lot of empathy for the people involved in the movement. They make a lot of great points. They are correct that the wealthiest 1% have an incredible amount of influence with our government. This is particularly true of corporations in the top percentile. The amount of influence (control) wielded is obviously disproportionate and flies in the face of a country that has a republic style of government.&lt;br /&gt;&lt;br /&gt;The Tea Party movement is also interesting to me. I have a lot of empathy for the people in the movement. They make a lot of great points. They are correct that the government is too powerful and in so many cases does much more harm than good. The amount of power wielded by the US government flies in the face of a limited government as described by The Constitution.&lt;br /&gt;&lt;br /&gt;Both of these groups are outraged by the status quo and for good reason. However these two groups seem to be at opposite ends of the political spectrum. Most consider OWS to a be "radically progressive." I've heard some people call them communists or anarchists. On the other hand, the Tea Party is considered to be "radically conservative." I've also heard people call them anarchists.&lt;br /&gt;&lt;br /&gt;As you've probably guessed by now, I think both groups have way more in common than they would care to admit. Now demographically they are probably quite different, but that doesn't have to matter. However we have seen the Tea Party get eaten up by the Republican Party. Similarly we are already seeing the Democratic Party eat up the OWS group. President Obama wasted no time getting in on this, just as an incumbent President coming up on an election year should.&lt;br /&gt;&lt;br /&gt;So in the end these two groups will be consumed by the very powers that be that they oppose. This is part of how the two party system works. In the end both of these groups just become instruments of the divisive, "rally the base" politics that have been the norm for decades.&lt;br /&gt;&lt;br /&gt;I'd love to see an alliance between the two groups, which would be a nightmare for both the Republican and Democratic Parties. Of course there is a fundamental difference between the two groups. As I see it, the OWS folks think that government can be fixed and can "do the right thing." They seem to want to use the very instrument of their misery as its own remedy. The Tea Party philosophy is that the government cannot be fixed, so the only way to lessen the damage that it inflicts is to limit its powers. One could say that the OWS folks are optimistic and the Tea Party folks are pessimistic.&lt;br /&gt;&lt;br /&gt;Personally I don't totally agree with either group (surprise surprise!) My philosophy certainly leans toward the Tea Party. I think that in a republic or representative democracy, those with the most wealth will yield more influence. I don't think this can be prevented without either undermining democracy, freedom of speech, or freedom of the press. So you are best off by limiting that power. Further, I think that if you make the power of government less attractive (eliminate corporate taxes, subsidies, tariffs etc.), you will also decrease the corruption. It's sort of a chain reaction. Government is corrupt, so make it less powerful. A less powerful government in turn attracts less corruption. It doesn't solve the problem because this problem can't be solved.&lt;br /&gt;&lt;br /&gt;However I don't prescribe to the "no new taxes" mantra of the Tea Party either. I do think that taxes are too high, and no I don't care that taxes were once higher or that taxes are higher in other countries. Both of those argument are logical fallacies. However we have built up a huge debt. If we don't pay down that debt, then our children will have to. We splurged, it's our debt. We should pay it down. And please don't tell me that I can pay extra taxes if I choose to. That's a classic prisoner's dilemma, only on a much larger scale.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-344657104821683785?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/344657104821683785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=344657104821683785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/344657104821683785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/344657104821683785'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/10/occupy-wall-street-and-tea-party.html' title='Occupy Wall Street and The Tea Party'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3443805210376980932</id><published>2011-09-28T22:13:00.000-07:00</published><updated>2011-09-29T21:59:44.410-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>The Perfect Android</title><content type='html'>&lt;p&gt;Yesterday Android developer advocate Reto Meier &lt;a href="https://plus.google.com/111169963967137030210/posts/i7J1mUYgWK1"&gt;asked about what developers loved/hated about application frameworks&lt;/a&gt;. It got me thinking about if I could change anything about Android development, what would it be? I mentioned some of these things in my comment on Reto's post, but I'll go into a little more detail here.&lt;/p&gt;&lt;p&gt;Less XML. There are a lot of places where XML is really unnecessary in Android. Top among those things is having to declare Activities, and to a lesser degree Services and BroadcastReceivers. I don't know about your code, but the vast majority of the Activity declarations that I've ever made simply stated the class and maybe some options about config changes and screen orientation. Does this have to be in the manifest XML? I'd prefer to not have to declare Activities in XML and still be able to navigate to them without my app crashing. I'd also like to be able to handle most of their options in Java. This could be as annotations, or maybe some kind of getConfiguration() method that you override, or maybe just as APIs to invoke during onCreate. I think I could live with any of those things. Now if you need to do something more complicated like put an IntentFilter, then that can be in XML. In fact I'm OK with XML always being allowed, just optional for the simpler cases that make up the majority of the Activities that developers write. You could apply similar logic to Services. If you have a Service that you only communicate with by binding to it and it runs in the same process as your main application, then it seems like you should not need any XML for it.&lt;/p&gt;&lt;p&gt;Functional programming. If you've read my blog for very long then this is probably no surprise. This probably requires closures to come to Java, but &lt;a href="http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html"&gt;it seems like we are pretty close to that happening&lt;/a&gt;. I think that once that syntax is settled on, then Android should not only get this language feature, but the app framework should be dramatically upgraded to take advantage of it. Technically some of this can be smoothed over by the compiler allowing closures to substitute for &lt;a href="http://developer.android.com/reference/android/view/View.OnClickListener.html"&gt;single-method interfaces&lt;/a&gt;. I'd rather be more explicit about it. And by the way, I don't see why Android should have to wait for Java 8 to be finished by Oracle. Android needs to maintain language and bytecode compatibility, but that doesn't mean it has to use somebody else's javac...&lt;/p&gt;&lt;p&gt;No more Parcelables. Yeah I know that Parcelables are a faster serialization/deserializtion solution. Cool. In most cases this requires a developer to write a lot of mindless code. On one hand tooling can help with this, but why not just have the compiler handle it? Then we could get rid of Parcelable. If a class implements good 'ol Serializable, then the compiler could easily generate the Parcelable code that tooling could generate, but that is currently generated by annoyed developers. Of course it's cool to let developers override this if they want to do something clever. If a class has fields that are Serializable, then the compiler could generate a warning or even an error.&lt;/p&gt;&lt;p&gt;MVC. Now this one is a lot more controversial for me. I'm not a big believer in MVC, so I've always liked that Android wasn't either. However I think that a lot of developers would have an easier time if Android followed a more pure MVC pattern. I think that's one of the ways that Cocoa Touch is easier for new developers to pick up. I've had more than one new developer ask me if an Activity was Android's version of a controller. It is not. But maybe it should be? There's room for things beyond MVC as well. With ICS, Fragments should become the norm for app developers. Developers will have to decide for themselves about the best way to coordinate and communicate fragment-to-fragment, fragment-to-activity, etc. Direct method invocation? Shared memory? Message/handlers? Event listeners? Too many choices and too many choices makes life especially difficult for newbie programmers. Provide a "standard" mechanism, while not ruling out the other choices so more experienced developers can still do things the way that they think is best. The same issue exists for activity-to-activity communication.&lt;/p&gt;&lt;p&gt;Better memory management. I'd love to have gobs of RAM and an amazing GC. In the absence of those just do me some favors like make sure all my soft/weak references are GC'd before an OOM. Always fire Application.onLowMemory before an OOM, and give me 20ms to react and prevent the OOM. Kill all non-visible/foreground processes and re-allocate their memory before an OOM. An OOM is a crash and is the worst possible thing for users. I know lots of snooty engineers will look down their nose and say "&lt;a href="http://code.google.com/p/android/issues/detail?id=8488"&gt;your app needs to use less memory&lt;/a&gt;", but that kind of attitude makes Android seem like a ghetto to end users.&lt;/p&gt;&lt;p&gt;No more sync. This is one of those features in Android that sounds great on paper but is more trouble than it is worth at this point. By adding your app to sync, you let the system schedule a time for your app to synchronize with your server. Sounds great. However your app won't be the only one getting busy at that time, that's part of the point of sync. Worst of all if the user decides to launch some other app when the sync is in progress then that app has a good chance of being hosed. Tons of CPU &amp;amp; I/O will be hogged by the sync and that app will be sluggish to say the least and may even crash. All of this because of sync. What's more is that there is no real need for sync anymore. With C2DM, a server can send an event to the phone to let your app know that it needs to sync state with the server. Your server can decide how often this needs to happen and can make sure there are no unnecessary syncs.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3443805210376980932?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3443805210376980932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3443805210376980932' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3443805210376980932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3443805210376980932'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/09/perfect-android.html' title='The Perfect Android'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6150364108977574121</id><published>2011-09-02T22:34:00.000-07:00</published><updated>2011-09-02T22:34:28.640-07:00</updated><title type='text'>Offshoring</title><content type='html'>Wikipedia describes &lt;a href="http://en.wikipedia.org/wiki/Offshoring"&gt;offshoring&lt;/a&gt; as "the relocation of a business process from one country to another." There once was a time in Silicon Valley that offshoring was a dirty word. I was here (in the Valley) at the time and I remember it well. Let me take you back a few years in time and describe what I've seen of offshoring over the years.&lt;br /&gt;&lt;br /&gt;I think there is still a general fear and bitterness associated with offshoring in the United States. It was much the same when I first heard about it in the Valley around 2002. It had all started several years before, but it was in the midst of the Valley's worst recession that it started to take full effect. The big companies of the Valley were under tremendous pressure to cut costs. They had offshored things like call centers, and so it only made sense to move up the value chain. There was plenty of programming talent to be found in India and China. Soon it wasn't just big companies, but even startups. It wasn't uncommon to hear about a startup where the founder was non-technical and shipped the programming tasks to a firm in &lt;br /&gt;&lt;br /&gt;For me personally, I heard a lot about this kind of offshoring, but it did not affect me until 2004. That was when I was working for Vitria Technology. Vitria had been a shining star in the dot com era, and made a lot of money selling the enterprise integration software known as BusinessWare. However by 2004, Vitria's glory days were long past. They had been searching for their second hit for years, but were still being buoyed by recurring revenue from BusinessWare. I joined to work on one of their new ideas, what was eventually known as Resolution Accelerator or RA for short. I worked on a small team of engineers at Vitria's office in Sunnyvale. We developed RA, but our QA was in India. Vitria had moved its QA functions to India the year before we built RA. &lt;br /&gt;&lt;br /&gt;RA turned out to be a success. We had lots of paying customs in healthcare and telecom. RA was built on top of BusinessWare, as that was part of our strategy. However a lot of the technical leadership behind BusinessWare felt that the RA team had built a lot of reusable features that belonged in BusinessWare. So even as we were selling RA to happy customers, we started a new project to migrate many of RA's key components to BusinessWare and then rebuild RA on top of this new version of BusinessWare as it was being developed at the same time. Great idea, right? &lt;br /&gt;&lt;br /&gt;I was working with the BusinessWare team who were essentially re-inventing my wheels but within the mammoth piece of software that was BusinessWare. However this team turned out to be a lot different than the team that I worked on that built RA. There were no developers. There were multiple architects who were assigned to BusinessWare, as it was the key piece of software in the company. Then there was a tech lead from the BusinessWare team. However this tech lead did not code. Instead he wrote specs that were then implemented by a development team in China and then tested by our QA team in India. This was the model they had adopted fro BusinessWare for a couple of years already. I was essentially a consultant to the tech lead and was not supposed to interact with the developers in China -- even though they were largely writing code that was functionally equivalent to code I had already written. Meanwhile I was the tech lead of RA and we were now supposed to "graduate" to the same development process as BusinessWare. So now I had a development team in China who I was supposed to direct. My job had "evolved" into writing a spec for developers in China and coordinating with a QA team in India. Sunday - Thursday you could find me on the phone from 9 - 11 PM every night. Good times.&lt;br /&gt;&lt;br /&gt;Meanwhile all of the developers on the RA team took off. One went to Google and worked on GMail. One went to Symantec. Finally I could take no more and split for a startup… That startup burned through cash like crazy, and went out of business a year later. All I've got is &lt;a href="http://www.wipo.int/patentscope/search/en/detail.jsf?docId=WO2008091705"&gt;this patent&lt;/a&gt; to show for it, along with the valuable experience of writing my own programming language. In 2007 I went to work for eBay and ran into offshoring at a much larger scale. &lt;br /&gt;&lt;br /&gt;Development organizations typically consisted of engineers in San Jose plus teams from our Shanghai office. Plus they were heavily augmented with contractors from two firms based in India. The contractors would have a tech lead in San Jose who interacted with a tech lead from eBay. In addition there would be a development manager who "owned" the application and who was usually the manager of eBay's tech lead on the project. The tech lead's job was similar to what it had been at Vitria. He was in charge of a spec and coordinated with the contractors plus engineers in San Jose and Shanghai. As you might guess, most of the actual coding was being done either in Shanghai or by contractors in India. The tech lead usually didn't interact with contractors in India though, instead they worked with the contractors tech lead/liaison. &amp;nbsp;Finally in addition to the development manager for the application, there might also be an architect -- if the application was important enough. The tech lead worked with the architect on the design that would become the spec that would be sent off to India and China. The tech lead would also interact with a data architect to design database schemas and operations architect to design the physical deployment and requirements of the application. The point is that the tech lead had almost no chance of actually coding, and this was just accepted and understood.&lt;br /&gt;&lt;br /&gt;Just before I left eBay, things started to change a bit. In particular eBay brought in some new blood from Microsoft of all places, who took over the search organization. This was the organization that trail blazed offshoring at eBay. It had been a search VP who had "opened" our Shanghai office, and most of the engineers and QA there were part of the search organization. New management decided that this was not working and sought to move all search engineering to San Jose. I'm not sure how the Indian contractors would play in this new vision, but it should sounded like they would be squeezed out too. The Shanghai engineers were unilaterally "reorged" to another organization in the company (an organization that had already been gutted and whose VP was being pushed out, but that's another long story.) &lt;br /&gt;&lt;br /&gt;Ok, so what's the point of all of this? I'm not sure to be honest. From my perspective, I was very dissatisfied with how we used offshoring at Vitria. When I joined eBay we were using it in a similar way. If anything, it seemed the eBay way was even more inefficient. There was an unwritten rule at eBay that if a San Jose tech lead estimated that a technical task would take N days, then you would need to set aside 2*N days if the development was being done in China and 2.5*N days if the development was being done by contractors in India. This might seem harsh or much worse, but certainly a big part of it was the operational overhead with offshoring. Further this system was judged a failure by the largest organization at eBay.&lt;br /&gt;&lt;br /&gt;At the same time it would be foolish to say that offshoring has been a failure. There is a lot of awesome software development being done via offshoring. I'm not so sure about the practice of "design it in America, develop it offshore" when it comes to software. At the very least I have not seen this work well in person. Then again perhaps the problem is simply one of tech leads who don't code and that just happened to coincide with my offshoring experiences.Whatever the case, one thing is for certain. There was palpable fear about offshoring a decade ago, and it turned out to be a false fear.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-6150364108977574121?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/6150364108977574121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=6150364108977574121' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6150364108977574121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6150364108977574121'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/09/offshoring.html' title='Offshoring'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1035069761369187440</id><published>2011-08-15T15:59:00.000-07:00</published><updated>2011-08-15T15:59:15.652-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android Fragmentation: The Screen Myth</title><content type='html'>As someone who develops Android apps for a living and who has worked on two Android apps that have been downloaded 10M+ each, I know about fragmentation. I can tell you all about device differences for cameras, address books, and accelerometers. However when most pundit talk about fragmentation, they usually rely on exactly one example: screen sizes. I'm here to tell you that this is a myth.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Chart" border="0" height="250" src="http://lh5.ggpht.com/-V0Oslpqyz9c/Tkmj65p8juI/AAAAAAAABRc/5hRtXhgYJlk/chart.png?imgmax=800" style="float: right;" title="chart.png" width="400" /&gt;&lt;br /&gt;If you look at the Screen Sizes and Densities page from the Android developers site, you will see a chart that looks&amp;nbsp;something like the one to the right. There are several slices to this pie, but two of them are much than the rest. One is "Normal hdpi" at 74.5% (as of August 2011) and the other is "Normal mdpi" at 16.9%. What does that mean? It means that 91.4% of all devices have a "Normal" sized screen, so roughly 3.5 - 4.3". The hdpi ones have a higher resolution of course. So for those devices you will want higher quality images and what not.&lt;br /&gt;&lt;br /&gt;Of course for anything like this, it is natural to compare things to the iPhone. On the iPhone all devices have 3.5" sized screen. However you once again have the situation with different resolutions between the iPhone 3G/3GS and iPhone 4. So similar to Android, you will probably want to include higher resolution artwork to take advantage of the iPhone 4's higher resolution screen. However as a developer you don't get much of an advantage with the higher resolution screen since the overall size is the same. It's not like you're going to make your buttons the same number of pixels and thus fit more buttons on the screen, etc.&lt;br /&gt;No wait a minute, there is a difference between 91.4% and 100%. A good chunk of that difference is because of tablets, with their "Xlarge mdpi" screens. You can expect that segment to continue to grow in the future. But again, this is a similar situation to the iOS. An iPad has a larger screen than an iPhone. If you care about this, you either make a separate app for the iPad, or you incorporate the alternate layouts within your existing app and make a "universal" app. This is the same deal on Android.&lt;br /&gt;&lt;br /&gt;To really make a fair comparison, you would have to exclude the xlarge screens on Android. Then the percentage of phones that fall in the combined Normal mdpi/hdpi bucket is even higher. It's still not 100% but it is pretty close. My point is that if somebody wants to talk to you about Android fragmentation and they use screen size as an example, some healthy skepticism is appropriate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1035069761369187440?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1035069761369187440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1035069761369187440' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1035069761369187440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1035069761369187440'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/08/android-fragmentation-screen-myth.html' title='Android Fragmentation: The Screen Myth'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-V0Oslpqyz9c/Tkmj65p8juI/AAAAAAAABRc/5hRtXhgYJlk/s72-c/chart.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-2786506127686732437</id><published>2011-07-24T11:12:00.001-07:00</published><updated>2011-07-24T11:12:07.848-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>What's a MacBook Air good for?</title><content type='html'>&lt;p&gt;At the beginning of this year, I bought a MacBook Air. I bought a maxed out one, with a 13" screen, 2.13 GHz cpu, 4 gb ram, 256 gb SSD. This past week Apple refreshed the MacBook Air line and I've seen a lot of people asking the question "Could I use a MacBook Air for ___?" So here's what all I use it for, along with a comparison to my work computer a maxed out 15" MacBook Pro.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Web browsing. I run Chrome on it and it screams. Actually the MBA set an expectation for me about how ChromeOS and in particular &lt;a href="http://fupeg.blogspot.com/2011/06/web-apps-mobile-web-apps-native-apps.html"&gt;how my Samsung Chromebook should perform&lt;/a&gt;. I basically expected the Chromebook to perform exactly like the Chrome browser on my MBA, which is awesome. I was very disappointed, as the Chromebook is nowhere close. Anyways, browsing on the MBA is fantastic. I can notice a slight difference in performance on super-JS heavy sites, with my MBP being slightly smoother. I think a non-engineer would have difficultly spotting these differences.&lt;/li&gt;&lt;li&gt;Word processing. I'm not just talking about rudimentary word processing either. When I got the MBA, I had a couple of chapters and appendices that I was still working on for &lt;a href="http://manning.com/collins/"&gt;Android in Practice&lt;/a&gt;. I used the MBA to write/complete these chapters. This involved using Microsoft Word along with the Manning Publications template for Word. The chapters were usually in the 30-50 page range, and often with tons of formatting (code, sidebars, etc.) and large graphics. I cannot tell any difference between my MBP and MBA for these massive Word docs.&lt;/li&gt;&lt;li&gt;Programming. Speaking of AIP, part of finishing it meant writing code for those chapters. I've run pretty much all of the code from AIP on my MBA with no problems at all. For smaller apps like I have in AIP, there is no appreciable difference between my MBA and MBP. Building a small app is an I/O bound task, and the SSD on the MBA shines. Now I have also built Bump on my MBA, and there is a very noticeable difference between it and my MBP. There are two major phases to the Bump build. The first is the native compilation, which is single-threaded. You can definitely notice a major CPU speed difference here, even though the raw clock speeds of the two machines are close. The second phase is the Scala/Java compilation phase. This is multi-threaded, and the four cores on my MBP obviously trump the two cores on the MBA. Still, I would saw the MBA compares favorably to the late-2008 era MacBook Pro that I used to use for work.&lt;/li&gt;&lt;li&gt;Photography. I used to use Aperture on my old MBP. On the MBA I decided to give Adobe Lightroom a try. So it's not an apples-to-apples comparison. However, Lightroom on my MBA blows away Aperture on my old MBP. I haven't tried either on my current MBP. Obviously the SSD makes a huge difference here. Nonetheless, post-processing on the MBA is super smooth. When it comes to my modest photography, Lightroom presents no problem for my MBA.&lt;/li&gt;&lt;li&gt;Watching video. I haven't watched too much video on my MBA, mostly just streaming Netflix. It is super smooth, though it will cause the machine's rarely used fan to kick-in (as will intense compilations, like building Bump.) Next week I am going on a cruise to Mexico, and I will probably buy/rent a few videos from iTunes to watch on the cruise. Based on previous experiences, I expect this to be super smooth and beautiful, though I have considered taking the MBP just for its bigger, high resolution screen.&lt;/li&gt;&lt;li&gt;Presentations. I've done a couple of talks using the MBA. For creating content in Keynote, I do sometimes notice a little sluggishness on the MBA that is not present on my MBP. For playback, it seems very smooth. However, I did have an animation glitch during one presentation. This never happened when previewing just on my MBA's screen, it only happened on the projected screen. Nobody seemed to notice during the presentation, except for me of course.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So there you go. What's a MacBook Air good for? Pretty much everything. If you are a professional developer who compiles software, then I think your money is best spent buying the most powerful computer available. This has always been true. Maybe this is also the case for professional photographers/videographers as well. However my MBA is way more than enough for most folks. Finally keep in mind that the new MBAs introduced this week are a good bit faster than my MBA, at least in terms of CPU speed.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-2786506127686732437?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/2786506127686732437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=2786506127686732437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2786506127686732437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2786506127686732437'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/07/what-macbook-air-good-for.html' title='What&amp;#39;s a MacBook Air good for?'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7704991978363565590</id><published>2011-07-22T18:05:00.000-07:00</published><updated>2011-07-22T18:05:01.906-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android JSON Bug</title><content type='html'>Today I was working on some code that needed to invoke a JavaScript function on a web page that was being displayed in a WebView within an Android application. As part of that function invocation a JSON object is passed in. It's actually a pretty complex JSON object. Of course it must be passed in simply as a string and then parsed by the JavaScript to an object. Android includes the JSON "reference implementation", so naturally I wanted to use this instead of relying on some 3rd party JSON library that would fatten up my APK. The standard way to do this with the reference implementation is to create an instance of &lt;a href="http://developer.android.com/reference/org/json/JSONObject.html"&gt;org.json.JSONObject&lt;/a&gt; and use its toString method. You can create an empty instance and programmatically build up a JSON data structure, or you can give it a Java Map to build from. I chose to go the latter route.&lt;br /&gt;When my web page choked, I wasn't too surprised. I'm never surprised when code I write has bugs initially. I added a log statement to show the data being passed in and was surprised to see that it looked like this:&lt;br /&gt;&lt;pre class="brush:js"&gt;{"a": "{b={c=d}}", "e":"f"}&lt;/pre&gt;This was not correct. This should have looked like this:&lt;br /&gt;&lt;pre class="brush:js"&gt;{"a": "{"b":"{"c":"d"}"}", "e":"f"}&lt;/pre&gt;To create the JSONObject that I was passing in, I passed it in a HashMap whose keys were all strings but whose values were either strings or another HashMap. So to create the above structure there would be code like this:&lt;br /&gt;&lt;pre class="brush:java"&gt;HashMap&amp;lt;String,Object&amp;gt; top = new HashMap&amp;lt;String,Object&amp;gt;();&lt;br /&gt;HashMap&amp;lt;String,Object&amp;gt; a = new HashMap&amp;lt;String,Object&amp;gt;();&lt;br /&gt;HashMap&amp;lt;String,Object&amp;gt; b = new HashMap&amp;lt;String,Object&amp;gt;();&lt;br /&gt;b.put("c", "d");&lt;br /&gt;a.put("b", b);&lt;br /&gt;a.put("e", "f");&lt;br /&gt;top.put("a",a);&lt;/pre&gt;It seemed that the JSONObject code was flattening out my objects and producing incorrect JSON (WTF equal signs!) as a result. I put together a quick workaround to recursively replace any HashMap values with JSONObjects like this:&lt;br /&gt;&lt;pre class="brush:java"&gt;JSONObject jsonIfy(HashMap&amp;lt;String,Object&amp;gt; map){&lt;br /&gt;	HashMap&amp;lt;String,Object&amp;gt; fixed = new HashMap&amp;lt;String,Object&amp;gt;();&lt;br /&gt;	for (String key : map.keySet()){&lt;br /&gt;		Object value = map.get(key);&lt;br /&gt;		if (value instanceof Map){&lt;br /&gt;			value = jsonIfy((HashMap&amp;lt;String,Object&amp;gt;) value);&lt;br /&gt;		}&lt;br /&gt;		fixed.put(key,value);&lt;br /&gt;	}&lt;br /&gt;	return new JSONObject(fixed);&lt;br /&gt;}&lt;/pre&gt;This worked perfectly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7704991978363565590?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7704991978363565590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7704991978363565590' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7704991978363565590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7704991978363565590'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/07/android-json-bug.html' title='Android JSON Bug'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7922409095182151453</id><published>2011-07-16T07:05:00.000-07:00</published><updated>2011-07-16T08:11:14.520-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><title type='text'>ChromeOS and Photography</title><content type='html'>So far I've been pretty disappointed with the Samsung Chromebook that Google gave me for attending I/O this year. That sounds pretty ungrateful for a free computer, but I am intrigued by the idea of ChromeOS. I'd like to see it work, just as a technical achievement. I think that perhaps the Chromebook that I have falls short because of its lack of hardware, but perhaps its shortcomings are inherent with the OS.&lt;br /&gt;Anyways, obviously the main idea with ChromeOS is that people spend all of their time on the web. However, one of the other common tasks that people do is use their computers to share digital photographs that they took with the camera. This might seem like a hard thing for ChromeOS to handle, but Google claimed that they had this figured out. So I decided to give it a spin.Here are the tools that I used.&lt;br /&gt;&lt;img alt="Chromebook and Camera" border="0" height="450" src="http://lh5.ggpht.com/-sw57KyCE9NU/TiGWttJJKNI/AAAAAAAABGs/4_i5tOKxKu8/IMG_20110715_230000.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_230000.jpeg" width="600" /&gt;&lt;br /&gt;I had taken a few dozen pictures at a Giants baseball game I went to last weekend with family. I took the SD card from my camera (a modest Nikon D3000) and plopped it into the SD card slot on the Chromebook. ChromeOS immediately opened a new tab with a file browser that allowed me to navigate and view my pictures on the SD card. Very nice!&lt;br /&gt;&lt;img alt="Viewing SD card contents" border="0" height="450" src="http://lh6.ggpht.com/-HY4Kx_ZiiEw/TiGXFv7q8II/AAAAAAAABGw/FykMZXrboP4/IMG_20110715_225509.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_225509.jpeg" width="600" /&gt; &lt;br /&gt;You could preview and even delete photos. The preview was a little slow to load. You could select photos and start an upload to ... &lt;span style="text-decoration: line-through;"&gt;Picasa&lt;/span&gt; Google Photos of course. The upload takes place in the background with a little notification window letting you know about the progress. Again, very nice. Once the pics are uploaded, browsing/previewing is much smoother. I assume this is because you are browsing downsized versions of the pics, whereas the file manager on ChromeOS has you browsing through the full versions.&lt;br /&gt;&lt;img alt="Pictures uploaded to Picasa" border="0" height="450" src="http://lh5.ggpht.com/-4i9xL6Uvd2c/TiGXfsgFeCI/AAAAAAAABG0/KjjCTpR42as/IMG_20110715_225608.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_225608.jpeg" width="600" /&gt; &lt;br /&gt;One of the things that I often do with my photos is edit them. One my MacBook Air, I use Adobe Lightroom. I didn't expect to have something as sophisticated as Lightroom, but I did expect to be able to do simple things like rotate and crop. I would also expect red-eye removal to be available, since this is a pretty common need. Anyways, the editing tool on the Picasa website is Picnik. I've used it before, and it is great. However, it had significant problems loading on ChromeOS:&lt;br /&gt;&lt;img alt="Loading Picnik" border="0" height="450" src="http://lh6.ggpht.com/-Xqc9L3Afbxg/TiGX2Ty3MhI/AAAAAAAABG4/wYuoZMqBk_I/IMG_20110715_225630.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_225630.jpeg" width="600" /&gt;&lt;br /&gt;&lt;img alt="Still loading..." border="0" height="450" src="http://lh5.ggpht.com/-RFIJdPOdlhs/TiGYFC3LM7I/AAAAAAAABG8/Dafa_x1obvY/IMG_20110715_225634.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_225634.jpeg" width="600" /&gt;&lt;br /&gt;&lt;img alt="Whoops!" border="0" height="450" src="http://lh6.ggpht.com/-al_eXvB3_EM/TiGYVF0MfhI/AAAAAAAABHA/cuFs1G6GreE/IMG_20110715_225638.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_225638.jpeg" width="600" /&gt;&lt;br /&gt;&lt;img alt="Restart your browser? Umm..." border="0" height="450" src="http://lh5.ggpht.com/-EtN134jA8Nw/TiGYjERzXHI/AAAAAAAABHE/0W_S6pEmRus/IMG_20110715_225704.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_225704.jpeg" width="600" /&gt;&lt;br /&gt;I thought that maybe this memory error was because of the size of the photo (2.5 MB). That would imply that Picnik is purely client-side? I don't think so. I would assume that the full size photo was on the server, and in which case the memory problem is purely from the Picnik tools loading and has nothing to do with the size of the picture. Either way, I don't think this photo is too much above average. Megapixels are cheap these days.&lt;br /&gt;&lt;br /&gt;So I couldn't edit the pics once uploaded to Picasa. I actually tried just using Picnik directly, not through Picasa, but it had the same problem. The nice thing is that any web app that allows you to upload pictures from your computer works great with ChromeOS. Here's Facebook for example:&lt;br /&gt;&lt;img alt="Upload to Facebook" border="0" height="450" src="http://lh5.ggpht.com/-Js-9uyI85gk/TiGYvq-BaRI/AAAAAAAABHI/9ppvINTHE6o/IMG_20110715_225757.jpeg?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="IMG_20110715_225757.jpeg" width="600" /&gt; &lt;br /&gt;You could essentially upload from your SD card to Facebook this way. I would think that if a tool like Picnik worked, you could edit and then upload. You could probably sell a Chrome app that did that (it should allowing tagging of your Facebook friends too) and make a few bucks, assuming Chromebooks started selling.&lt;br /&gt;I suppose a pretty common use case will be to simply upload all of the pics off of your SD card to Facebook. It seems like ChromeOS handles that pretty good. Put in you SD card, open up Facebook, and start uploading. If you use Picasa and Google+, it is even a little simpler. Editing seems to be a problem right now. Much like the general power performance of the Chromebook, it might be purely a function of subpar hardware. Maybe if Samsung put more memory in it, then Picnik wouldn't have choked? Hopefully the shortcomings can be addressed through software, since I don't think Google can update the RAM on my Chromebook.&lt;br /&gt;&lt;br /&gt;Note: The "screenshots" were taken with my Nexus S. Why? Because the &lt;a href="https://chrome.google.com/webstore/detail/dphhbbnlnbdkabjgkljkhplmehadonid?hl=en-US"&gt;screenshot tool for ChromeOS&lt;/a&gt; didn't work for me. It works great on Chrome browser, but it would only capture part of the screen on ChromeOS and then freeze up. Sigh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7922409095182151453?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7922409095182151453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7922409095182151453' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7922409095182151453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7922409095182151453'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/07/chromeos-and-photography.html' title='ChromeOS and Photography'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-sw57KyCE9NU/TiGWttJJKNI/AAAAAAAABGs/4_i5tOKxKu8/s72-c/IMG_20110715_230000.jpeg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4071388894094624304</id><published>2011-07-14T17:07:00.000-07:00</published><updated>2011-07-14T17:07:04.211-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rdio'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='spotify'/><title type='text'>Spotify vs. Rdio</title><content type='html'>Today was the much anticipated US launch of Spotify. I've been using Rdio for several months, and &lt;a href="http://fupeg.blogspot.com/2011/06/this-is-year-of-music.html"&gt;really love it&lt;/a&gt;. Not surprisingly, there are a lot of &lt;a href="http://techcrunch.com/2011/07/14/heres-spotify-the-music-streaming-service-officially-lands-in-the-us/"&gt;posts&lt;/a&gt; out there &lt;a href="http://www.quora.com/How-do-Rdio-and-Spotify-compare"&gt;comparing&lt;/a&gt; the two services. That's all good stuff to read. Here's my summary:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spotify has more music. If you stick to stuff from the last 10 years and that you can find on iTunes, then you probably won't find much difference. But going further back or by going "more obscure", you will notice the differences.&lt;/li&gt;&lt;li&gt;Spotify has a desktop app, but it is an iTunes clone. The Rdio desktop app is more of a wrapper on their website. So big advantage to Spotify, despite being an ugly iTunes clone. Also, Spotify will play music on your computer, so it tries to be a replacement for iTunes.&lt;/li&gt;&lt;li&gt;The Rdio mobile app is way better, at least on Android. Subjectively, it has a cleaner design and is easier to use. The Spotify mobile app looks like I designed it. Objectively, the Rdio app's sync is far superior. Spotify requires your mobile device to be on the same wifi network as your computer that is running Spotify. On Rdio, you can easily send any song, album, playlist, etc. to all of your mobile devices with no requirements except that you've got an Internet connection.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4071388894094624304?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4071388894094624304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4071388894094624304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4071388894094624304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4071388894094624304'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/07/spotify-vs-rdio.html' title='Spotify vs. Rdio'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3853884883842462860</id><published>2011-07-12T16:33:00.000-07:00</published><updated>2011-07-12T16:33:11.027-07:00</updated><title type='text'>Netflix Disappointment</title><content type='html'>&lt;span class="Apple-style-span" style="background-color: white; font-family: Arial, sans-serif; font-size: 13px; line-height: 18px;"&gt;Remember when Netflix started making us wait two weeks to get new releases? It was supposed to be a tradeoff to get more streaming content from Hollywod. Now here we are with &lt;a href="http://www.readwriteweb.com/archives/netflixs_inevitable_split.php"&gt;higher prices&lt;/a&gt; than ever, less streaming content, and still no new releases on DVD.&lt;br /&gt;&lt;br /&gt;Why can't we have a Rdio or Spotify for movies and TV? At some price, this should be possible, right? I know that is what I want, and I don't think I'm the only one. How much would you pay for it? I think my max price is somewhere north of $35/month, assuming I can use it on all of my devices. Doesn't it seem like there's a very profitable business out there for this kind of service at that price? I'm guessing backwards thinking in Hollywood is to blame here, along with continued paranoia over privacy. At least &lt;a href="http://news.cnet.com/8301-31001_3-20074484-261/take-that-netflix-hbo-go-app-sees-big-growth/"&gt;HBO seems to be getting this right&lt;/a&gt;.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3853884883842462860?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3853884883842462860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3853884883842462860' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3853884883842462860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3853884883842462860'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/07/netflix-disappointment.html' title='Netflix Disappointment'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7181075135906403807</id><published>2011-07-04T16:30:00.001-07:00</published><updated>2011-07-04T16:30:57.101-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google+'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Google+ and Hitting the Reset Button</title><content type='html'>&lt;p&gt;&lt;img style="float: right;" title="reset-button1-297x300.jpeg" src="http://lh6.ggpht.com/-7BwAFeAU7Ik/ThJJRdzyAgI/AAAAAAAAA8U/h_XXCHgsdek/reset-button1-297x300.jpeg?imgmax=800" border="0" alt="Reset your social network" width="297" height="300" /&gt;&lt;/p&gt;&lt;p&gt;So you might have heard this week that there's this new social networking thing (*yawn*) called &lt;a href="https://plus.google.com/"&gt;Google+&lt;/a&gt;. That's right, it's from Google. So it's gonna suck, right? I was &lt;a href="http://twitter.com/#!/anildash/status/85766184045252608"&gt;skeptical at first&lt;/a&gt;, as were many others. After all, nobody roots for The Big Company who clones popular products made by smaller companies, and Google has had a well known poor track record in this space. But after a few days of using Google+, I'm a believer -- in its potential. Here's why.&lt;/p&gt;&lt;p&gt;Google+ is a chance to hit the rest button on social networking. For me, when I first started using Facebook it was mostly to catch up with old college classmates. Two big events happened later. Facebook was opened up to everybody, and Twitter showed up. When Facebook was opened up to everyone, I pretty much accepted friend requests from anyone I knew at all. I still didn't use Facebook that much. Meanwhile I really fell in love with Twitter when it showed up. On there I connected mostly with people in the same or related professions as me. Most of my tweets were around things that had to do with my job (programming, technology.)&lt;/p&gt;&lt;p&gt;Meanwhile on Facebook, I had more and more family members join. Suddenly Facebook became a great place to share family related things, especially pictures. Then I hooked up my Twitter account to Facebook. Now I could just post things to Twitter, and they would show up on Facebook. Then I would occasionally post pictures on Facebook as well. However, most of my tweets were geeky stuff. I did have some co-workers and college classmates who found such things interesting, but more and more most of my friends on Facebook (lots of family high school classmates) found this useless. Eventually I cut off the Twitter-Facebook connection.&lt;/p&gt;&lt;p&gt;My story here is certainly different from a lot of folks, but I imagine there are a lot of similarities too. Google+ seems to offer the possibility to do things over and get it right this time. The key is its grouping feature, Circles. You have to put people in Circles, so you are motivated to organize your friends. This is important. Facebook and Twitter have both had similar features for awhile, and they just aren't used. Twitter's lists aren't really comparable since you still send tweets to everyone. Facebook's groups are more comparable, so why aren't they used?&lt;/p&gt;&lt;p&gt;&lt;img style="float: left;" title="facebook-privacy1.jpeg" src="http://lh4.ggpht.com/-XtiWTHU-A_Y/ThJJ4S8AMKI/AAAAAAAAA8Y/br1C4ou_p_w/facebook-privacy1.jpeg?imgmax=800" border="0" alt="All your privacies are belong to us" width="413" height="310" /&gt;&lt;/p&gt;&lt;p&gt;First and foremost, I don't think Facebook really wants anyone to use them. They have a pretty strong history of trying to decrease privacy on their network. Obviously Facebook benefits if everything posted on their network can be searched and viewed by others on Facebook. It seems like one of those features that they added because some users wanted it, but it did not benefit Facebook The Business. Within a couple of days of Google+'s debut, &lt;a href="http://techcrunch.com/2011/07/01/facebook-circles/"&gt;reports came out&lt;/a&gt; of a Facebook engineer easily hacking together the same interface to use with Facebook groups. So clearly it would have been pretty easy for Facebook to make groups easy for users to use to organize their friends and incorporate groups into content published on Facebook, but instead Facebook chose not to do this.&lt;/p&gt;&lt;p&gt;This raises the question of why the heck is Google+ doing it? If I had to guess, I doubt that Google really wants to do this either. However, this is one of many places where Google+ feels like something designed around the strengths and weaknesses of its competition, Facebook and Twitter. Privacy was an obvious weakness of Facebook and so Google+ takes advantage of that. It's the kind of thing you do to get market share, whereas Facebook has been doing just the opposite because they are trying to monetize existing users and content.&lt;/p&gt;&lt;p&gt;&lt;img style="float: right;" title="bill_borg.png" src="http://lh4.ggpht.com/-Jfz20qfpDEk/ThJKmN0xBZI/AAAAAAAAA8c/BySnCqGQiu8/bill_borg.png?imgmax=800" border="0" alt="Resistance is futile" width="300" height="250" /&gt;&lt;/p&gt;&lt;p&gt;Privacy is not the only place where Google+ feels like a product that has been cleverly designed around its competition. In fact it reminds me a lot of &lt;a href="http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish"&gt;embrace, extend, extinguish&lt;/a&gt; era Microsoft. I think they have realized that they don't necessarily have to &lt;a href="http://wave.google.com/"&gt;come up with something&lt;/a&gt; that Facebook and Twitter don't do at all, they can just do a lot of the same things and do them a little better. Some other examples of this are viewing pictures and allowing rich markup in status updates. So they make a slightly better product, then they play their own monopoly card by putting the G+ bar on top of all Google pages, including search results and GMail...&lt;/p&gt;&lt;p&gt;Anyways, going back to privacy... The creation of Circles is only half the battle. The other half is picking which of your Circles to publish to. G+ has made this easy to do, and it is a feature that I want to use. However, I don't know if others will do the same. Right now it still seems like most posts that I read are public. This may change as more people start to use G+, but maybe not.&lt;/p&gt;&lt;p&gt;If it doesn't change, then G+ then seems like it will be more of a competitor to Twitter than to Facebook. It already has a lot of similarities, since it uses an asymmetric friendship model like Twitter. I definitely noticed a drop in tweets by those I follow on Twitter since G+ came out. If people don't use the privacy features, then the most it could become is a better Twitter. There have been other better Twitters before, so I don't know if that is good enough. Features like hangouts (group video chat) and huddles (group messaging) seem like they could appeal to Facebook users, but it's hard to say right now. For me, the kind of folks who I use Facebook to communicate with, but would not use Twitter to communicate with, have not even heard of Google+. Yet.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7181075135906403807?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7181075135906403807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7181075135906403807' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7181075135906403807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7181075135906403807'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/07/google-and-hitting-reset-button.html' title='Google+ and Hitting the Reset Button'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-7BwAFeAU7Ik/ThJJRdzyAgI/AAAAAAAAA8U/h_XXCHgsdek/s72-c/reset-button1-297x300.jpeg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7919079094565328472</id><published>2011-06-29T14:10:00.000-07:00</published><updated>2011-06-29T14:10:05.625-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><title type='text'>Web Apps, Mobile Web Apps, Native Apps, ... Desktop Apps?</title><content type='html'>There's never any shortage of people debating mobile web apps vs. native apps. I don't want to waste your time with yet another rehash of this debate. Personally I sum it up as a choice between user experience and cost. But obviously I am biased -- I build native apps and even wrote a book on how to do it. So you shouldn't believe anything I have to say about this topic, it must be wrong. Anyways, one of the interesting lines of reason that often comes up in this debate is how web apps replaced desktop apps. I want to examine this a little bit closer.&lt;br /&gt;&lt;br /&gt;I'm actually writing this blog post from a Chromebook that I got for attending the Google I/O conference last month. This device is perhaps the logical conclusion of the web apps replacing desktop apps axiom. However, I have a problem with that axiom. It is often based on the emergence of popular websites like Yahoo, Google, Amazon, and eBay. The argument is that these apps were web based and the fact that they ran on servers that could be rapidly updated is a key to why they succeeded. The long update cycle of desktop software would have made it impossible for these apps to be anywhere but in a browser.&lt;br /&gt;&lt;br /&gt;There is some truth in this, but it's misleading. The most important factor in the success of those apps was that their data was in the cloud. They brought information and interactions that could not exist simply as part of a non-connected desktop app. They had business models that were not based on people paying to install the software. These were the keys. The fact that end users interacted through a web browser was secondary. It's pretty much the same story for newer super popular web apps like Facebook and Twitter. &lt;br /&gt;&lt;br /&gt;Going back to the world of mobile for a minute... One of the things that mobile has taught us is that users don't care so much about how they interact with your "web-based" application. Hence the popularity of native apps for web giants like Amazon and Facebook. In fact, some might even argue that users prefer to use native apps to interact with traditional web properties. I won't argue that, but I would definitely disagree with any claims that users prefer to use a browser.&lt;br /&gt;&lt;br /&gt;Anyways, the point is that the notion that web apps replaced desktop apps is dubious. In fact, if you look at places where web apps were tried to exactly replace desktop apps, such as word processing, they have had limited success. Currently we see a movement to replace music players like iTunes with web apps. These web apps have some distinct advantages, but it is not at all clear that they will prove popular with users. Apple has taken the approach of adding more network based features (store and download your music from their servers) to iTunes instead of going with a web app -- at least for now.&lt;br /&gt;&lt;br /&gt;Connected desktop apps have a lot to offer. I often find myself using desktop apps like Twitter, Evernote, Sparrow (for GMail), and Mars Edit (for Blogger.) They provide a better experience than their browser based cousins. Apple's Mac App Store has definitely made such apps more popular on the Mac platform, as they have made it easier to discover, purchase, and update such apps. Speaking of updates, these apps update frequently, usually at least once a month. Again, I think that our expectations have adjusted because of mobile apps. &lt;br /&gt;&lt;br /&gt;So will desktop apps make a comeback? Are mobile web apps doomed? I don't know. I think it is very unclear. It's not a given that a computer like this Chromebook that I'm using is "the future." We can haz network without a browser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7919079094565328472?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7919079094565328472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7919079094565328472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7919079094565328472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7919079094565328472'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/06/web-apps-mobile-web-apps-native-apps.html' title='Web Apps, Mobile Web Apps, Native Apps, ... Desktop Apps?'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7691457818358104655</id><published>2011-06-18T09:40:00.001-07:00</published><updated>2011-06-18T09:40:33.629-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rdio'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='turntable'/><title type='text'>This is the Year of Music</title><content type='html'>&lt;p&gt;Last month I wrote &lt;a href="http://fupeg.blogspot.com/2011/05/we-all-love-music.html"&gt;a bit about cloud music&lt;/a&gt;. Since then Apple got in the game with iTunes in the iCloud. I'm not a fan of it because you have to manage what songs are downloaded to your devices before you can listen to them. Of course having to download a song before you can listen to it is not surprising from a company that sells hardware priced by storage capacity. If you didn't have to download to use your media, why would you spend an extra $100 on the 32gb iWhatever instead of the 16gb version? Still you gotta give Apple props on the price point. I am optimistic that competition around price and features between Apple, Google, and Amazon will be very beneficial for consumers.&lt;/p&gt;&lt;p&gt;Anyways while the your music-in-the-cloud market is obviously very hot market being contested by three of the biggest technology companies in the world, there is a lot more interesting innovation around music going in in technology. This blog post is about two of my favorite music startup/services: &lt;a href="http://www.rdio.com/"&gt;Rdio&lt;/a&gt; and &lt;a href="http://turntable.fm/"&gt;Turntable.fm&lt;/a&gt;. There's tons of tech press on each of these companies, so I won't go into that. I'm just going to talk about why I like them.&lt;/p&gt;&lt;p&gt;Rdio launched in late 2010, and I've been a paying customer since January 2011. It's conceptually similar to subscriptions services like fake Napster and Rhapsody. What I like about it is how great it is to use on mobile devices. I have it on my Nexus S, on my Nexus One that I listen to when I run/work-out, and on the iPod Touch that I have plugged in to my car. Now you might be thinking, now how can I use this on a iPod in my car with no internet connection? Well you can mark songs/albums/playlists as songs to sync to your devices and be usable with no connection. So I can use the Rdio Mac app, mark some songs, and then just connect my iPod or Nexus One to a wifi network, and the songs get synced. Then I can listen to them anytime. I regularly read reviews of new music on &lt;a href="http://www.metacritic.com/"&gt;Metacritic&lt;/a&gt;, listen to some of the music I find there on Rdio, and then sync it to my devices. Then I can listen to it while running or driving to work.&lt;/p&gt;&lt;p&gt;Speaking of discovering new music, that is the sweet spot of Turntable. It's pretty new, I only &lt;a href="http://techcrunch.com/2011/06/08/turntable-addiction/"&gt;heard&lt;/a&gt; about it earlier this month and started using it this week. The idea of being a DJ for the room may sound lame at first -- and maybe it is -- but it is also awesome. However I will warn you to resist being a DJ. You will be drawn in and waste massive amounts of time. It's completely unnecessary too. Like I said, Turntable is awesome for music discovery. Go to a room that sounds interesting (avoid the Coding Soundtrack unless you really enjoy electronica/dance AND don't mind witnessing pissing contests measured by playing obscure remixes) and enjoy. There's a good chance that you will hear familiar music, but an even better chance you will hear something you've never heard before. The DJs try hard to impress, and you win because of it. It's like Pandora, but better, with no ads, and ... you always have the option to enter the chat or even take your turn at DJ'ing.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7691457818358104655?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7691457818358104655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7691457818358104655' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7691457818358104655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7691457818358104655'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/06/this-is-year-of-music.html' title='This is the Year of Music'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-5339362773440552065</id><published>2011-06-12T17:17:00.001-07:00</published><updated>2011-06-12T17:17:33.897-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>I hate your smartphone</title><content type='html'>&lt;p&gt;When people talk about smartphones, they often mean iPhones and Android phones. Sure there are still Blackberries out there, I think I once saw a guy using a webOS phone, and Microsoft has 89,000 employees who have to use Windows Phone 7, but it's mostly an Android and iPhone world right now. If you have a phone running Android or iOS, life is pretty good. You've probably got a really powerful phone, with a huge number of apps and games to choose from. You've also got a web browser that's more advanced than &lt;a href="http://en.wikipedia.org/wiki/Usage_share_of_web_browsers"&gt;the one&lt;/a&gt; used by most desktop computer users. So given all of those things to be happy about, why is that smartphone owners are so hostile to each other?&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="chickenjesus.jpeg" src="http://lh6.ggpht.com/-wAkN561mYzk/TfVNpMlQmSI/AAAAAAAAA4s/WQZQJROe-fw/chickenjesus.jpeg?imgmax=800" border="0" alt="Can't we all get along?" width="400" height="401" /&gt;&lt;/p&gt;&lt;p&gt;iPhones user love to look down their noses and make derisive comments about Android users. Not to be outdone, Android users never miss an opportunity to mock iPhone users. There is an obvious parallel here to Mac vs. Windows, but I think it's actually much nastier than Mac vs. Windows ever was. Here's a list of my theories (in no particular order) on why there is such animosity.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;It's so easy to do. The truth is that both iOS and Android are deeply flawed. Going back to the Mac vs. Windows comparison, think about how much less mature these smartphone OS's are compared to Windows and OSX. So if you have any inclination to make fun of either OS, it's embarrassingly easy to do. This is where things really differ from Mac vs. Windows. There's not much to debate there. If you wanted to say "Mac sucks", there is a short list of things that you can point to. Not true for iOS or Android.&lt;/li&gt;&lt;li&gt;Social networking. In this day and age of social networks, your "friends" shove what they are doing in your face constantly. Smartphone apps make heavy use of this, as a way to spread virally. But what happens when there is an impedance mismatch caused by apps available on one OS but not the other? The folks with the unsupported OS get a little annoyed, and the other folks get an artificial feeling of &lt;a href="http://www.urbandictionary.com/define.php?term=133t"&gt;133tness&lt;/a&gt;&lt;/li&gt;&lt;li&gt;It starts at the top. Apple and Google both frequently take shots at each other. They do it at developer conferences. They do it when reporting quarterly earnings. It doesn't stop there. Motorola, Verizon, T-Mobile and others have all taken shots at Apple in commercials seen by millions. &lt;/li&gt;&lt;li&gt;Big decisions. You only have one smartphone (unless you are weird like me) and in the US, you usually buy it on a two-year contract. So you have to pick just one, and then you are stuck with it for two years. Thus if anybody is gonna suggest that you made a bad decision, most people will defend their decisions vehemently. &lt;/li&gt;&lt;li&gt;The Apple effect. So this really is straight out of Mac vs. Windows. Apple wants their products to seem elite and luxurious. They want the owners to feel like they have purchased far superior products, and feel that they (the user) is superior because of this. It's brilliant marketing, and it totally works. The air of superiority hangs over any Apple product owners, but especially iPhone users. So naturally any non-iPhone users are going to react negatively to the haute attitudes of iPhone users.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;a href="http://www.urbandictionary.com/define.php?term=133t"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-5339362773440552065?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/5339362773440552065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=5339362773440552065' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5339362773440552065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5339362773440552065'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/06/i-hate-your-smartphone.html' title='I hate your smartphone'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-wAkN561mYzk/TfVNpMlQmSI/AAAAAAAAA4s/WQZQJROe-fw/s72-c/chickenjesus.jpeg?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-5020091140438424813</id><published>2011-06-10T10:51:00.001-07:00</published><updated>2011-06-10T10:51:59.722-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='wwdc'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Rallying the Base</title><content type='html'>&lt;p&gt;This week was WWDC 2011. Last year I was lucky enough to attend what appears to be the final &lt;a href="http://en.wikipedia.org/wiki/Apple_Special_Events#The_.22Stevenote.22_Address"&gt;stevenote&lt;/a&gt;. This year I followed along online, like much of Silicon Valley. There are a lot of reasons why so many of us who work in the tech world pay such close attention to the WWDC keynote. This is the place where Apple typically unveils innovative hardware and software. However, this year's event reminded me of another  watershed moment in recent US history: John McCain choosing Sarah Palin as his VP candidate back in 2008.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="rally.jpeg" src="http://lh6.ggpht.com/-bhgOIvvH8qs/TfJRcPcDVyI/AAAAAAAAA4k/fRBYWlATPQo/rally.jpeg?imgmax=800" border="0" alt="Rallying the Base" width="600" height="195" /&gt;&lt;/p&gt;&lt;p&gt;These two events were similar because they were both examples of rallying the base. In 2008, McCain decided against trying to appeal to moderate Republican/Democrats/independents who were either inclined to vote for Obama or undecided. Instead he went with Palin, a candidate who did not appeal to those people. The idea was to appeal to the most conservative elements of the Republican party and get those people to vote instead of staying home for whatever reason. Obviously this did not work.&lt;/p&gt;&lt;p&gt;So how was WWDC 2011 a rallying of the base tactic? Apple did not try to introduce near software or hardware that would get non-iPhone owners to go out and buy an iPhone or more strongly consider buying an iPhone the next time they were in the market for a new phone. Instead they did their best to make sure that current iPhone owners continued to buy iPhones. The strategy was two-fold.&lt;/p&gt;&lt;p&gt;First, they needed the places where they were weak and other were strong. Now let's be honest here, by others we are talking about Android/Google. There were a couple of glaring problems with iOS 4. First was notifications, so Apple essentially adopted Android's model here. Second was the dependency on iTunes the desktop software application. They introduced wireless sync and their iCloud initiatives to address this weakness. Apple did not break any new ground in any of these areas, they simply removed some obvious reasons for people to buy an Android device over an iPhone.&lt;/p&gt;&lt;p&gt;Phase two of rallying the base was to increase lock-in. If you are an iPhone user, you already experience lock-in. Buying an Android phone means losing all of your apps and games. Depending on what you use for email, calendar, etc. you might also lose that data too. Of course this is true to some degree about any smartphone platform. However, with the expansion of the Android Market (I've seen many projections that it will be bigger than the App Store soon), pretty much every app or game you have on your iPhone can be found on Android. Further, there's a good chance that it will be free on Android, even if you had to pay for it on the iPhone. Further, with the popularity of web based email, especially GMail, you probably would not lose any emails, calendar events, etc. So the lock-in was not as high as Apple needed it to be. Enter iCloud and iMessaging.&lt;/p&gt;&lt;p&gt;As many have noted, iCloud/iMessaging does not offer anything that you could not get from 3rd party software. Syncing your docs, photos, email, calendar, etc. is something that many of us already do, and that includes iPhone users. Further many folks already have IM clients that do everything that iMessaging does. The big difference is that all of those existing solutions are not tied to iOS or OSX. Thus they are cross-platform (no lock-in) but that also means that you have to add this software to your devices. It's very nice for users to not have to worry about installing Dropbox, Evernote, or eBuddy. But the obvious win for Apple is here is the lock-in. If you start relying on Pages for writing docs and sync'ing them across devices, you are going to be very reluctant to buy anything other than an iPhone (and a Mac for that matter.) If you get used to using iMessaging to chat with your other iPhone toting friends, same thing.&lt;/p&gt;&lt;p&gt;Apple is keeping the cost of using all of their new offerings very low. It's a classic &lt;a href="http://en.wikipedia.org/wiki/Loss_leader"&gt;loss leader&lt;/a&gt; strategy. It's ok if iCloud and iMessaging both lose a lot of money for Apple. If they can just lock-in existing iPhone users, they can continue to make huge profits. In that scenario, it's ok for Google/Android to have N times the number of users as Apple. The Apple users won't be going anywhere, and they spend a lot of money. Seems like a smart strategy by Apple. It should work out much better than it did for the Republican party in 2008.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-5020091140438424813?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/5020091140438424813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=5020091140438424813' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5020091140438424813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5020091140438424813'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/06/rallying-base.html' title='Rallying the Base'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-bhgOIvvH8qs/TfJRcPcDVyI/AAAAAAAAA4k/fRBYWlATPQo/s72-c/rally.jpeg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-5440802524619464685</id><published>2011-06-04T22:10:00.001-07:00</published><updated>2011-06-04T22:10:28.377-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>The Concurrency Myth</title><content type='html'>&lt;p&gt;For nearly a decade now technology pundits have been talking about &lt;a href="http://www.slate.com/id/2132826/"&gt;the end of Moore's Law&lt;/a&gt;. Just this week, The Economist ran an &lt;a href="http://www.economist.com/node/18750706"&gt;article&lt;/a&gt; about how programmers are starting to learn functional programming languages to make use of the multi-core processors that have become the norm. Indeed inventors of some of these newer languages like Rich Hickey (Clojure) and Martin Odersky (Scala) love to &lt;a href="http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey"&gt;talk&lt;/a&gt; about how their languages give developers a much better chance of dealing with the complexity of concurrent programming that is needed to take advantage of multi-core CPUs. Earlier this week I was at the &lt;a href="http://days2011.scala-lang.org/"&gt;Scala Days conference&lt;/a&gt; and got to hear Odersky's keynote. Pretty much the second half of his keynote was on this topic. The message is being repeated over and over to developers: you have to write concurrent code, and you don't know how to do it very well. Is this really true, or is it just propaganda?&lt;/p&gt;&lt;p&gt;There is no doubt that the computer that we buy are now multi-core. Clock speeds on these computers have stopped going up. I am writing this blog post on a MacBook Air with a dual-core CPU running at 2.13 GHz. Five years ago I had a laptop with a 2.4 GHz processor. I'm not disputing that multi-core CPUs are the norm now, and I'm not going to hold my breath for a 4 GHz CPU. But what about this claim that it is imperative for developers to learn concurrent programming because of this shift in processors? First let's talk about which developers. I am only going to talk about application developers. What I mean are developers who are writing software that is directly used by people. Well maybe I'll talk about other types of developers later, but I will at least start off with application developers. Why? I think most developers fall into this category, and I think these are the developers that are often the target of the "concurrency now!" arguments. It also allows me to take a top-down approach to this subject.&lt;/p&gt;&lt;p&gt;What kind of software do you use? Since you are reading this blog, I'm going to guess that you use a lot of web software. Indeed a lot of application developers can be more precisely categorized as web developers. Let's start with these guys. Do they need to learn concurrent programming? I think the answer is "no, not really." If you are building a web application, you are not going to do a lot of concurrent programming. It's hard to imagine a web application where one HTTP request comes in and a dozen threads (or processes, whatever) are spawned. Now I do think that event-driven programming like you see in node.js will become more and more common. It certainly breaks the assumption of a 1-1 mapping between request and thread, but it most certainly does not ask/require/suggest that the application developer deal with any kind of concurrency.&lt;/p&gt;&lt;p&gt;The advancements in multi-core processors has definitely helped web applications. Commodity app servers can handle more and more simultaneous requests. When it comes to scaling up on a web application, Moore's Law has not missed a beat. However it has not required all of those PHP, Java, Python, Ruby web developers to learn anything about concurrency. Now I will admit that such apps will occasionally do something that requires a background thread, etc. However this has always been the case, and it is the exception to the type of programming usually needed by app developers. You may have one little section of code that does something concurrent, and it will be tricky. But this has nothing to do with multi-core CPUs.&lt;/p&gt;&lt;p&gt;Modern web applications are not just server apps though. They have a lot of client-side code as well, and that means JavaScript. The only formal concurrency model in JavaScript are Web Workers. This is a standard that has not yet been implemented by all browsers, so it has not seen much traction yet. It's hard to say if it will become a critical tool for JS development. Of course one of the most essential APIs in JS is XMLHttpRequest. This does indeed involve multiple threads, but again this is not exposed to the application developer.&lt;/p&gt;&lt;p&gt;Now one can argue that in the case of both server side and client side web technologies, there is a lot of concurrency going on but it is managed by infrastructure (web servers and browsers). This is true, but again this has always been the case. It has nothing to do with multi-core CPUs, and the most widely used web servers and browsers are written in languages like C++ and Java.&lt;/p&gt;&lt;p&gt;So is it fair to conclude that if you are building web applications, then you can safely ignore multi-core CPU rants? Can you ignore the Rich Hickeys and Martin Oderskys of the world? Can you just stick to your PHP and JavaScript? Yeah, I think so.&lt;/p&gt;&lt;p&gt;Now web applications are certainly not the only kind of applications out there. There are desktop applications and mobile applications. This kind of client development has always involved concurrency. Client app developers are constantly having to manage multiple threads in order to keep the user interface responsive. Again this is nothing new. This has nothing to do with multi-core CPUs. It wasn't like app developers used to do everything in a single thread, but now that multi-core CPUs have arrived, you need to start figuring out how to manage multiple threads (or actors or agents or whatever.) Now perhaps functional programming can be used by these kind of application developers. I think there are a lot of interesting possibilities here. However, I don't think the Hickeys and Oderskys of the world have really been going after developers writing desktop and mobile applications.&lt;/p&gt;&lt;p&gt;So if you are a desktop or mobile application developer, should you be thinking about multi-core CPUs and functional programming? I think you should be thinking about it at least a little. Chances are you already deal with this stuff pretty effectively, but that doesn't mean there's room for improvement. This is especially true if language/runtime designers started thinking more about your use cases.&lt;/p&gt;&lt;p&gt;I said I was only going to talk about application developers, but I lied. There is another type of computing that is becoming more and more common, and that is distributed computing. Or is it called cloud computing? I can't keep up. The point is that there are a lot of software systems that run across a cluster of computers. Clearly this is concurrent programming, so bust out the functional programming or your head will explode, right? Well maybe not. Distributed computing does not involve the kind of shared mutable state that functional programming can protect you from. Distributed map/reduce systems like Hadoop manage shared state complexity despite being written in Java. That is not to say that distributed systems cannot benefit from languages like Scala, it's just that the benefit is not necessarily the concurrent problems/functional programming that are often the selling points of these languages. I will say that Erlang/OTP and Scala/Akka do have a lot to offer distributed systems, but these frameworks address different problems than the multi-core concurrency.&lt;/p&gt;&lt;p&gt;It might sound like I am a imperative program loving curmudgeon, but I actually really like Scala and Clojure, as well as other functional languages like Haskell. It's just that I'm not sure that the sales pitch being used for these languages is accurate/honest. I do think the concurrency/functional programming angle could have payoffs in the land of mobile computing (desktop too, but there's not much future there.) After all, tablets have already gone multi-core and there are already a handful of multi-core smartphones. But these languages have a lot of work to do there, since there are already framework features and common patterns for dealing with concurrency in mobile. Event driven programming for web development (or the server in client/server in general) is the other interesting place, but functional languages have more to offer framework writers than application developers in that arena.  My friend David Pollak recently &lt;a href="http://goodstuff.im/functional-languages-will-rule-but-not-this-y"&gt;wrote&lt;/a&gt; about how the current crop of functional languages can hope for no more than to be niche languages like Eiffel. I think that he might be right, but not just because functional programming has a steep learning curve. If all they can offer is to solve the concurrency problem, then that might not be enough of a problem for these languages to matter.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-5440802524619464685?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/5440802524619464685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=5440802524619464685' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5440802524619464685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5440802524619464685'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/06/concurrency-myth.html' title='The Concurrency Myth'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-115541350658481974</id><published>2011-06-03T15:23:00.001-07:00</published><updated>2011-06-03T15:52:50.680-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bluetooth'/><category scheme='http://www.blogger.com/atom/ns#' term='nfc'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Local data exchange with NFC and Bluetooth</title><content type='html'>One of the exciting technologies being &lt;a href="http://blog.foursquare.com/2011/05/09/experimenting-with-nfc-check-ins-for-google-io/"&gt;shown off&lt;/a&gt; at Google's I/O conference this year was &lt;a href="http://en.wikipedia.org/wiki/Near_field_communication"&gt;near field communication&lt;/a&gt; or NFC. It certainly got my interest, so I attended an excellent talk on NFC. Here's a video of the talk:&lt;br /&gt;&lt;iframe frameborder="0" height="349" src="http://www.youtube.com/embed/49L7z3rxz4Q" width="560"&gt;&lt;/iframe&gt;&lt;br /&gt;One of the things mentioned in the talk was that you did not want to use NFC for any kind of long running, verbose communication. Its range was too short and its transfer speed was too slow. Bluetooth was the way to go for such data exchange, so what you really wanted to do was an NFC-to-Bluetooth handoff. It was even mentioned that the popular Fruit Ninja game did this, or would do this in the future. Earlier this week at Bump we had our second &lt;a href="http://blog.bu.mp/hack"&gt;hackathon&lt;/a&gt;. I decided that local communication using NFC and Bluetooth would make for an interesting hackathon project. So based on what I had learned from the I/O presentation, &lt;a href="http://developer.android.com/resources/browser.html?tag=sample"&gt;the examples in the Andoird SDK&lt;/a&gt;, and a tip from &lt;a href="http://roman.nurik.net/"&gt;Roman Nuri&lt;/a&gt;k, here's some code on how to do the NFC-to-Bluetooth handoff to setup a peer-to-peer connection between two phones to exchange data between them.&lt;br /&gt;We'll start with the NFC pieces. You want the phone to do two things. First, it needs to broadcast an NFC "tag". This tag can have whatever information you want in it. In this case we will have it send all of the information needed to setup a Bluetooth connection: the Bluetooth MAC address for our phone plus a UUID for our app's connection. You can add more stuff to the tag as well, but these two parts are sufficient. Technically you could do without the UUID, but you'll want this in case other apps are using a similar technique. Here is some simplified code for generating an NFC text record:&lt;br /&gt;&lt;pre class="brush:java"&gt;public static NdefRecord newTextRecord(String msg) {&lt;br /&gt;    byte[] langBytes = Locale.ENGLISH.getLanguage().getBytes(&lt;br /&gt;            Charset.forName("US-ASCII"));&lt;br /&gt;    byte[] textBytes = msg.getBytes(Charset.forName("UTF-8"));&lt;br /&gt;    char status = (char) langBytes.length;&lt;br /&gt;    byte[] data = new byte[1 + langBytes.length + textBytes.length];&lt;br /&gt;    data[0] = (byte) status;&lt;br /&gt;    System.arraycopy(langBytes, 0, data, 1, langBytes.length);&lt;br /&gt;    System.arraycopy(textBytes, 0, data, 1 + langBytes.length,&lt;br /&gt;            textBytes.length);&lt;br /&gt;    return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT,&lt;br /&gt;            new byte[0], data);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This code only handles English/ASCII characters. Take a look at the Android samples for a more generic approach. Next we need to get the Bluetooth MAC address to pass in to the above function. That is simply: BluetoothAdapter.getDefaultAdapter().getAddress(). Now we can create the text record to broadcast using NFC. To do this, you need to be inside an Android Activity:&lt;br /&gt;&lt;pre class="brush:java"&gt;@Override&lt;br /&gt;public void onResume() {&lt;br /&gt;    super.onResume();&lt;br /&gt;    NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);&lt;br /&gt;    // code to generate a string called msg with the MAC address, UUID, etc.&lt;br /&gt;    NdefMessage message = new NdefMessage(new NdefRecord[] { newTextRecord(msg) });&lt;br /&gt;    adapter.enableForegroundNdefPush(this, message);&lt;br /&gt;    // more code to come later&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;In this code there is a String called msg that I didn't show how it was generated. It would have the Bluetooth MAC address, as well as the UUID for your app, plus whatever else you want to include in the NFC broadcast. Now when your app loads, it will use NFC to broadcast the info needed for the Bluetooth handoff. The app needs to not only broadcast this, but also listen for this information as well:&lt;br /&gt;&lt;pre class="brush:java"&gt;@Override&lt;br /&gt;public void onResume() {&lt;br /&gt;    // see above code&lt;br /&gt;    PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this,&lt;br /&gt;            getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);&lt;br /&gt;    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);&lt;br /&gt;    try {&lt;br /&gt;        ndef.addDataType("*/*");&lt;br /&gt;    } catch (MalformedMimeTypeException e) {&lt;br /&gt;        throw new RuntimeException("fail", e);&lt;br /&gt;    }&lt;br /&gt;    IntentFilter[] filters = new IntentFilter[] { ndef, };&lt;br /&gt;    String[][] techLists = new String[][] { new String[] { NfcF.class.getName() } };&lt;br /&gt;    adapter.enableForegroundDispatch(this, pendingIntent, filters, techLists);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This code configures an NFC listener using an IntentFilter and a type of NFC tag (there are many.) It uses a PendingIntent for this same Activity. So when a NFC tag that matches our criteria (based on the IntentFilter and tag type), then an Intent will be fired that will be routed to our Activity (because that's the Activity we put in the PendingIntent.) Now we just need to override the onNewIntent method of our Activity, since that is what will be invoked when an NFC tag is encountered:&lt;br /&gt;&lt;pre class="brush:java"&gt;@Override&lt;br /&gt;public void onNewIntent(Intent intent) {&lt;br /&gt;    NdefMessage[] messages = getNdefMessages(intent);&lt;br /&gt;    for (NdefMessage message : messages) {&lt;br /&gt;        for (NdefRecord record : message.getRecords()) {&lt;br /&gt;            String msg = parse(record);&lt;br /&gt;            startBluetooth(msg);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;public static String parse(NdefRecord record) {&lt;br /&gt;    try {&lt;br /&gt;        byte[] payload = record.getPayload();&lt;br /&gt;        int languageCodeLength = payload[0] &amp;amp; 0077;&lt;br /&gt;        String text = new String(payload, languageCodeLength + 1,&lt;br /&gt;                payload.length - languageCodeLength - 1, "UTF-8");&lt;br /&gt;        return text;&lt;br /&gt;    } catch (UnsupportedEncodingException e) {&lt;br /&gt;        // should never happen unless we get a malformed tag.&lt;br /&gt;        throw new IllegalArgumentException(e);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;For our example, there should only be one NdefMessage received, and it should have exactly one NdefRecord, the text record we created earlier. Once we get the message from the NFC tag, we it's time to start the Bluetooth connection. Bluetooth uses sockets and requires one device to act as a server while the other acts as a client. So if we have two devices setting up a peer-to-peer Bluetooth connection, which is one is the server and which is the client? There are a lot of ways to make this decision. What I did was have both phones include a timestamp as part of the NFC tag they broadcast. If a phone saw that it's timestamp was smaller than the other's, then it became the server. At this point you will want to spawn a thread to establish the connection. Here's the Thread I used:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class ServerThread extends Thread {&lt;br /&gt;&lt;br /&gt;    private final BluetoothAdapter adapter;&lt;br /&gt;    private final String macAddress;&lt;br /&gt;    private final UUID uuid;&lt;br /&gt;    private final Handler handler;&lt;br /&gt;&lt;br /&gt;    public ServerThread(BluetoothAdapter adapter, String macAddress, UUID uuid,&lt;br /&gt;            Handler handler) {&lt;br /&gt;        this.adapter = adapter;&lt;br /&gt;        this.macAddress = macAddress;&lt;br /&gt;        this.uuid = uuid;&lt;br /&gt;        this.handler = handler;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void run() {&lt;br /&gt;        try {&lt;br /&gt;            BluetoothServerSocket server = adapter&lt;br /&gt;                    .listenUsingInsecureRfcommWithServiceRecord(macAddress,&lt;br /&gt;                            uuid);&lt;br /&gt;            adapter.cancelDiscovery();&lt;br /&gt;            BluetoothSocket socket = server.accept();&lt;br /&gt;            server.close();&lt;br /&gt;            CommThread comm = new CommThread(socket, handler);&lt;br /&gt;            comm.start();&lt;br /&gt;        } catch (IOException e) {}&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This Thread uses the device's BluetoothAdapter to open up an &lt;a href="http://en.wikipedia.org/wiki/Bluetooth_protocols#Radio_frequency_communication_.28RFCOMM.29"&gt;RFCOMM&lt;/a&gt; socket. Once you start listening, you'll want to immediately turn off Bluetooth discovery. This will allow the other device to connect much quicker. The server.accept() call will block until another devices connects (which is why this can't be in the UI thread.) Here's the client thread that will run on the other device:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class ClientThread extends Thread {&lt;br /&gt;&lt;br /&gt;    private final BluetoothAdapter adapter;&lt;br /&gt;    private final String macAddress;&lt;br /&gt;    private final UUID uuid;&lt;br /&gt;    private final Handler handler;&lt;br /&gt;&lt;br /&gt;    public ClientThread(BluetoothAdapter adapter, String macAddress, UUID uuid,&lt;br /&gt;            Handler handler) {&lt;br /&gt;        super();&lt;br /&gt;        this.adapter = adapter;&lt;br /&gt;        this.macAddress = macAddress;&lt;br /&gt;        this.uuid = uuid;&lt;br /&gt;        this.handler = handler;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void run() {&lt;br /&gt;        BluetoothDevice remote = adapter.getRemoteDevice(macAddress);&lt;br /&gt;        try {&lt;br /&gt;            BluetoothSocket socket = remote&lt;br /&gt;                    .createInsecureRfcommSocketToServiceRecord(uuid);&lt;br /&gt;            adapter.cancelDiscovery();&lt;br /&gt;            socket.connect();&lt;br /&gt;            CommThread comm = new CommThread(socket, handler);&lt;br /&gt;            comm.start();&lt;br /&gt;        } catch (IOException e) {}&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;On the client thread, you find the other device by using it's MAC address (not the client's.) Then you connect to it using the device using the shared UUID. On both client and server, we stated another thead for communication. From here on out this is just normal socket communication. You can write data on one end of the socket, and read it from the other.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-115541350658481974?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/115541350658481974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=115541350658481974' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/115541350658481974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/115541350658481974'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/06/local-data-exchange-with-nfc-and.html' title='Local data exchange with NFC and Bluetooth'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/49L7z3rxz4Q/default.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-151752876307827498</id><published>2011-05-23T22:14:00.000-07:00</published><updated>2011-05-23T22:14:24.815-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='espn'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Not all mobile apps are great to use</title><content type='html'>I've played ESPN fantasy sports for many years. ESPN also creates one of my favorite mobile apps, their ScoreCenter app (though it could be sooo much better.) However their fantasy baseball app is one of the most frustrating apps out there. It provides access to your fantasy baseball teams. The other way to access your teams is through the website. The website is what sets your expectation of course. When you login to the website, you are first presented with a list of your teams. Once you choose a team, you are shown your team's stats for the day:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-XxksPiPrMrA/Tds7zyAxkoI/AAAAAAAAA4I/FvWSb-eKQNg/s1600/flb_web.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="218" src="http://4.bp.blogspot.com/-XxksPiPrMrA/Tds7zyAxkoI/AAAAAAAAA4I/FvWSb-eKQNg/s400/flb_web.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;This not only sets one's expectations for interacting with your fantasy baseball team, but it really is quite useful. You want to see how your team is doing today when you login. We should expect something similar from the corresponding mobile app. Instead you get this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-pblL3yiro3A/Tds8cF9Bj5I/AAAAAAAAA4M/X4L4skTBxfc/s1600/flb_all.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/-pblL3yiro3A/Tds8cF9Bj5I/AAAAAAAAA4M/X4L4skTBxfc/s400/flb_all.png" width="373" /&gt;&lt;/a&gt;&lt;/div&gt;This is from the Android app, but the iPhone one is almost identical (which is also a sad state of things.) You start off with having to pick your team. However when you pick your team, you are presented with the season stats for all of your players. That's not what you want. To get how your team did today, you have to open &amp;nbsp;up this crazy selector, then change the option whose default value is "Season" (we only the value, not the name of what this property is) to "Day." This brings us back to the crazy selector, where you select Done and then you get today's stats for your team.&lt;br /&gt;&lt;br /&gt;What's even worse is that this is the 2011 version of the app. There was a (different) app for 2010. To get the 2011 one, you had to buy it. The 2010 app had the same frustrating UI. Last year at WWDC I talked about this to the developer of the iPhone app (which is exactly as bad as the Android one.) I told them about how this sucks. So not only did the 2010 app not get fixed, but they didn't fix it for the 2011 app which was a "new" app that required one to&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-151752876307827498?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/151752876307827498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=151752876307827498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/151752876307827498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/151752876307827498'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/05/not-all-mobile-apps-are-great-to-use.html' title='Not all mobile apps are great to use'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-XxksPiPrMrA/Tds7zyAxkoI/AAAAAAAAA4I/FvWSb-eKQNg/s72-c/flb_web.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4506238962621920306</id><published>2011-05-17T13:06:00.000-07:00</published><updated>2011-05-17T13:06:26.790-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>We All Love Music</title><content type='html'>Last week at Google I/O, big G finally delivered on &lt;a href="http://music.google.com/about/"&gt;Google Music&lt;/a&gt;. Well sort of. &lt;a href="http://mashable.com/2011/05/10/google-music/"&gt;As many have pointed out&lt;/a&gt;, it's taken a long time to get Music out the door, despite it being announced a year ago. What is most interesting is that it comes after Amazon made a similar offering with its &lt;a href="https://www.amazon.com/clouddrive/learnmore"&gt;Cloud Drive/Player service&lt;/a&gt;. I have no used both services along with their Android apps quite a bit. So I thought I'd share my experiences, in no particular order...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Uploading 4000 songs takes a long time. That's about how many songs I have on my MBP, and it comes out to a little more than 50 GB. I was one of the lucky attendees of I/O, so not only do I have access to Google Music, but it is currently free. Amazon gives you 5 GB, and 20 GB free if you buy an MP3 album. I did the latter. However 20 GB is not enough space for me, so I have not uploaded a lot of music to Amazon. I have done this with Google Music. It took many days, and it tends to wreck havoc on WiFi networks (which should be the subject a future blog post/rant.)&amp;nbsp;&lt;/li&gt;&lt;li&gt;The Android players are good, but both have room for improvement. Google Music has a an instant mix feature, similar to the Genius feature in iTunes. I would say that it is better than Genius for several reasons. First, it seems to do fine with "non-standard" sings. I mean stuff like Girl Talk, or remixes and live versions of popular (or not) songs. Genius fails on this consistently, maybe because these are songs (or in the case of Girl Talk, artists) that are not in iTunes? Genius also fails for newer music. Google Music seems to do fine in this situation too. The Cloud Player does not have this feature, and that is a shame. However it does have an equalizer. This is something that Google Music lacks, and that is a shame. I generally find that mobile devices (and mobile headphones, if you will) especially need equalization. The Amazon EQ is not that great though, as it only has a list of presets (Jazz, &amp;nbsp;Rock, etc.)&amp;nbsp;&lt;/li&gt;&lt;li&gt;I don't like listening to music in the browser. For desktop computers, both of these services have you open a browser and listen to music that way. I'd say that Google's is a little better, but they both seem clunky. The Amazon one does not have the equalizer that their Android app has. The sound on the Google one also seems a little better, which is counter-intuitive. It is my impression that Google may downsample your music during playback, based on bandwidth, whereas Amazon plays your music back as-is. Anyways, neither sounds as good as iTunes. Of course they aren't the ginormous mess that iTunes is either.&lt;/li&gt;&lt;li&gt;Google Music works better over crappier networks. It seems to do fine over edge, even though I *think* I can hear a difference in sound quality. This could be psychosomatic. On the other hand Amazon has a lot more noticeable pauses.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Google Music seems to manage metadata better, both metadata about songs and about collections (albums, playlists, etc.) However, I have heard other users complain about this.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I am generally pleased with both services. Since I was able to upload all of my music to Google for free, I have used it more. However it has convinced to upload more of my music to Amazon, and consider paying for it. However, that would cost me $100, since I have more than 50 GB of music.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So far I have only uploaded music from my laptop. I have about 80 GB of music on my desktop computer, though this is pretty much a superset of what is on my laptop. I am going to start the Google Music uploader on it too. Hopefully it will not do two copies of songs that are in common, and only upload the 30 GB of music that is not already present. If it does that well, and I have all of my music on their servers, it will be very tempting to pay for this service once the beta holiday ends.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These cloud based services have made me wish that I could have similar access in my car. I have an old iPod Touch (8 GB) hooked up in my glove box currently. It would be nice to have 10x capacity, but at what cost? Not to mention that the car interface (I have a large Sony head unit with a touchscreen interface) leaves a lot to be desired. That only gets worse with 10x data to deal with.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4506238962621920306?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4506238962621920306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4506238962621920306' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4506238962621920306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4506238962621920306'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/05/we-all-love-music.html' title='We All Love Music'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-65360396445532420</id><published>2011-04-19T12:39:00.001-07:00</published><updated>2011-04-19T12:39:48.092-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows phone 7'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Thoughts on Windows Phone 7</title><content type='html'>&lt;p&gt;A few weeks ago, I was contacted by a friend from Microsoft about going to a get-together that Microsoft was having. The reason for the meetup was Windows Phone 7. It was going to be at &lt;a href="http://www.alexanderssteakhouse.com/"&gt;Alexander's Steakhouse&lt;/a&gt;, which is one of the best places to eat in the Bay Area -- at least in my carnivorous opinion. So I said that I was interested, even though I had done no development for WP7. He took that as an opportunity to hook me up with an LG Quantum running the latest and greatest version of WP7 and a &lt;a href="http://www.amazon.com/Microsoft%C2%AE-Silverlight%C2%AE-Programming-Windows%C2%AE-Phone/dp/0735656673/"&gt;Programming Windows Phone 7 book&lt;/a&gt;. I figured that since MS was being so kind to invite me to such a nice place, I should at least kick the wheels on WP7. Here's my take.&lt;/p&gt;&lt;p&gt;First, here's my impression of WP7 and the LG Quantum. I will give MS props for trying out some new user experience patterns. However, I am not a fan. I do not like the left-to-right organization of apps. Often I finding myself scrolling down a page trying to read something and accidentally scrolling to the next page on the right. This would just be a minor inconvenience if scrolling back to what I was interested in was quick and easy, but unfortunately the app starts loading another screen (the page on the right) and when I go back to the left one, it has to reload. Not only does this take awhile, but it almost always loses my context of what I was reading on the left page. It really sucks.&lt;/p&gt;&lt;p&gt;The other side effect of this way of organization screens in an application is that each screen feels narrow. Worse, most screens seem to use a small font. This seems to be true of all of the apps, from the built-in ones by Microsoft to the big-name ones like Facebook, Netflix, Foursquare, and Twitter. I have a much harder time reading text on these apps than I do on their Android or iPhone cousins. I think WP7 is to blame here, these apps are consistent with the platform and that's why they make me squint.&lt;/p&gt;&lt;p&gt;That last paragraph is clearly influenced by my experience with writing code for WP7. However, I would say that the development situation on WP7 is generally pretty good. The worst part is the "getting started". For me this involved installing Windows 7 on my MBP. I already had Parallels on there fortunately, but not Win7. Once I had Win7 running under Parallels, I followed the WP7 &lt;a href="http://create.msdn.com/en-us/home/getting_started"&gt;getting started guide&lt;/a&gt;. I was a little annoyed to see this involved a three-step download/install process. First download the WP7 developer tools. Then install the WP7 developer tools January 2011 update. And then install the WP7 developer tools fix! Really? Why in this not all one download? Why does that third download even (the "tools fix") even exist?&lt;/p&gt;&lt;p&gt;I've always thought that the Android tools installation process left a lot to be desired. But at least they had a reasonable excuse that IDE support was optional. So you could just install the SDK, but you had additional steps if you wanted to use either Eclipse or IDEA (and you got options here, which is nice.) Things are much better on iOS, but there are a lot less options there. WP7 is the worst of all worlds, as there are no options, but you have three installs including a "fix". Oh wait there are options, but they are for using Visual Basic which also requires that you use the "Pro" version of the tools. I'm not a big fan of an up-sale when it comes to developer tools. Do you want me to build for your platform? Make it easy and make it free until I want to publish something.&lt;/p&gt;&lt;p&gt;So there's my big gripe with the tools. Otherwise they are very good. If you've ever used Visual Studio, you know that it has a lot of nice features. The book mentioned earlier is a good companion too. Of course when you tie development so closely to a tool, then a book gets old fast, but for now it works. I wrote a neat little program that downloaded and parsed some XML and then used data binding to show the results in a list. Tapping on items in the list could bring up more information or open an external browser link. It was sweet and the tools made the development go by fast. I think this (along with the tightly integrated designer tools) may be WP7's biggest asset. There is no doubt in my mind that if you want to build some very "standard" looking apps, you can do it much faster on WP7 than on Android or iOS. It's not even close.&lt;/p&gt;&lt;p&gt;However the tale of the tools does not have a happy ending. I got my little app to run on the emulator, and I was pleased that the emulator loaded quickly and was responsive. However I don't trust emulators (and you should not either), so I was eager to run the app on the LG Quantum. However when I tried, I got an error saying "Zune software is not installed." Lucky for me that developing for WP7 was just a hobby, so I could laugh at this WTF error.&lt;/p&gt;&lt;p&gt;I have one last critique of WP7, and actually this came from Matt Trunnell. He's a bad-ass WP7/Silverlight developer who works for Netflix and wrote their WP7 app. We met at the MS event I mentioned at the beginning and shared with me some of his perspectives on WP7. I stated that I thought that MS seemed to be trying to "out Apple, Apple". What I meant was that they had followed Apple's lead on most issues, from how the OS ran, to what developers could do, etc. However Matt made me realize that I was wrong about this. He pointed out that MS had really done a lot of "triangulation" where they had tried to find middle ground between how Apple and Google had done things. An example of this is the multitasking in WP7 (well coming this fall to WP7.) MS adopted&lt;a href="http://fupeg.blogspot.com/2010/06/ios-multitasking.html"&gt; the pseudo-multitasking&lt;/a&gt; (fast app switching) of the iPhone, but also included "Live Agents" that could run in the background, but only in a limited way that is beyond the developer's control.&lt;/p&gt;&lt;p&gt;I think I have become immersed in the Android world so much that Microsoft's triangulation seemed like being very Apple-ish to me. But Matt was right on. MS has very consistently tried to "learn" from Apple and Google and come up with a best-of-both worlds approach. There are some very good things about this kind of strategy (you *should* learn from your competitors) but ultimately it is frustrating. Everything always seems second-rate.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-65360396445532420?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/65360396445532420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=65360396445532420' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/65360396445532420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/65360396445532420'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/04/thoughts-on-windows-phone-7.html' title='Thoughts on Windows Phone 7'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1199147545721203431</id><published>2011-04-05T12:25:00.001-07:00</published><updated>2011-04-05T12:25:07.109-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Fragmentation? What fragmentation?</title><content type='html'>&lt;p&gt;Fragmentation is a fun word to use in the mobile space. The devotees of Apple and the iPhone delight in the term because it makes Android aficionados cringe. Heck even the executives at Apple use the term at every opportunity. Some of the folks on the Android team &lt;a href="http://android-developers.blogspot.com/2010/05/on-android-compatibility.html"&gt;deny it exists&lt;/a&gt;. However in &lt;a href="http://tech.fortune.cnn.com/2011/04/04/android-is-a-mess-say-developers/"&gt;a recently published study&lt;/a&gt;, most Android developers say it is a real problem. So what's the deal?&lt;/p&gt;&lt;p&gt;As with so many other contentious things in this world, a lot comes down to how you define something. If you write an Android application, you will have to test it on multiple devices. So I will use this as my definition of fragmentation. So obviously Android suffers from fragmentation. Here is a simple example of it:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="tboltsucks.png" src="http://lh6.ggpht.com/_XmwdENwf53s/TZtow9F71aI/AAAAAAAAA38/ddUMSg0UpVA/tboltsucks.png?imgmax=800" border="0" alt="HTC Thunderbolt winning" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;This is a screenshot of an app running on the HTC Thunderbolt. According to some folks, &lt;a href="http://www.slashgear.com/htc-thunderbolt-sales-surpass-the-iphone-4-at-verizon-stores-says-analyst-01143950/"&gt;it is selling quite well&lt;/a&gt;. What's the point of the screenshot? Well take a look at the text field right below the "Your phone number" prompt. Here is the code for it:&lt;/p&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;EditText&lt;br /&gt;	android:layout_height="wrap_content"&lt;br /&gt;	android:layout_width="fill_parent"&lt;br /&gt;	android:id="@+id/entry_phone"&lt;br /&gt;	android:textStyle="bold"&lt;br /&gt;	android:inputType="phone"&lt;br /&gt;	android:imeOptions="actionNext"&lt;br /&gt;/&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;See the problem? WTF is up with those zeros in the field? They clearly should not be there. This was the only phone I could find that produced this problem, but I will have to add code just to deal with this annoyance. This is fragmentation. Code has to be tested on many devices, and you may have to put in some device-specific things to get the app to work the same.&lt;/p&gt;&lt;p&gt;Now don't be fooled, fragmentation exists on all mobile platforms. Yes, even iOS. There is less of it, but it is not insignificant. Fragmentation is quite prominent on almost all application platforms. Do not get any web developer started about IE specific CSS for example.&lt;/p&gt;&lt;p&gt;So it is a huge problem on Android? My answer to that question is irrelevant, as the perception that it is a problem is all that does matter. I think this perception is completely reasonable. Many Android developers were programming for the iPhone in the past, and were used to testing on a single iPhone and nothing else. Thus &lt;a href="http://news.cnet.com/8301-30685_3-20023199-264.html"&gt;Android seems arduous&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1199147545721203431?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1199147545721203431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1199147545721203431' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1199147545721203431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1199147545721203431'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/04/fragmentation-what-fragmentation.html' title='Fragmentation? What fragmentation?'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_XmwdENwf53s/TZtow9F71aI/AAAAAAAAA38/ddUMSg0UpVA/s72-c/tboltsucks.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1684522765506582611</id><published>2011-03-18T07:36:00.001-07:00</published><updated>2011-03-18T07:36:20.928-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ebay'/><category scheme='http://www.blogger.com/atom/ns#' term='bump'/><title type='text'>My Last Day at eBay</title><content type='html'>&lt;p&gt;&lt;img style="float: right;" title="NewImage.png" src="http://lh3.ggpht.com/_XmwdENwf53s/TYNt0fk6lnI/AAAAAAAAA30/4FHG25XS5Xo/NewImage.png?imgmax=800" border="0" alt="This is The End" width="500" height="377" /&gt;&lt;/p&gt;&lt;p&gt;Today is my last day at eBay. I have been there for nearly four years and it has been a remarkable experience. When I joined eBay, I had come from a startup called Ludi Labs. One thing I realized while at Ludi Labs was that "scalability" was largely a hypothetical term to me. I thought I understood the keys to making an application function at web scale, but it unfortunately it was very theoretical knowledge. None of the startups I had worked at had ever really hit that kind of scale. Hence my interest in working a large scale web company, like eBay.&lt;/p&gt;&lt;p&gt;Four years later and I realize how very limited my theoretical knowledge of scalability really was. Sure I understood the basic principles, but there are definitely many subtleties involved in implementing these principles. I won't now claim to be a scalability expert, but I have certainly learned some real world lessons.&lt;/p&gt;&lt;p&gt;When I first joined eBay, I worked with the infrastructure team on eBay's homegrown presentation technology. A lot of this technology was based on what works at scale: high volume web pages, working in dozens of different languages, running on servers spread across multiple data centers, and built by hundreds of engineers around the globe. I went on to help many of the different teams at eBay adopt and optimize their use of eBay's presentation technology. As such I got opportunities to work on many of the major pages of eBay: home page, search results, view item, my eBay, just to name a few. Often my experience was limited to helping the team solve some site speed issues, but I still got a chance to understand how each of these highly complex web pages could function at massive scale.&lt;/p&gt;&lt;p&gt;Of course the last couple of years of my career at eBay was dominated by mobile. It's been an exciting time, as our mobile team saw massive growth both in terms of users and their usage (measured using the best possible metric: money) as well as in terms of the team behind the technology. It's had some great moments as well, such as seeing &lt;a href="http://www.fastcompany.com/most-innovative-companies/2011/top-10-mobile.php"&gt;eBay named by Fast Company as the #2 most innovative company in mobile&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This leads to the obvious question of why I am leaving eBay. The future for mobile at eBay is very bright. However it's one of those cases where the change is not about where I'm coming from, but about where I'm going. In this case that's &lt;a href="http://bu.mp/"&gt;Bump Technologies&lt;/a&gt;. I'm very excited about the opportunity at Bump. They already have a great product that they've built in just two years. However, I think that two years from now the current product will look very limited in comparison. It's going to be an exciting time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1684522765506582611?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1684522765506582611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1684522765506582611' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1684522765506582611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1684522765506582611'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/03/my-last-day-at-ebay.html' title='My Last Day at eBay'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_XmwdENwf53s/TYNt0fk6lnI/AAAAAAAAA30/4FHG25XS5Xo/s72-c/NewImage.png?imgmax=800' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-8731229881072126942</id><published>2011-03-02T17:21:00.001-08:00</published><updated>2011-03-03T15:27:33.368-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='honeycomb'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Honeycomb Drag and Drop Basics</title><content type='html'>&lt;p&gt;If you are thinking about developing an Android tablet app, one of the most exciting things has got to be the &lt;a href="http://developer.android.com/guide/topics/ui/drag-drop.html"&gt;drag and drop capabilities&lt;/a&gt; that were added to Android as part of Honeycomb. No wait a minute, aren't there a lot more interesting features than drag and drop in Honeycomb? There are definitely a lot of great features, but drag and drop is one of the most interesting in my opinion. It's a perfect fit for tablets, where you can have this nice big graphical objects to drag and drop. I think it really challenges mobile designers and developers to rethink our interaction models. If you read through that tutorial I just linked to, you will learn about many of the intricacies of drag and drop Android style. I thought I'd provide an even simpler example for those of you who prefer the Cliff Notes versions of things.&lt;/p&gt;&lt;p&gt;First we will start with a simple UI, a 2x2 grid with a cute little image that we will drag and drop around this grid. Here is what it looks like:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="dnd0.png" src="http://lh4.ggpht.com/_XmwdENwf53s/TW7nM1BGcwI/AAAAAAAAA3g/7pgXLj1cViE/dnd0.png?imgmax=800" border="0" alt="DnD UI" width="600" height="375" /&gt;&lt;/p&gt;&lt;p&gt;I used a simple TableLayout for this, along with some basic border background Drawables. Here's the XML for it:&lt;/p&gt;&lt;pre class="brush:xml"&gt;&amp;lt;TableLayout&lt;br /&gt;  xmlns:android="http://schemas.android.com/apk/res/android"&lt;br /&gt;  android:layout_width="match_parent"&lt;br /&gt;  android:layout_height="match_parent"&gt;&lt;br /&gt;  &amp;lt;TableRow&gt;&lt;br /&gt;    &amp;lt;LinearLayout android:layout_width="640px"&lt;br /&gt;        android:layout_height="345px"&lt;br /&gt;        android:id="@+id/topLeft"&lt;br /&gt;        android:background="@drawable/border"&gt;&lt;br /&gt;        &amp;lt;ImageView android:id="@+id/droid"&lt;br /&gt;            android:src="@drawable/bugdroid"&lt;br /&gt;            android:layout_width="150px"&lt;br /&gt;            android:layout_height="150px"&lt;br /&gt;         /&gt;&lt;br /&gt;    &amp;lt;/LinearLayout&gt;&lt;br /&gt;    &amp;lt;LinearLayout android:layout_width="640px"&lt;br /&gt;        android:layout_height="345px"&lt;br /&gt;        android:id="@+id/topRight"&lt;br /&gt;        android:background="@drawable/border2"&lt;br /&gt;    /&gt;    &lt;br /&gt;  &amp;lt;/TableRow&gt;&lt;br /&gt;  &amp;lt;TableRow&gt;&lt;br /&gt;    &amp;lt;LinearLayout android:layout_width="640px"&lt;br /&gt;        android:layout_height="345px"&lt;br /&gt;        android:id="@+id/bottomLeft"&lt;br /&gt;        android:background="@drawable/border2"&lt;br /&gt;    /&gt;&lt;br /&gt;    &amp;lt;LinearLayout android:layout_width="640px"&lt;br /&gt;        android:layout_height="345px"&lt;br /&gt;        android:id="@+id/bottomRight"&lt;br /&gt;        android:background="@drawable/border"&lt;br /&gt;    /&gt;    &lt;br /&gt;  &amp;lt;/TableRow&gt;  &lt;br /&gt;&amp;lt;/TableLayout&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Nothing special so far. All of the magic happens in the code. Here's the basics of the Activity that uses this XML.&lt;/p&gt;&lt;pre class="brush:java"&gt;public class DndActivity extends Activity {&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; protected void onCreate(Bundle savedInstanceState) {&lt;br /&gt;  super.onCreate(savedInstanceState);&lt;br /&gt;  setContentView(R.layout.grid);&lt;br /&gt;  View droid = findViewById(R.id.droid);&lt;br /&gt;  droid.setOnLongClickListener(new OnLongClickListener(){&lt;br /&gt;   @Override&lt;br /&gt;   public boolean onLongClick(View v) {&lt;br /&gt;    ClipData data = ClipData.newPlainText("foo","bar");&lt;br /&gt;    DragShadowBuilder shadowBuilder = new DragShadowBuilder();&lt;br /&gt;    v.startDrag(data, shadowBuilder, v, 0);&lt;br /&gt;    return true;&lt;br /&gt;   }&lt;br /&gt;  });&lt;br /&gt;  findViewById(R.id.topLeft).setOnDragListener(new BoxDragListener());&lt;br /&gt;  findViewById(R.id.bottomLeft).setOnDragListener(new BoxDragListener());&lt;br /&gt;  findViewById(R.id.topRight).setOnDragListener(new BoxDragListener());&lt;br /&gt;  findViewById(R.id.bottomRight).setOnDragListener(new BoxDragListener());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Here we just set the contentView, then we get a handle on the droid image. We set its onLongClickListener. I think the long click will become the de facto way to initiate drag and drop in Android apps. You could use some other event of course, but long click feels right. The key thing we need to do to initiate drag and drop is invoke the startDrag method. To do that, we have to create a ClipData object and DragShadowBuilder. You can use the ClipData to put all kinds of interesting data/metadata that will be passed around to the drop zones (Views) in your app. In this case I didn't need anything fancy, so I put something minimal and arbitrary. For the DragShadowBuilder, you might want to do something fancy to make the dragging look cool. I used a default one and it doesn't do much at all. You also need to set a "localData" object. This can be anything. Since my local data is the image itself, I chose to pass the ImageView that will be passed in to the onLongClick method. Now you can call startDrag. Finally, make sure you return true to let the OS know that drag and drop is a go.&lt;/p&gt;&lt;p&gt;Next in the code you will see that for each of the cells in my table, I have set an OnDragListener object. I've set this to a new instance of BoxDragListener for each of the cells. This is an inner class of DndActivity:&lt;/p&gt;&lt;pre class="brush:java"&gt;class BoxDragListener implements OnDragListener{&lt;br /&gt; boolean insideOfMe = false;&lt;br /&gt; Drawable border = null;&lt;br /&gt; Drawable redBorder = getResources().getDrawable(R.drawable.border3);&lt;br /&gt; @Override&lt;br /&gt; public boolean onDrag(View self, DragEvent event) {&lt;br /&gt;  if (event.getAction() == DragEvent.ACTION_DRAG_STARTED){&lt;br /&gt;   border = self.getBackground();&lt;br /&gt;   self.setBackgroundDrawable(redBorder);&lt;br /&gt;  } else if (event.getAction() == DragEvent.ACTION_DRAG_ENTERED){ &lt;br /&gt;   insideOfMe = true;&lt;br /&gt;  } else if (event.getAction() == DragEvent.ACTION_DRAG_EXITED){&lt;br /&gt;   insideOfMe = false;&lt;br /&gt;  } else if (event.getAction() == DragEvent.ACTION_DROP){&lt;br /&gt;   if (insideOfMe){&lt;br /&gt;    View view = (View) event.getLocalState();&lt;br /&gt;    ViewGroup owner = (ViewGroup) view.getParent();&lt;br /&gt;    owner.removeView(view);&lt;br /&gt;    LinearLayout container = (LinearLayout) self;&lt;br /&gt;    container.addView(view);&lt;br /&gt;   }&lt;br /&gt;  } else if (event.getAction() == DragEvent.ACTION_DRAG_ENDED){&lt;br /&gt;   self.setBackgroundDrawable(border);     &lt;br /&gt;  }&lt;br /&gt;  return true;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;This guy will get a stream of DragEvents fired at its onDrag method. You can determine what kind of DragEvent it is by calling getAction on the event. The first one you will get is an ACTION_DRAG_STARTED event. For this we want to change the border of our cell to red to let the user know that they can drop the image in this cell. Here's what that looks like:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="dnd1.png" src="http://lh6.ggpht.com/_XmwdENwf53s/TW7rW3usHHI/AAAAAAAAA3o/uu2in55dXsA/dnd1.png?imgmax=800" border="0" alt="Enter the red zone" width="600" height="375" /&gt;&lt;/p&gt;&lt;p&gt;Next we want to keep track if the user's finger has entered into a drop zone. So we look for the ACTION_DRAG_ENTERED and toggle a local boolean. Similarly, we look for ACTION_DRAG_EXITED in case the user changed their mind and picked a different zone to drop the image into. Next we look for the ACTION_DROP. If the object is inside our drop zone, then we update the UI by removing it from its previous parent and adding it to the drop zone. Finally, we listen for ACTION_DRAG_ENDED to know when the drag and dropping is finished. We then restore the borders to their original color. That's it!&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; The code above will not draw a shadow when you drag the image around the screen. There is a very easy way to get a shadow and that is to pass the View to it the DragShadowBuilder constructor, i.e. new DragShadowBuilder(v); in the above code. That will cause the image in the sample app to be used as the shadow. Be careful using this technique though. If the View that you are dragging is big/complex, then you might take a performance hit (UI becomes sluggish.) In that case you might want to subclass DragShadowBuilder and override its onDragShadow method to draw something simpler for the shadow. I've been playing around with this and StackViews however, and it has worked great with no need to subclass DragShadowBuilder. Be sure to set the android:hardwareAccelerated="true" attribute in your AndroidManifest.xml either on the Activity or the whole Application.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-8731229881072126942?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/8731229881072126942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=8731229881072126942' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8731229881072126942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8731229881072126942'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/03/honeycomb-drag-and-drop-basics.html' title='Honeycomb Drag and Drop Basics'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_XmwdENwf53s/TW7nM1BGcwI/AAAAAAAAA3g/7pgXLj1cViE/s72-c/dnd0.png?imgmax=800' height='72' width='72'/><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-8593787925339981517</id><published>2011-02-18T17:57:00.001-08:00</published><updated>2011-02-18T17:57:38.122-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='obama'/><category scheme='http://www.blogger.com/atom/ns#' term='war'/><category scheme='http://www.blogger.com/atom/ns#' term='iraq'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Why I Won't be Voting for President Obama in 2012</title><content type='html'>&lt;p&gt;I voted for President Obama in 2008. &lt;a href="http://fupeg.blogspot.com/2008/09/distractions.html"&gt;My reasons&lt;/a&gt; were a little different than most. Given that and one look at this chart, it should be no surprise that he won't be getting my vote in 2012.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="chart_1 (1).png" src="http://lh5.ggpht.com/_XmwdENwf53s/TV8iwTC4NWI/AAAAAAAAA3Y/NG-Kp97wZ-E/chart_1%20%281%29.png?imgmax=800" border="0" alt="Money Spent on War" width="600" height="371" /&gt;&lt;/p&gt;&lt;p&gt;Seriously, if McCain had won do you really think this chart would look a lot different? The withdrawal of US troops from Iraq was widely hailed, but it has been made up for by increasing troops in Afghanistan and using more private military companies (mercenaries) in both Iraq and Afghanistan. Fool me once, shame on you; fool me twice...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-8593787925339981517?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/8593787925339981517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=8593787925339981517' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8593787925339981517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8593787925339981517'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/02/why-i-won-be-voting-for-president-obama.html' title='Why I Won&amp;#39;t be Voting for President Obama in 2012'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_XmwdENwf53s/TV8iwTC4NWI/AAAAAAAAA3Y/NG-Kp97wZ-E/s72-c/chart_1%20%281%29.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-8478973340487127513</id><published>2011-02-18T14:34:00.001-08:00</published><updated>2011-02-18T14:34:10.317-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Ginger Honey Ice Cream Mess</title><content type='html'>&lt;p&gt;A few nights ago I was working at the &lt;a href="http://www.android-android.net/"&gt;Silicon Valley Android Meetup&lt;/a&gt;. eBay was hosting the meetup, and I had volunteered to help with the registration table. One of my co-workers was talking about how very few people had brought business cards with them to the event (there was a raffle and you could use your business card to enter it), and I commented that business cards were antiquated. I mentioned &lt;a href="http://bu.mp/"&gt;Bump&lt;/a&gt; as one of many more sophisticated alternatives. She quickly downloaded Bump to her Android phone, and we attempted to ... well ... Bump. We had a hard time mainly because the accelerometer on her phone was not very sensitive.&lt;/p&gt;&lt;p&gt;She remarked: "I really need a new phone."&lt;/p&gt;&lt;p&gt;I asked: "Yeah what's that thing running, like Android 1.6?"&lt;/p&gt;&lt;p&gt;She replied: "I wish, it's actually 1.5."&lt;/p&gt;&lt;p&gt;Now I was actually kind of amazed that Bump even worked on a 1.5 phone. But before I could make some witty comment about her phone...&lt;/p&gt;&lt;p&gt;She asked: "What is the latest version anyways?"&lt;/p&gt;&lt;p&gt;I replied immediately: "2.3"&lt;/p&gt;&lt;p&gt;She gasped is disbelief: "Holy crap, I've only had the phone for a year or so. Do they release a new version of Android every month or something?"&lt;/p&gt;&lt;p&gt;Who can blame her for her dismay at the velocity of Android? She went on to curse the phone maker (Samsung) and network (Sprint) for not putting out an update (though I think they did, but not OTA? Anyways, you should be able to guess the model now.) Of course who can blame handset makers and carriers for being slow to put out updates, again given the pace of Android. As soon as you get done getting one version ready to ship, another one comes out.&lt;/p&gt;&lt;p&gt;Of course that's part of the fun from a developer standpoint. And part of the pain -- a big part. However the mach speed evolution of Android in the past is starting to look downright soothing compared to the &lt;a href="http://en.wikipedia.org/wiki/Glossary_of_The_Dark_Tower#Thinny"&gt;thinny&lt;/a&gt; before us. Let's recap briefly&lt;/p&gt;&lt;p&gt;In December 2010, Google announced Android 2.3 a.k.a. Gingerbread. This seemed all well and good at the time. Android 2.2 (Froyo) came out half a year earlier, so this seemed like a reasonable amount of time between releases. Of course we would later learn that the Android team was not pacing themselves, the long time between releases was a fluke. Anyways, the timing still seemed a little odd, as it was right before the holidays. The Nexus S was simultaneously released and it was running 2.3. Still there was no way any other Gingerbread running devices would be out in stores for the holiday season. Also, there seemed to be a lot of oft-rumored stuff missing from Gingerbread.&lt;/p&gt;&lt;p&gt;In early January (a month later), Android 3.0 a.k.a. Honeycomb was previewed at CES. Videos of Honeycomb in action were posted to YouTube. Three weeks later, a preview version of the SDK was made available to developers. It had a lot of the new UI features that had been rumored for Gingerbread. However, it didn't just bolt on new features or refine existing APIs. It added some very core fundamental things. There were Fragments: a new (better?) way to organize your application code. There was the app bar: a persistent UI element at the top of the screen where contextual extras could be placed. The app bar is what the menu should have been (nobody uses the menu.) There was also the system bar at the bottom of the screen. This is not directly accessible to developers, however it is where Honeycomb's new more powerful notifications originate from. Android already had the best notification system out there (sorry webOS and your new imitator, Windows Phone ... and iOS is not even in the conversation), but now you get notifications that the use can interact with without interrupting what they were doing. Anyways, 3.0 is a release unlike any other in Android's history, but mostly in a good way. However it was billed as being just for tablets, leaving us with two different "latest" versions of Android.&lt;/p&gt;&lt;p&gt;In February (just this week) we get comments from exiting CEO Eric Schmidt that Gingerbread and Honeycomb were merging together in the "I" release of Android. This was release has been "known" to be Ice Cream Sandwich for awhile. Would it be Android 2.4? Would it come out at Google IO?&lt;/p&gt;&lt;p&gt;But wait, it gets better. Apparently Android 2.4 will be released before Google IO, and it will not be Ice Cream Sandwich. We will have to wait for the sandwich until later in the year apparently.&lt;/p&gt;&lt;p&gt;So what the hell is going on? First let me say this. I have been using a Nexus S for about a month now. When it works (which is most of the time), it is fantastic, easily the best phone I've ever used. However, it is also the buggiest phone I have ever used. I've never had the reported spontaneous reboot happen to me during a call (by the way the call quality is excellent, the best I've ever had in a smartphone.) However, I often have to reboot it myself because it just hangs during a call. Or it will suddenly lose its network connection and never get it back until ... I reboot it. Or it will stop receiving email (service probably crashing and the OS putting it out of its memory I'm guessing) until ... I reboot it. Since this phone is very similar to the Galaxy S in terms of hardware, I am guessing that this is mostly a software issue. And since this baby is running "stock" Android, that makes it a Gingerbread issue. Maybe this explains why 2.3 has not been released to any phone? Maybe this explains the need for yet another major release before the Ice Cream Merge?&lt;/p&gt;&lt;p&gt;Besides the 2.3 issues, most of the rest of the craziness comes from the need to go after tablets in a big way. That's why a lot of in-flux, potentially undercooked code is being pushed out so quickly. That's why we all get to see git repo being forked and merged in such a public manner. Software development is scary and messy more often than not.&lt;/p&gt;&lt;p&gt;So back to the scorecard. It makes sense that 2.4 will not be Ice Cream Sandwich. It can't include the Honeycomb features and yet have a lower release number, right? Perhaps Ice Cream Sandwich will be 3.1, later this summer. Or maybe it will be 3.2, as I would not be surprised if there were a massive bug fix release after 3.0, given its obviously rushed nature. So maybe we can go 2.3, 2.4. 3.0, 3.1, 3.2 all in the span of what, 6 or 9 months? Yee haw!!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-8478973340487127513?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/8478973340487127513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=8478973340487127513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8478973340487127513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8478973340487127513'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/02/ginger-honey-ice-cream-mess.html' title='Ginger Honey Ice Cream Mess'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-927349167816950473</id><published>2011-02-13T11:51:00.001-08:00</published><updated>2011-02-13T11:51:38.280-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='user experience'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Wither the Dashboard Pattern</title><content type='html'>&lt;p&gt;Recently I barely managed to register for this year's Google IO conference. One of my favorite sessions from last year's conference was on &lt;a href="http://www.google.com/events/io/2010/sessions/android-ui-design-patterns.html"&gt;UI patterns in Android&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;iframe src="http://www.youtube.com/embed/M1ZBjlCRfz0" width="640" height="390" frameborder="0"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;It's a great video, you should definitely watch it. The first pattern that they talk about is the Dashboard. You can see their example of a dashboard in the video, but there was an even more concrete example: &lt;a href="https://market.android.com/details?id=com.twitter.android"&gt;Twitter for Android&lt;/a&gt;. The Twitter app was released just before IO, and it was developed jointly by Google and Twitter. It showcased the UI patterns that Google wanted designers and developers to start using to help create some expectations for users. Here's the Twitter dashboard:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="twitter-old.png" src="http://lh6.ggpht.com/_XmwdENwf53s/TVgjxFgRDsI/AAAAAAAAA2Q/WbUQvj8tNqY/twitter-old.png?imgmax=800" border="0" alt="Ye olde Twitter with dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;The idea is simple. The home screen of your app provides shortcuts to all of the major components of the app. The combination of using this pattern in a popular app (Twitter has 5M+ downloads) and evangelizing it at the IO conference certainly had the desired results. Many other apps adopted the pattern, including every platform's most popular app, &lt;a href="https://market.android.com/details?id=com.facebook.katana"&gt;Facebook&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="fb.png" src="http://lh6.ggpht.com/_XmwdENwf53s/TVgk2d5spJI/AAAAAAAAA2U/aONNk2SWL30/fb.png?imgmax=800" border="0" alt="Facebook's dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;The pattern has been a hit with note-taking/organizer apps like &lt;a href="https://market.android.com/details?id=com.evernote"&gt;Evernote&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="evernote.png" src="http://lh6.ggpht.com/_XmwdENwf53s/TVglKSGs2bI/AAAAAAAAA2c/tIralkD0Quk/evernote.png?imgmax=800" border="0" alt="Evernote's dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;Evernote's more recent competitor &lt;a href="https://market.android.com/details?id=com.springpad"&gt;Springpad&lt;/a&gt; also uses a dashboard:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="springpad.png" src="http://lh6.ggpht.com/_XmwdENwf53s/TVglivffwmI/AAAAAAAAA2g/zS7e3Cm58rg/springpad.png?imgmax=800" border="0" alt="Springpad's dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;Evernote and Springpad are both popular apps, with more than 1.5M downloads between them. Another very popular app that uses the dashboard is &lt;a href="https://market.android.com/details?id=com.yelp.android"&gt;Yelp&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="yelp.png" src="http://lh3.ggpht.com/_XmwdENwf53s/TVgmYml8svI/AAAAAAAAA2o/oxxON47sZT8/yelp.png?imgmax=800" border="0" alt="Yelp's dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;Google's Yelp/Foursquare compettitor Places also uses the dashboard pattern:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="places.png" src="http://lh4.ggpht.com/_XmwdENwf53s/TVgoTnBRf7I/AAAAAAAAA20/ho6ejI6Wwak/places.png?imgmax=800" border="0" alt="Places' dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;Finally, there's my favorite Android music player &lt;a href="https://market.android.com/details?id=com.mixzing.basic"&gt;MixZing&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="mxz.png" src="http://lh5.ggpht.com/_XmwdENwf53s/TVgm0pNqgRI/AAAAAAAAA2s/J8nxyvwx19w/mxz.png?imgmax=800" border="0" alt="MixZing's dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;MixZing shows that you can be a little creative with the dashboard pattern. So the pattern's been a big success, right? Users are familiar with it and developers have embraced it. So it was a little surprising to me to see that Twitter has now decided that the dashboard is not so good after all:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="twitter-new.png" src="http://lh4.ggpht.com/_XmwdENwf53s/TVgowhBFwFI/AAAAAAAAA24/cFsR5RgZuJo/twitter-new.png?imgmax=800" border="0" alt="New Twitter, sans dashboard" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;There's no more dashboard in the 2.0 version of Twitter's app. The release notes allude to the major problem with the dashboard pattern: it forces the user to constantly go to the dashboard if they want to navigate to a different part of the app. It makes everything at least two taps away. Of course it makes it easy for the user to find things, since they can just go to the dashboard to find a shortcut to whatever they are looking for. For example, how do you think you find what's trending on the Twitter app now (go to search) or view your profile (gotta use the dreaded Android menu)? Maybe Twitter has found that their users rarely use these features, so the new design will be more effective for the vast majority of their users.&lt;/p&gt;&lt;p&gt;Speaking of the new design, it obviously uses a &lt;a href="http://developer.android.com/resources/tutorials/views/hello-tabwidget.html"&gt;tab layout&lt;/a&gt;. This is a more common UI pattern in Android and has its own set of APIs to make it easy to use for developers. There are a lot of examples of tab layouts out there, such as &lt;a href="https://market.android.com/details?id=com.joelapenna.foursquared"&gt;Foursquare&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="4sq.png" src="http://lh3.ggpht.com/_XmwdENwf53s/TVgtoejNo3I/AAAAAAAAA3A/AArLmiObCUI/4sq.png?imgmax=800" border="0" alt="Foursquare likes tabs" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;Another example is one of my favorite apps, &lt;a href="https://market.android.com/details?id=com.bumptech.bumpga"&gt;Bump&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="bump.png" src="http://lh6.ggpht.com/_XmwdENwf53s/TVguTSoovkI/AAAAAAAAA3E/H9X0_9WDDVI/bump.png?imgmax=800" border="0" alt="Bump likes tabs" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;I won't bore you with more examples, as there are a lot. I think it's often very comfortable for a web app going native to use a tab design. It often mimics their website. That's why I picked Foursquare and Bump, two apps that are what I would consider mobile-first. Most people's first interaction with either company is through their mobile apps, not through their desktop web browser.&lt;/p&gt;&lt;p&gt;The other common pattern worth mentioning briefly is what I call Listomania. You start off with lists, and keep going from there like traversing a tree. Here's &lt;a href="https://market.android.com/details?id=com.google.android.apps.reader"&gt;Google Reader&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="reader.png" src="http://lh4.ggpht.com/_XmwdENwf53s/TVgyURruN8I/AAAAAAAAA3M/24Ot6UuPRc0/reader.png?imgmax=800" border="0" alt="Google Reader likes lists" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;And here's &lt;a href="https://market.android.com/details?id=com.kayak.android"&gt;Kayak's&lt;/a&gt; listomania:&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="kayak.png" src="http://lh5.ggpht.com/_XmwdENwf53s/TVgzIRhz7rI/AAAAAAAAA3Q/kqy76d0OD18/kayak.png?imgmax=800" border="0" alt="Kayak likes lists" width="360" height="600" /&gt;&lt;/p&gt;&lt;p&gt;Personally I don't find the Listomania format very user friendly. I think it is often a by-product of porting an iPhone app that makes heavy use of &lt;a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html"&gt;UINavigationControllers&lt;/a&gt; (in all fairness, many of the tab-using Android apps are the products of porting iPhone apps that used a &lt;a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITabBarController_Class/Reference/Reference.html#//apple_ref/occ/cl/UITabBarController"&gt;UITabBarController&lt;/a&gt;). I think the dashboard usually solves the same kind of problem (lots of features, hierarchy) in a nicer way. The tab alternative is more of the Pareto principle, putting all of the focus on the most commonly used features. Anyways, it will be interesting to see if the dashboard pattern becomes less common now that it's poster-child has ditched it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-927349167816950473?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/927349167816950473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=927349167816950473' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/927349167816950473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/927349167816950473'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/02/wither-dashboard-pattern.html' title='Wither the Dashboard Pattern'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/M1ZBjlCRfz0/default.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4903245459734572491</id><published>2011-02-11T17:13:00.001-08:00</published><updated>2011-02-11T17:13:17.391-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c2dm'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android Notifications, C2DM, and The Way to Succeed and the Way to Suck Eggs</title><content type='html'>&lt;p&gt;When it comes to Android Cloud-to-Device Messaging, I've found many new and exciting ways to fail and fail hard. So y'know, learn from my failure and stuff:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;State: To Have or Not To Have, That is The Question&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are a lot of cool things you can do with C2DM, but of course notifications are one of the most common and most important things. Now remember that unlike on other inferior platforms, you get total control of what happens when a message is pushed to your application via C2DM. So you don't have to show a notification at all. In case you do though, the first thing you need to decide is if your notifications will be stateful or stateless.&lt;/p&gt;&lt;p&gt;What's the difference? Glad you asked. Let's take a simple scenario. A message is pushed to your app via C2DM, and you display a notification to the user. Now Android notifications do not force the user to either open or dismiss the notification. In my opinion that is a very good thing, and I think most folks agree. You might really be interested in a particular notification, but sometimes you've just gotta finish that game of Meteor Blitz or finish posting a crazy picture to picplz. That's not a problem on Android. The sound will go off, the ticker text will scroll across the status bar, and then a simple icon will appear up there and the user can deal with the notification at their convenience. However, let's say that a few minutes later that another message is pushed to your app via C2DM and once again you need to notify the user of this. If you choose a stateless system, then you will simply replace the current notification about message #1 with a new one about message #2. Alternatively you could post a new notification about message #2 that would sit along side the notification about message #1. However if you do this, then you are a schmuck. You've just created an application that can potentially flood the status bar with your notifications. Your app would have be to all kinds of awesome for me to keep it on my phone, especially if I can't turn off your notifications. So don't do that. So really there's only one option if you want to go stateless: most recent notification always wins and anything older goes to the trash.&lt;/p&gt;&lt;p&gt;Don't like that approach? Me neither. That first notification might have nothing to do with the second, and it might be more important. So that means we need to go stateful. With a stateful system, we can remember that we received message #1, and then replace it with a notification that indicates that we have received message #1 and message #2. How you do that will be very specific to your application of course, but you can figure something out. The point is that you persisted the state, that you had received message #1 and it has not been viewed yet, and you use this knowledge to provide a better experience for the user when message #2 rolls in. Of course now the real fun begins.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Watch out for the Clear Button &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;You need to not only keep track of the messages that you have received via C2DM, but also their state. Has the user seen them or not? What constitutes "seen" is again specific to your application, but it just means that at various places in your application you will need "mark as seen" for certain messages. There is gotcha here and that is the "Clear" button on the status bar. That should have the effect of marking all messages as seen. However, how do you know when the user taps this button? I thought that maybe there was an Intent fired and that I could receive this with a BroadcastReceiver with the proper action/Intent filter. I searched the docs and found no such action, but I still thought that this was probably the case and it was just not documented (there are a lot of such Intent/actions!) I was so stumped that I posted &lt;a href="http://stackoverflow.com/questions/4666887/how-to-know-when-my-notification-is-cleared-via-clear-button"&gt;a question on StackOverflow and offered a 50 reputation point bounty&lt;/a&gt;. Turns out there is a very simple answer: the &lt;a href="http://developer.android.com/reference/android/app/Notification.html#deleteIntent"&gt;deleteIntent&lt;/a&gt; field on the Notification object. Talk about face-palm... Anyways you can set a PendingIntent here, and that PendingIntent can start a Service that does the "mark all as read" work for you.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Badging&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Android provides a really easy way to badge your notification icons in the status bar. If you just set the &lt;a href="http://developer.android.com/reference/android/app/Notification.html#number"&gt;number&lt;/a&gt; field on the Notification object, you get badging for free. However, badging looks a little ugly, and if you only have one message then you probably don't want it. In that case just don't set the number field and you are good to go. Then the next time a new message comes in, set the number field to 2. Try this out and rut it on your phone. Unless you have a Nexus S, you will notice a problem. The badging will not show up when you set the number 2 (or 3 or 4 or whatever.) This appears to be a bug with Android that was fixed in 2.3. That's why it works correctly on a Nexus S, but not on anything else (the NS is the only phone with 2.3 as of the time I wrote this.) So what do you do? Badge with a 1? Ugly. Don't badge at all? Less informative. The correct answer is workaround.&lt;/p&gt;&lt;p&gt;Actually you might get lucky and do it the "right" way to begin with. What I did was create a Notification with the same ID as the existing Notification, and then simply call notify on the NotificationManager service. That should replace the existing Notification with the new one, and you should get the right badging. This is the case on my Nexus S, so I'm guessing it's the case on Android 2.3+. This is not the case on previous versions of Android. Everything about the old Notification is replaced except for the badging. The work around is to remove the old Notification (using the cancel method on NotificationManager) and then create the new one using notify. That will work on all versions of Android.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Collapse Key&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If you read &lt;a href="http://code.google.com/android/c2dm/index.html#push"&gt;the C2DM documentation&lt;/a&gt;, one of the seemingly innocuous things that it mentions is the collapse key. It says this is "An arbitrary string that is used to collapse a group of like messages when the device is offline, so that only the last message gets sent to the client. This is intended to avoid sending too many messages to the phone when it comes back online." Doesn't this sound like this is for the C2DM servers, so they can throttle the messages being sent to your app? Maybe so, but I found that it come in handy on the app as well, as C2DM passes it on to the app. The reason is simple. You may get the same message from C2DM twice. Well I suppose it might even come more than twice, but what's the difference? Regardless you should expect that dupes might be sent, and so you should de-dupe. The collapse key is perfect for this. A good way to keep track of these is to use a static HashMap (depending on how you implement the Service that processes the C2DM messages, you may not be guaranteed that there will only be one instance of that Service, hence a static HashMap) with soft keys, so that if it grows too large the GC will toss old collapse keys that you don't need anymore.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4903245459734572491?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4903245459734572491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4903245459734572491' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4903245459734572491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4903245459734572491'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/02/android-notifications-c2dm-and-way-to.html' title='Android Notifications, C2DM, and The Way to Succeed and the Way to Suck Eggs'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3515712052467515199</id><published>2011-02-11T11:41:00.001-08:00</published><updated>2011-02-11T11:47:02.726-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>The Static Starter Pattern</title><content type='html'>One of my favorite things about Android is that it is not another MVC framework. Now some people find this as a weakness, but not me. I think MVC has its faults. Still many people think of application in terms of MVC, and for them Android's Activity class is as close to a controller as you will get. Pretty much every "screen" or "page" in an Android application has a single Activity behind it (there are exceptions, I know, but bear with me.) Inevitably you need to transition between Activities, and this is one of the places where Android can seem a little weird. You need to create an Intent and then pass that to the startActivity method on a Context object (usually the Activity that you are transitioning from.) That's not too bad. However, it is often the case that a given Activity expects some data -- a model if you like -- that it will use to create the UI (the view if you like.) Let's take a concrete example from &lt;a href="http://www.manning.com/collins/"&gt;Android in Practice&lt;/a&gt;. The MediaMogul application (chapter 11) allows the user to create a slideshow by selecting pictures, music, and video from their SD card. Then there is an Activity that plays the slideshow called SlideshowActivity. Here is code from the Activity that starts the SlideshowActivity.&lt;br /&gt;&lt;pre class="brush:java"&gt;Intent intent = new Intent(this, SlideshowActivity.class);&lt;br /&gt;intent.putExtra("videoUri", videoUri);&lt;br /&gt;intent.putExtra("imageFileNames", images);&lt;br /&gt;intent.putExtra("selectedSong", song);&lt;br /&gt;startActivity(intent);&lt;br /&gt;&lt;/pre&gt;And here is code from SlideshowActivity to retrieve this data:&lt;br /&gt;&lt;pre class="brush:java"&gt;Intent intent = getIntent();&lt;br /&gt;ArrayList&amp;lt;String&amp;gt; images = intent.getStringArrayListExtra("imageFileNames");&lt;br /&gt;Song song = intent.getParcelableExtra("selectedSong"); // custom Parcelable class&lt;br /&gt;Uri videoUri = intent.getParcelableExtra("videoUri");&lt;br /&gt;&lt;/pre&gt;There is an obviously ugly issue here. Both Activities need to know the keys (imageFileNames, selectedSong, videoUri) to use to put/get from the Intent's extras. This is such a common thing in Android, even in the framework, that there is a simple pattern for dealing with it. Just use public constants declared in the class that will use the Intent extras:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class SlideshowActivity extends Activity{&lt;br /&gt;public static final String EXTRA_IMAGE_FILE_NAMES = "imageFilesNames";&lt;br /&gt;public static final String EXTRA_SELECTED_SONG = "selectedSong";&lt;br /&gt;public static final String EXTRA_VIDEO_URI = "videoUri";&lt;br /&gt;...&lt;br /&gt;Intent intent = getIntent();&lt;br /&gt;ArrayList&amp;lt;String&amp;gt; images = intent.getStringArrayListExtra(EXTRA_IMAGE_FILE_NAMES);&lt;br /&gt;// etc.&lt;br /&gt;&lt;/pre&gt;And then of course in the calling class you would now have:&lt;br /&gt;&lt;pre class="brush:java"&gt;intent.putExtra(SlideshowActivity.EXTRA_IMAGE_FILES_NAMES, images):&lt;br /&gt;// etc.&lt;br /&gt;&lt;/pre&gt;Problem solved, right? Well not exactly. You still don't know what the types of the extras should, and you do not know if a particular extra is required or optional. Documenting your code can help with this:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class SlideshowActivity extends Activity{&lt;br /&gt;  /**&lt;br /&gt;   * An ArrayList of Strings. Required.&lt;br /&gt;   */&lt;br /&gt;  public static final String EXTRA_IMAGE_FILE_NAMES = "imageFileNames";&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So we put the type information and wether the field is required or not as a comment. Wait, doesn't this feel more like Ruby or Python instead of Java? Isn't there some way to use the language syntax and compiler to state this information in a better way instead of relying on code comments? That's where the Static Start Pattern kicks in:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class SlideshowActivity extends Activity{&lt;br /&gt;  public static void start(ArrayList&amp;lt;String&amp;gt; images, Song song, Uri videoUri, Context ctx){&lt;br /&gt;    Intent intent = new Intent(ctx, SlideshowActivity.class);&lt;br /&gt;    intent.putExtra(EXTRA_IMAGE_FILE_NAMES, images);&lt;br /&gt;    intent.putExtra(EXTRA_SELECTED_SONG, song);&lt;br /&gt;    intent.putExtra(EXTRA_VIDEO_URI, videoUri);&lt;br /&gt;    ctx.startActivity(intent);&lt;br /&gt;  }&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;From this method signature, I know the types of all of the extras and I know that they are all required. If I wanted to make one of them optional, then I could simply overload the start method with only two of the parameters, removing the optional parameter. Of course, somebody could bypass this and still use an Intent.&lt;br /&gt;Now this is not the best pattern for every Activity. The most obvious example is if you want your Activity to be started by other applications. Another application won't be able to invoke a static method. You will have to use the action/Intent-filter path for this. Of course this is pretty rare, how many of your Activities are meant to be started by other apps? Even if this is the case, you can still use the pattern for use within your app.&lt;br /&gt;This pattern is also not limited to Activities. You can do it with Services as well, especially IntentServices:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class AwesomeService extends IntentService{&lt;br /&gt;  public static void start(String someString, int someInt, Context ctx){&lt;br /&gt;    Intent intent = new Intent(ctx, AwesomeService.class);&lt;br /&gt;    intent.putExtra(EXTRA_SOME_STRING, someString);&lt;br /&gt;    intent.putExtra(EXTRA_SOME_INT, someInt);&lt;br /&gt;    ctx.startService(intent);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;If your IntentService handles multiple actions, this can be built into the pattern:&lt;br /&gt;&lt;pre class="brush:java"&gt;public class AwesomeService extends IntentService{&lt;br /&gt;  public static startUploadFile(String someFileName, Context ctx){&lt;br /&gt;    Intent intent = new Intent(ctx, AwesomeService.class);&lt;br /&gt;    intent.setAction(ACTION_UPLOAD_FILE); // ACTION_UPLOAD_FILE is a constant&lt;br /&gt;    intent.putExtra(EXTRA_SOME_FILE_NAME, someFileName);&lt;br /&gt;    ctx.startService(intent);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;You get the idea. You could extend this to BroadcastReceivers as well. I discussed this pattern a bit with my Android in Practice co-author, &lt;a href="http://www.screaming-penguin.com/blog/1"&gt;Charlie Collins&lt;/a&gt;. He liked it too, and pointed out that &lt;a href="http://mgmblog.com/2011/01/01/happy-new-years-simple-pattern-for-opening-an-android-activity/"&gt;others have used it&lt;/a&gt; as well. Personally, I'm not a fan of static methods or of passing around the Context like that, but the positives seem to outweigh the negatives. What do you think? Useful? Over-engineered?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3515712052467515199?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3515712052467515199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3515712052467515199' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3515712052467515199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3515712052467515199'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/02/static-starter-pattern.html' title='The Static Starter Pattern'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-344612360403348077</id><published>2011-02-07T13:45:00.000-08:00</published><updated>2011-02-07T13:45:12.056-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='nexus s'/><title type='text'>Some More Nexus S Comparisons</title><content type='html'>My last post about buying a Nexus S led to some interesting comments ... &lt;a href="http://www.google.com/buzz/konigsberg/h9ctAozxy51/Moving-on"&gt;on Google Buzz&lt;/a&gt; of all places. Actually it was &lt;s&gt;retweeted&lt;/s&gt;, I mean &lt;s&gt;rebuzzed?&lt;/s&gt; err reposted by my friend &lt;a href="http://konigsberg.blogspot.com/"&gt;Robert&amp;nbsp;Konigsberg&lt;/a&gt; at Google... Some of the points there were about comparing the NS and the N1. I argued that the NS had a much better processor (because of its integrated GPU) as well as having the best screen on the market right now. I also incorrectly stated that it had more RAM than the N1, but actually both of them have 512 MB. Here are a few more notable comparisons:&lt;br /&gt;&lt;br /&gt;The NS has 1 GB of "internal storage", but this actually part of its non-removable 16 GB of storage. The N1 has 512 MB of internal storage. As many apps only allow you to install them on internal storage (especially any app that has a homescreen widget because of &lt;a href="http://code.google.com/p/android/issues/detail?id=8555"&gt;this bug&lt;/a&gt;), you have twice as much space for such apps on the NS. However, you cannot upgrade the 16 GB. The N1 has only 4 GB included, but you can upgrade it. In fact, I had already upgraded it to 16 GB.&lt;br /&gt;&lt;br /&gt;The biggest thing that I forgot to mention is the reception (both voice and data) on the NS. To me, the N1 and the iPhone 4 both got similar reception -- and that is horrible. The iPhone 4's poor reception is well documented, but I think the N1 was just as bad. If you consider that T-Mobile's network is a step below AT&amp;amp;T's, you get a nasty combination. The NS has much better reception than either of these phones. For that matter, it is much better than any other iPhone I have used (3G/3GS). I'm talking about consistently getting two more bars than the N1, and much clearer and louder reception on the phone. It seems obvious that the use of metal in the outer casing is the key here. Both the iPhone 4 and N1 use metal to destroy your reception.&lt;br /&gt;&lt;br /&gt;Some folks have also asked me about battery life. I would say that the NS is slightly worse than the N1, and about the same as an iPhone 3GS. That makes it definitely worse than the iPhone 4. The most obvious culprit here is the screen. Bigger screen = more juice. I came across &lt;a href="http://www.readwriteweb.com/archives/iphone_to_android_one_week_with_the_nexus_s.php"&gt;this amusing blog&lt;/a&gt; about switching to the Nexus S from an iPhone. This included a complaint about using the power widget to turn off Bluetooth, Wi-Fi, and even GPS on the phone in order to save battery life. This was kind of shocking to me. As an iPhone user, I almost never turned on Wi-Fi and kept Bluetooth off except when in the car. I had to do this on the 3GS, or I would not make it through the day on a single charge. In fact one of the things that I love about Android is how much easier it is to do these two tasks than on iOS. In fact I always thought that this was a big miss by Apple, but I guess that most people actually leave that stuff on all of the time? I don't understand how anyone who uses their phone much, especially if they receive lots of push email, could get away with leaving all of that stuff on all of the time and not run out of juice by 3 PM. I never tried to do this with the iPhone 4 and its awesome battery, just because I was so used to managing the power on my device. Similarly, I can't imagine NOT charging my phone when I go to bed every night. Anyways, if I manage the Wi-Fi and Bluetooth and charge each night as usual, then the Nexus S makes it through the day easily for me. If I play a lot of games on it or use it as a mobile hotpost, that changes things noticeably.&lt;br /&gt;&lt;br /&gt;Finally, some folks didn't like that the NS does not have the glowing trackball that the N1 did. I liked the trackball on the N1. The LED lights weren't that useful, since I get email constantly. Still if I got a blue light, I would know that I got something from Facebook. The trackball was especially useful when there were small parts of the screen that needed to be tapped on. However, I have not found myself missing this on the NS, partially because the screen is bigger, but mostly because the touch accuracy on the screen is very good. I always found the N1 to be slightly worse than the iPhone 4 (which I think is slightly worse than the iPhone 3GS) when it comes to touch sensitivity/accuracy. I think the NS is a little better than the iPhone 4, about as good as the iPhone 3GS.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-344612360403348077?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/344612360403348077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=344612360403348077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/344612360403348077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/344612360403348077'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/02/some-more-nexus-s-comparisons.html' title='Some More Nexus S Comparisons'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-9060547394506157051</id><published>2011-02-03T22:58:00.001-08:00</published><updated>2011-02-03T23:04:30.631-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Moving on</title><content type='html'>&lt;div&gt;Recently I was in Los Angeles and took a cab from the airport to my hotel. When I got out of the cab, I left my iPhone 4 in the car. I called the cab company, but they were of no use. I had lost my iPhone. And no, I didn't have the Find My iPhone feature enabled on my iPhone. It's actually a pain to do that, if you don't use MobileMe.&lt;br /&gt;&lt;br /&gt;Fortunately being a mobile developer, I had another phone with me, my Nexus One. I've been carrying two phones for awhile. I only used apps on the N1, and mostly just phone features on the iPhone (not a good use of an iPhone, especially the iPhone 4.) I stuck with most of my app usage on the N1, since I thought it would make me a better Android developer. Now all I had was an Android phone.&lt;br /&gt;I moved my phone number to the N1, which was on T-Mobile. Just so you know, I immediately got hit with the dreaded early termination fee. I didn't get an option to keep paying for the line of service.&lt;br /&gt;So now I was in no-contract land, and I had a lot of options. I could buy another iPhone, even one on Verizon. I could wait until some of the new Android phones announced at CES were out. I was in no hurry because I had my N1. Instead of doing those things, I decided to buy a Nexus S. Here's why.&lt;br /&gt;&lt;br /&gt;I think the Super AMOLED screen is by far the best out there. I had the iPhone 4 for six months, and I wasn't very impressed with the Retina Display. You can't make use of all of those pixels on such a small screen. Yes text looks great, but the colors are washed out and I definitely noticed that a lot more than the awesome text rendering.&lt;br /&gt;&lt;br /&gt;I love that the Nexus S runs stock Android. No crap on it. I dislike SenseUI. I can tolerate TouchWiz, but I'm no fan. There are also no carrier crap, like the NASCAR app on Sprint 's phones. The only disadvantage of stock Android is the camera app. In comparison, I think the camera app on the Galaxy S and Galaxy Tab is excellent. But hey it's Android, I can always customize.&lt;br /&gt;&lt;br /&gt;I thought about getting a 4G phone. However I don't think it's worth it. Especially since I get to use the Nexus S's wireless hotspot feature for free. Plus I think all phones suffer when they transition from 3G to edge, and I think that problem would be much worse with 4G which will be spotty on any network for awhile.&lt;br /&gt;&lt;br /&gt;Obviously the Nexus S is ideal for a developer as well. So the Nexus S it is! In fact, I wrote this blog post on it.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-9060547394506157051?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/9060547394506157051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=9060547394506157051' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/9060547394506157051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/9060547394506157051'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2011/02/moving-on.html' title='Moving on'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total><georss:featurename>Hotel Lucia, 400 Southwest Broadway, Portland, OR, United States</georss:featurename><georss:point>45.521158 -122.678382</georss:point></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6361968113303044235</id><published>2010-12-11T11:44:00.000-08:00</published><updated>2010-12-11T11:44:20.822-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='galaxytab'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><title type='text'>The Tablet Wars Have Begun</title><content type='html'>A few weeks ago I picked up a Samsung Galaxy Tab. Being an Android developer, I thought it was a good idea to see how my apps as well as other apps function on the Tab. After all, it’s hard not to remember what it was like for iPhone developers when the iPad came out. iPhone apps run on the iPad, but they are virtually unusable. They either look ridiculously small, or you can “2x” them and they look like crap. So there was (and is) a lot of pressure on iPhone developers to port their apps to the iPad. Would the same thing hold true for Android developers and the Tab?&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPS-qxWF9I/AAAAAAAAA2A/qs7ey4XFW3Y/s1600/ebay.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="400" src="http://1.bp.blogspot.com/_XmwdENwf53s/TQPS-qxWF9I/AAAAAAAAA2A/qs7ey4XFW3Y/s400/ebay.png" width="233" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s1600/espn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s1600/espn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s1600/espn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s1600/espn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s1600/espn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s1600/espn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s1600/espn.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://1.bp.blogspot.com/_XmwdENwf53s/TQPRRjGtJOI/AAAAAAAAA18/XBnFgLyjfbY/s400/espn.png" width="233" /&gt;&lt;/a&gt;I am pleased to say that this is not the case for the Galaxy Tab. Most Android applications look good on the Tab. In fact, I would say that most of them look great. The extra real estate only adds to things. Now there are cases where the apps could make better use of space, or maybe their buttons look a little too big on the Tab. However these are minor issues compared to what it is like to run an iPhone app on an iPad.&lt;br /&gt;&lt;br /&gt;That being said, there are some apps that suffer on the Galaxy Tab. Notably some popular weather apps (The Weather Channel’s app, Weather Bug) looked bad on the Tab. However in subsequent weeks these apps have released updates that now look good on the Tab. During that time ESPN’s Scorecenter app also released an update. The previous version of the app looked fine on the Tab, since it relied heavily on ESPN’s mobile website. The update brought a more native UI with less reliance on mobile web. However, it has some serious layout issues and looks bad on the Tab.&lt;br /&gt;&lt;br /&gt;So why is it that most apps look good on the Tab, but a few do not? Is it something inherent to Android vs. iOS? Well, yes and no. It is not really anything inherent to Android the OS or Android the SDK. However, Android is designed to work on different sized screens and always has been. As a developer, you are given many choices for creating the layout of your UI, but you are encouraged to use relative/flow-based layouts. These are fluid and resize beautifully on different sized screens. So you take those apps and drop them on to a tablet, and they look just as good.&lt;br /&gt;&lt;br /&gt;Of course you don’t have to use these kinds of layouts. You can use layouts that are more fixed and absolute -- which is the norm for iOS developers. However, then you run into Weather Bug and ESPN style problems. Their developers can make adjustments to make their apps look good on tablets, but they may find themselves doing this again when ten-inch tablets start showing up.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.peterglaeser.com/wp-content/uploads/2010/06/p_1024_768_05C35B06-CD65-4DF1-AFF4-EE242477BE81.jpeg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="400" src="http://www.peterglaeser.com/wp-content/uploads/2010/06/p_1024_768_05C35B06-CD65-4DF1-AFF4-EE242477BE81.jpeg" width="300" /&gt;&lt;/a&gt;&lt;/div&gt;I think the fact that most Android apps run seamlessly on the Tab is a significant selling point of the device. If you have 200 iPhone apps, chances are that either many of them will not have been ported to the iPad, or if they were, then it will be as a different app (Blah blah blah HD!) that you will have to purchase. If you have 200 Android apps, then you are good to go on the Tab.&lt;br /&gt;&lt;br /&gt;The Tab has a few other advantages over the iPad. The one most people talk about is that it is more portable. This is not a small advantage. I just got back from a trip to Portland. When I’m there, I often like to go to the Starbucks near Pioneer Square to get tea and a scone for breakfast. One time I took my iPad with me, because I wanted to read blogs or news, catch up on Twitter and Facebook, etc. while I ate my scone. However I didn’t like having to carry it, and it was especially inconvenient once I got my tea and scone (3 items, 2 hands.) So I took it with me one time and never again. Instead I would just use either my iPhone or Nexus One. However this time I had my Tab and I always took it. Even with it raining, I could just put it in the inside pocket of my jacket and it was no trouble at all. &lt;br /&gt;&lt;br /&gt;Then there is the related issue of weight. I have often read books (via the Kindle app) on my iPad while on airplanes, or at a café, or just around my house. The iPad always makes my wrist very tired, and I find myself switching hands or trying to awkwardly prop it up on something. The Tab is so much lighter that this is never a problem. I am currently reading Stephen King’s The Waste Lands on the Tab (also via the Kindle app) and have had no problems with my wrist tiring out.&lt;br /&gt;&lt;br /&gt;I would say that the above three things are the major advantages of the Galaxy Tab over the iPad. Android apps work much better on it than iPhone apps work on the iPad; it is portable; it is much lighter. There are some other things too, like it having two cameras instead of zero, or being available on Verizon, T-Mobile, etc. Just to be fair though, the iPad still has some significant advantages over the Tab.&lt;br /&gt;&lt;br /&gt;The bigger screen is obviously the biggest advantage. This really opens up the iPad for a lot of experiences that aren’t possible on the Tab, or would suffer. Also, it makes using non-mobile optimized websites much better on the iPad. For example, ebay.com is pretty usable on the iPad. On the Tab, it is ok in landscape mode, but definitely not in portrait. So I would not really consider using it on the Galaxy Tab, but would on the iPad. Of course there is still a decent chance that a non-mobile optimized site is going to have problems on the iPad still.&lt;br /&gt;&lt;br /&gt;The bigger size of the iPad also leads to a larger battery. To me the battery life of the iPad is amazing. I do not use my iPad that much, so often it will go many days on standby. It blows me away how little battery is drained from say five days of standby. I have the non-3G iPad, so that makes a big difference, but still you just cannot beat the battery life of the iPad. &lt;br /&gt;&lt;br /&gt;Big screen and big battery are big advantages. However if you want to watch TV &amp;amp; movies on your tablet-of-choice, then the iPad has an even more bigger advantage: iTunes. There is no good way to download a movie and watch it on your Galaxy Tab. I think we will see Netflix on Android and thus the Tab in the next few months. That will help, but Netflix’s streaming selection is still very limited. However, iTunes has an excellent selection. I would guess that we will also see Amazon’s Video-on-Demand on Android, since it is on the Android-based GoogleTV. That will help with selection as well, but still it will fall well short of what’s on iTunes. Plus any streaming solution is more limited than iTunes buy/rent model. Not to mention that there is already a Netflix iPad app, and it would be shocking if Amazon didn’t have a VOD app for the iPad sometime next year as well. If you want to watch TV shows or movies on your tablet, the iPad is definitely the way to go for the foreseeable future. &lt;br /&gt;&lt;br /&gt;Based on the above, if a friend/family member asked me if they should buy a Galaxy Tab or an iPad I would ask them three questions:&lt;br /&gt;1.) Do you plan on using it primarily at home/office, or do you want to take it with you when you are out or traveling?&lt;br /&gt;2.) Do you use a lot of apps on your phone?&lt;br /&gt;3.) Do you want to watch TV shows or movies on it?&lt;br /&gt;&lt;br /&gt;Regardless of how they answered these questions, I think that a tablet like the Galaxy Tab or the iPad can replace a laptop for most people, but not everyone. If you are a heavy user of office-apps (word processing, spreadsheet, presentation software), then a tablet cannot be your primary device. I think the new MacBook Air is perfect for such folks. This is also a space where the ChromeOS netbooks have a chance to compete, as well as traditional Windows-based netbooks. If you do more “creative” activities, like graphical design, photography, and of course programming, then you need a real machine with serious RAM &amp;amp; CPU. That’s why my MacBook Pro will remain my primary machine for a long time. A tablet will always be complementary for folks like me. That’s why I think the portability and lightness of the Galaxy Tab outweighs the bigger screen and battery of the iPad for people who really need a laptop or even a netbook.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-6361968113303044235?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/6361968113303044235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=6361968113303044235' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6361968113303044235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6361968113303044235'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/12/tablet-wars-have-begun.html' title='The Tablet Wars Have Begun'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XmwdENwf53s/TQPS-qxWF9I/AAAAAAAAA2A/qs7ey4XFW3Y/s72-c/ebay.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-8384855054621227747</id><published>2010-11-12T16:12:00.000-08:00</published><updated>2010-11-12T16:12:45.709-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c2dm'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>C2DM on older versions of Android</title><content type='html'>Back in May, I made my &lt;a href="http://fupeg.blogspot.com/2010/05/android-wish-list.html"&gt;Android Wish List&lt;/a&gt;. The #1 item on my list was push notifications. The Android team delivered in spades with Cloud to Device Messaging. C2DM is much better than push notifications as they exist in the iOS world, because the user does not have to see the message being pushed. Instead your app can have a background service process the message and decide if a notification should be shown or not. That allows apps to receive many more types of events from the cloud, since they don't have to worry about bothering the user (or the user just ignoring the event.)&lt;br /&gt;&lt;br /&gt;Of course there was one obvious downside to C2DM: it required Android 2.2. This is obvious, but is a bummer since it meant that developers needed to wait until 2.2 adoption became very high before they could start using C2DM. Here we are six months later, and only about half of all Android phones in use are running 2.2 (for the US, this is lower in other countries.) Who wants to ship an app that can only reach half of the universe of users, or update an existing app if half of your loyal users will be left in the cold?&lt;br /&gt;&lt;br /&gt;This is definitely one of the places where you have to envy the iPhone. When iPhoneOS 3.0 came out, the adoption curve was pretty fast, even though users had to hook up their phone to iTunes. The reason for this was simple: OS 3.0 was available on all iDevices, and it was immediately available to everyone via iTunes. On Android, updates are pushed out over-the-air, which is great. However, it is up to vendors to do this. Plus a specific flavor of Android must be made for each Android device (this is true of iOS as well, but there are a lot less devices), and sometimes an update is not made for some devices for whatever reasons. For example, there are a large number of devices out there running Android 1.6 that will never be updated to Android 2.x. &lt;br /&gt;&lt;br /&gt;Don't get so down though. The point of this blog post is that all is not lost with regards to C2DM. It is actually entirely possible to add C2DM to your application, even if your application is compiled at API level 4 (Android 1.6.) Actually, it would probably work against API level 3 (Android 1.5), but there aren't too many of those devices out there. The key is that the way that you communicate with C2DM is through Intents, no 2.2-specific APIs needed. Let's take a look.&lt;br /&gt;&lt;br /&gt;First things first, you still need the proper permissions and receivers setup in your manifest. In particular you need a BroadcastReceiver that receives Intents with an action of&amp;nbsp;com.google.android.c2dm.intent.RECEIVE or&amp;nbsp;com.google.android.c2dm.intent.REGISTRATION. The names of actions are not constrained in the manifest schema, so that you can use custom/application actions. Thus this causes no problems on devices not running Android 2.2. Check out &lt;a href="http://code.google.com/android/c2dm/index.html#manifest"&gt;the official docs&lt;/a&gt; for all of the gory manifest details.&lt;br /&gt;&lt;br /&gt;Next, your application needs to check if the device is running Android 2.2+ or something older. If it is, then you can &lt;a href="http://code.google.com/android/c2dm/index.html#registering"&gt;register for C2DM&lt;/a&gt;. Here's how you check:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java" name="code"&gt;if (Build.VERSION.SDK_INT &amp;gt;= 8){&lt;br /&gt;    registerForC2dm();&lt;br /&gt;} else {&lt;br /&gt;    // continue to use your pre-C2DM solution here&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The only thing hacky here is that normally if you compare Build.VERSION.SDK_INT to something, it would be a defined constant like Build.VERSION_CODES.FROYO. However that constant is not available in Android 1.6, so instead we use its value of 8. I sure hope that constant doesn't change in future versions of Android!&lt;br /&gt;&lt;br /&gt;Finally, you need to handle the registration and message Intents that C2DM will send you. Again, you are just specifying a string for the actions on these Intents, so no API dependency. That's it! No reflection, no compile against API level 8, but declare you only need level 4 hack (as is commonly done to enable an app to be installed on the SD card.) I've tested this approach on a device running Android 2.2 and on a device running Android 2.1. The 2.2 device gets C2DM messages, just as you'd hope, while the 2.1 device simply ignores the C2DM code and is unaffected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-8384855054621227747?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/8384855054621227747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=8384855054621227747' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8384855054621227747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8384855054621227747'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/11/c2dm-on-older-versions-of-android.html' title='C2DM on older versions of Android'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-2502147769808270427</id><published>2010-09-07T13:23:00.000-07:00</published><updated>2010-09-07T13:23:21.465-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android Love</title><content type='html'>My colleague David Beach recently penned &lt;a href="http://www.itsbeach.com/blog/2010/08/developing-for-android.html"&gt;a great post about developing apps for Android&lt;/a&gt;. If you haven't read it, go read it now. Seriously. I know a lot of you will see that he's a product manager and stop right there, but get your lazy ass back over there and read it anyways. Look, even &lt;a href="http://techcrunch.com/2010/09/05/apple-android/"&gt;TechCrunch picked up&lt;/a&gt; his post. Ok I know that might actually be a disincentive for some of you, but still...&lt;br /&gt;&lt;br /&gt;Anyways, I want to make a retort of sort to Beach and talk about why I love Android. However, I have to start by making a confession. My go-to phone is my iPhone 4. So why would I, an Android fanboy and somebody who is writing &lt;a href="http://www.manning.com/collins/"&gt;a book about Android development&lt;/a&gt;, use an iPhone 4? The answer is really quite simple. The apps are better.&lt;br /&gt;&lt;br /&gt;My secondary device is a Nexus One, and I use it a lot. I would say I use it about 30-40% of the time. Many of the apps that I use a lot are available on both: eBay, PayPal, Facebook, Twitter, Foursquare, Yelp, Urban Spoon, Bank of America, Bump. However, in almost all cases, the iPhone app is just a lot better. This is definitely the case for the eBay app. It is most obviously the case for Facebook, which often dumps you off to their mobile web site to do things that you can't do in the app, even though you can do them on the iPhone app. The one app that I would say more than holds its own is the Twitter app, but even there I miss the conversations feature on the Twitter app for iPhone.&lt;br /&gt;&lt;br /&gt;It's understandable that the apps on the iPhone are better. In many/most cases, these apps have been out 1+ year longer than their Android equivalents. So they have more features, less bugs, and are more refined in general. Further, most companies have a lot more iPhone users than Android (this is obviously changing), so they are going to invest more heavily in iPhone development. You probably want your best developer working on your iPhone app. Then again, &lt;a href="http://twitter.com/joehewitt/status/20734288938"&gt;Joe frickin' Hewitt is doing Android development&lt;/a&gt; now, so the developers have arrived.&lt;br /&gt;&lt;br /&gt;I went off on this little tangent because it actually brings us back to the original topic. I use an iPhone still because its apps are better. I claim that the apps being better is mostly because of the head start that the iPhone is still enjoying. However, you could definitely infer from Beach's writeup (you did read it, right?) that it is easier to develop a great app for the iPhone than it is for Android. Heck, of the apps I listed earlier, the one that holds it own is the Twitter app. This is an app that was largely developed by Google -- who has to scratch their Android itch by developing 3rd party apps, because they largely focus on mobile web apps instead of native apps despite their ownership of the Android platform. Maybe all of us 3rd party developers have no chance of developing a great Android app because it is just too hard?&lt;br /&gt;&lt;br /&gt;Obviously I do not think this is the case. The challenges that Beach lays out are absolutely spot on. For designers, there is no &lt;a href="http://en.wikipedia.org/wiki/Human_interface_guidelines"&gt;HIG&lt;/a&gt;, it is very much a free-for-all. I would add that the default controls and themes are also poor. You simply must do some significant styling to your app or it will look like ass. I think some/all of this will be addressed with the &lt;a href="http://www.boygeniusreport.com/2010/06/30/android-3-0-aka-gingerbread-gets-detailed/"&gt;Gingerbread release&lt;/a&gt;. It is fair to say that Apple would have never gone this route, i.e. wait until the 3.0 version of their software to focus on user experience. That is fair, and since we haven't seen Gingerbread yet, maybe it will continue to fall short.&amp;nbsp;Even if you can't rely on the OS+SDK to make your app look spiffy, you can still do it yourself. It's not that hard. I mean, it's not like you have to re-invent the button or something. It just takes some experience and knowledge of what is possible with Android.&lt;br /&gt;&lt;br /&gt;Once you get past the eye candy, many things about Android development are actually quite nice. The development environment is excellent. Yes, there will be people who just don't like Eclipse and thus ADT, just as there are people who just don't like XCode. However, ADT's capabilities are quite advanced. One common complaint I have heard is about the amount of time that it takes to start an Android emulator image. This is contrast to the iPhone simulator, which starts up rapidly. However, if you consider that the Android emulator is an actual virtual machine being booted up, and not a shell that is simply relying on the underlying computer, then this is understandable. The advantages are obvious. Most apps run slower on the Android emulator than on a real device. The only advantage they may have over a real device is the network speed, but even this can be easily throttled to emulate edge or 3G conditions. If your app runs fast on the emulator, it is going to run great on a real device. You just can't say this about iPhones apps running on the simulator.&lt;br /&gt;&lt;br /&gt;Going beyond the tools, Android is a more advanced operating system, at least from an application developer's standpoint. It lets you do things that are just not possible on the iPhone. The obvious thing here is multitasking. With Android's background services, you can always have the latest data from a remote server and never have to wait for it when your application launches. Imagine if you had an up-to-the-second Twitter stream always waiting for you before you launch the Twitter app. It is possible on Android. It is not possible on the iPhone.&lt;br /&gt;&lt;br /&gt;It doesn't stop there. Communication between apps is formally supported on Android (though it could be improved) and can only be hacked on the iPhone. How many apps do you have that have some kind of "post it to Facebook" feature? Wouldn't it be great if you could just use the Facebook app to handle this -- thus no need to re-enter your Facebook name/password? It is possible on Android. It could sort of be hacked in a limited way on the iPhone, but it is not going to be pretty or seamless.&lt;br /&gt;&lt;br /&gt;These are just a couple of examples. My point is that even though the UI/UX issues on Android are significant, they are not insurmountable. Once you get past them, the other advantages of Android are even more significant. As Android apps mature and Android developers mature, we should see the day where Android apps are better than iPhone apps. I don't think that day is too far off. Now would that counter-balance the arrival of the iPhone on Verizon and other carriers? I think so.&lt;br /&gt;&lt;br /&gt;I will conclude on a more personal note once again. I work with all of the mobile teams here at eBay, including our iPhone teams. I've had a much more involved role on our Android app for awhile now, and I want it to be one of the first examples of an Android app that is significantly better than the iPhone equivalent. That's not because I'm an iPhone hater (though I'm sure we'd all agree that&amp;nbsp;competition is a very good thing)&amp;nbsp; or something, it's just because I think that by fully tapping the capabilities of the Android platform, we can deliver something incredibly useful to our users. Mobile software development is an amazing experience. Our users get to connect with our software in a much more personal way. Our software literally runs in the palm of their hands. That's a remarkable place to be. Right now I think Android is the platform that can deliver the most in that place, and I'm going to put my money where my mouth is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-2502147769808270427?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/2502147769808270427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=2502147769808270427' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2502147769808270427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2502147769808270427'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/09/android-love.html' title='Android Love'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1870535626404946807</id><published>2010-07-24T15:41:00.000-07:00</published><updated>2010-07-24T15:41:55.859-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='samsung galaxy s'/><category scheme='http://www.blogger.com/atom/ns#' term='vibrant'/><category scheme='http://www.blogger.com/atom/ns#' term='captivate'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Phone Number Fixer: The Glory and The Shame</title><content type='html'>A couple of months ago, &lt;a href="http://fupeg.blogspot.com/2010/05/phone-number-fixer-for-android.html"&gt;I wrote a little Android app called Phone Number Fixer&lt;/a&gt;. I wrote this for my friend Maria, but decided to put it on the Android Market for free. Since then it has a decent number of downloads, around 1000, and had several good reviews. However, recently not only did its number of downloads jump up, but it started getting some poor reviews. The reason? The Samsung Galaxy S.&lt;br /&gt;&lt;br /&gt;I have to admit that I had not been impressed with Samsung's previous efforts in the Android world. They seemed like decent "second-tier" phones. They were not in the same class with the Droid, Nexus One, or the MyTouch. Now the Galaxy S has come out, along with several other notable Android phones like the Evo, Droid X, and soon the Droid 2. I must admit to paying more attention to those phones than to the Galaxy S. However, it looks like Samsung has a winner on their hands.&lt;br /&gt;&lt;br /&gt;The Galaxy S is available on both AT&amp;amp;T and T-Mobile. On AT&amp;amp;T it is known as the &lt;a href="http://www.att.com/shop/wireless/devices/samsung-captivate.jsp"&gt;Captivate&lt;/a&gt;, and on T-Mobile it is known as the &lt;a href="http://www.t-mobile.com/promotions/pcmtemplate.aspx?passet=Pro_Pro_SamsungVibrant"&gt;Vibrant&lt;/a&gt;. I think this is the first time that AT&amp;amp;T has carried a top-of-the-line Android phone, i.e. a phone that is a significant competitor to the iPhone. Of course we all know that the iPhone is coming to Verizon, so this should be no surprise (Big Red is getting the Galaxy S too, as is Sprint. Hey isn't that everybody in the US?)&lt;br /&gt;&lt;br /&gt;Anyways, it seems like there are a lot of existing AT&amp;amp;T or T-Mobile users who are buying the Galaxy S. Of course they just want to take their SIM card from their existing phone (maybe even from their old iPhone?) and plop it into their new Android phone. That's when they run across the contacts-imported-from-SIM card problem that my little app can help fix. However, apparently there is something different about the Galaxy S. Not only is the phone immune to the power of the Phone Number Fixer, it even causes the app to hang and crash.&lt;br /&gt;&lt;br /&gt;Unfortunately I do not have a Galaxy S of any sort, so I cannot test against it. I know the Fixer works fine with a Nexus One, Evo, G1, and a Droid, and I did not get any negative reviews until the Galaxy S. So I think there is something unique about this device. Once I get my hands on one, I will fix the problem. I am really curious to see what the cause of the problem is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1870535626404946807?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1870535626404946807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1870535626404946807' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1870535626404946807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1870535626404946807'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/07/phone-number-fixer-glory-and-shame.html' title='Phone Number Fixer: The Glory and The Shame'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>1</thr:total><georss:featurename>Kooser, San Jose, CA, USA</georss:featurename><georss:point>37.250212481751944 -121.90614223480225</georss:point><georss:box>37.245942481751946 -121.91343773480224 37.25448248175194 -121.89884673480225</georss:box></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3346097754252518652</id><published>2010-07-14T10:55:00.000-07:00</published><updated>2010-07-14T10:55:07.211-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='targus'/><category scheme='http://www.blogger.com/atom/ns#' term='bluetooth'/><category scheme='http://www.blogger.com/atom/ns#' term='logitech'/><category scheme='http://www.blogger.com/atom/ns#' term='mouse'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>A Tale of Two Mice</title><content type='html'>For a couple of years now, I have used a &lt;a href="http://computers.shop.ebay.com/23160/i.html?_nkw=logitech+v470&amp;amp;_dmpt=Mice&amp;amp;_trksid=p3286.c0.m282.l1516"&gt;Logitech V470&lt;/a&gt; mouse. It is a laser mouse that uses bluetooth. I've used it with a black MacBook and two MacBook Pros and it has always worked perfectly. The only negative I could ever give it is that it is a little small for my hand (but I have large hands, I wear x-large gloves.) However, years of heavy use have taken their toll on the mouse, and I decided it was time to replace it.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XmwdENwf53s/TD30Lv3tSKI/AAAAAAAAA1Y/agLh78b7Yi4/s1600/mice.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="308" src="http://4.bp.blogspot.com/_XmwdENwf53s/TD30Lv3tSKI/AAAAAAAAA1Y/agLh78b7Yi4/s400/mice.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This picture shows the V470 in the front, and its replacement a &lt;a href="http://computers.shop.ebay.com/i.html?_nkw=targus+AMB09US&amp;amp;_sacat=23160&amp;amp;_dmpt=Mice&amp;amp;_odkw=logitech+v470&amp;amp;_osacat=23160&amp;amp;_trksid=p3286.c0.m270.l1313"&gt;Targus AMB09US&lt;/a&gt; which they call "Comfort Laser Mouse." Why did I pick the Targus? Well it is also a laser mouse that uses bluetooth. I read many a rave review, so I figured it was just as good of a mouse as my V470. It is a bigger mouse, as manufacturers have started realizing that just because I want a bluetooth mouse does not mean that I want a "travel" (small) mouse. However, after several weeks of use, here is what my desk looks like:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/TD33KiAbSqI/AAAAAAAAA1c/-TKwn46ASSs/s1600/desk.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/_XmwdENwf53s/TD33KiAbSqI/AAAAAAAAA1c/-TKwn46ASSs/s640/desk.jpg" width="480" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Yep, the old V470 is back, despite being chipped and have plastic peeling off of it. The Targus mouse is just not as good for several reasons. Its interaction with my MacBook Pro is buggy. Often the cursor on the screen does not change as it should (imagine web pages where you don't get the little hand to indicate a link). The sensitivity of its sensitivity is way too high. What I mean is that a slight adjustment in sensitivity has huge effects. It is either sluggish or spastic. I've tried adding a mousepad to the mix, but it only helped a little. Finally, it does weird things when interacting with OSX. I hide my Dock on the left of the screen. If I put the cursor over there, then the Dock appears as it should. However, if I roll over items in the Dock, they are not magnified as they should be. I can still click on them, but this messes with me and makes me think too much when I just want to launch something from the Dock. Also, I actually missed horizontal scrolling with the V470. Its wheel could move left/right to allow for horizontal scrolling. The Targus mouse does not have this feature, and I didn't think I'd miss it. However, I did not realize how often I actually used this, especially in Aperture and OmniGraffle.&lt;br /&gt;&lt;br /&gt;Now I know that many/most of these problems may have as much to do with OSX as with the Targus mouse. But I don't care. I'm not going to switch operating systems. Instead I will switch mice. I'd really like to get a larger version of the V470, which is why I have not just bought a new V470 and continue to use my old beat-up one. At some point I will probably give in and just buy a new V470.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3346097754252518652?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3346097754252518652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3346097754252518652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3346097754252518652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3346097754252518652'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/07/tale-of-two-mice.html' title='A Tale of Two Mice'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XmwdENwf53s/TD30Lv3tSKI/AAAAAAAAA1Y/agLh78b7Yi4/s72-c/mice.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4742263718808309557</id><published>2010-07-09T17:44:00.000-07:00</published><updated>2010-07-09T17:44:01.930-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><category scheme='http://www.blogger.com/atom/ns#' term='lebron james'/><category scheme='http://www.blogger.com/atom/ns#' term='nba'/><title type='text'>LBJ, Cleveland, and Miami</title><content type='html'>I was one of the millions who watched Lebron James announce that he would play for the Miami Heat next year. I have to say that the aftermath of this has been one of the most entertaining non-sports things in sports I have ever experienced. Where to start...&lt;br /&gt;&lt;br /&gt;1.) To all of the people complaining about what an egotistical p.o.s. Lebron is for having the TV special: take a look in the mirror. Did you watch it? If the answer is yes, then shut up. You created the market for his ego, and he was simply smart enough to milk it for what it's worth. Good for him. So why are you bitter? Maybe it's because you didn't like The Decision (and I'm not talking about the TV special.)&lt;br /&gt;&lt;br /&gt;2.) To Dan Gilbert, owner of the Cavaliers: thanks for playing! I want to tell you to grow up and stop acting like a fool, but that would be dumb. No, you've made this whole thing so much more enjoyable with your childish antics. Please continue.&lt;br /&gt;&lt;br /&gt;3.) To the Cavaliers fans: I'm sorry, but what did you really expect? Your team has bumbled this whole thing. The kind of overpaid, underperforming players that your team has continuously brought in to try to Win Now has been predictable and pathetic. The Cavaliers as an organization is weak, and has been for years. The only reason they got Lebron seven years ago was because they lost a lot of games in the right season. Yay. They've needed a coach who could get the most out of Lebron's unprecedented talents, and that has not happened. Instead everything has been done to appease Lebron, and you see how that works out. If the Cavs had had a coach who moved Lebron to point-forward (preferably playing the four-spot), posted him up on 2/3 of the plays, and told him never to take a 3-pointer unless it was to beat the shot clock, would Lebron have stayed in Cleveland? Who knows, but I think the Cavs would have won more games, especially more playoff games. That might have lead to a championship, and that probably would have made it harder for him to leave... All that being said, I still feel sorry for Cavs fans just because of the TV show. I think that would have made me physically ill.&lt;br /&gt;&lt;br /&gt;4.) To the Bulls, Knicks, and Nets fans: just shut up. The Cavs fans have legit gripe, but you guys don't. So you didn't win the lottery. Boo-frickin'-hoo.&lt;br /&gt;&lt;br /&gt;5.) To Kobe Bryant: congratulations. You are no longer the most disliked player in the NBA, a position you have held at least since you kicked Shaq out of L.A. Your style of egotism just became slightly less appalling to people outside of southern California. One interesting piece of analysis I've read is that there is no way Kobe would have gone to Miami, if he would have been in Lebron's position. The reason is that he would never want to have a decreased role so that he could play alongside Dwayne Wade. This is probably true, but I have a hard time seeing this as a negative about Lebron. Imagine if Lebron had got on TV last night and said he was playing for the Knicks or Bulls next year because he not only wanted to win a championship, he wanted to be The Undisputed Man on said championship team. That's the Kobe Bryant brand of egotism, and is that really more appealing? Maybe to some people, but not to me.&lt;br /&gt;&lt;br /&gt;6.) To Kevin Durant: your time has come. You have a very legit chance to become the most popular player in the NBA next year, and you seem to deserve it. He's an unbelievably good player. He seems to have a Kobe-like work ethic. He also seems to be unbelievably humble. He's also 21 years old. He has to be on the short list for possible MVPs next year (Lebron's stats will take a big tumble in Miami.) His team looks like it will be very good for many years to come. It would not be surprising if a year from now Durant is sporting an MVP trophy, and coming off an exciting run deep in the playoffs. The only thing that might limit his commercial/endorsement potential is his own desire to stay focussed on basketball. Can you honestly say that about any other NBA player?&lt;br /&gt;&lt;br /&gt;7.) To my home state of Florida: basketball just became king. Between the Orlando Magic and Miami Heat, my home state has three of the top five players in the NBA, two teams that will be expected to win ~60 games per year for the&amp;nbsp;foreseeable&amp;nbsp;future and meet each year in the Eastern Conference Finals. The only teams that could possibly stand in their way in the East are the aging Celtics and ... Maybe the Bulls if Derrick Rose becomes a top 10 player next year (which he definitely could do.) Seriously, there are going to be a lot of Florida Turnpike Series over the next five years.&lt;br /&gt;&lt;br /&gt;8.) To Pat Riley: you are the man. You've got your work cut out for you, filling out that roster, but I'm not about to start doubting you at this point. In fact I would not be surprised if Wade, Bosh, and James all wind up taking considerably less than max contracts, all in the pursuit of a championship roster. As an Orlando Magic fan, I really hope this is not the case, but I'm too scared of Riley to think otherwise. I'm also impressed with his willingness to part with Michael Beasley, a very high and hyped draft pick. Personally I think Beasley may still turn out to be a very good NBA player, but I don't think most GMs would be willing to so quickly admit a mistake.&lt;br /&gt;&lt;br /&gt;9.) To the pundits: let's see how long your memory is. A lot of people are saying that Lebron is taking the easy way out (even though many of those same people also think that having two All-NBA and one all-star player does not guarantee much in terms of championships.) It's Wade's team still, they say. Lebron can't be considered one of the game's greats now. That's all ridiculous to me. If Lebron continues to play the high level he's played at, and the Heat win multiple championships, none of this will matter. Nobody will care that it wasn't Lebron's team. Magic Johnson was never the "give me the ball at clutch time and get out of the way" kind of player, but nobody doubts his greatness. Lebron is much more cut in his mold than he is Michael Jordan's, and frankly it would be pleasing to see Lebron accept this. I think his stats will suffer, but mostly just scoring. I don't think his assists will necessarily suffer, especially if the Heat play an uptempo game (which they should.) His rebounding will go up if he plays in the paint more, and again if the Heat play uptempo. Imagine if he had a three year stretch averaging 20 points, 12 assists, 12 rebounds per game, while shooting 55% from the field? Throw in a couple of titles, and you're telling me he's not one of the top five players of all time? Nobody will care if Wade has the ball in his hands at crunch time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4742263718808309557?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4742263718808309557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4742263718808309557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4742263718808309557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4742263718808309557'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/07/lbj-cleveland-and-miami.html' title='LBJ, Cleveland, and Miami'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1633630208250114879</id><published>2010-06-09T13:19:00.000-07:00</published><updated>2010-06-12T09:33:51.570-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='multitasking'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='fast app switching'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>iOS Multitasking</title><content type='html'>By now you’ve seen the ads. Anyone who works in mobile totally &lt;a href="http://fupeg.blogspot.com/2010/06/wwdc-wish-list.html"&gt;saw it coming&lt;/a&gt;. It’s the supposed revolutionary way to do multitasking in iOS, the new name for the iPhone OS. It’s complete bullshit, and here’s why.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;It’s Not Revolutionary&lt;/b&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Personally, I don’t really care about this point. However, it must be noted that the multitasking on the iPhone is strictly speaking a proper subset of the multitasking architecture used by Android and Palm’s webOS. Does it really matter? No, not really, but it is certainly annoying to hear Apple talk about how they didn’t do multitasking in the past because they hadn’t figured it out yet. The notion that what they ‘came up with’ is some brilliant solution that it took four years to figure out is insulting to the intelligence of developers. Not that that matters...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;It’s Not Multitasking&lt;/b&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Even Apple is pretty honest about this ... to developers. For us they say “it’s actually something We call Fast App Switching, and it’s all most of you people need.” This is the feature that was done by Android and webOS for the last couple of years. On iOS, when a user switches apps or hits the home button, your app has a brief time when it “runs in the background.” Then it becomes suspended. In its suspended state, it is still in memory, but gets no CPU cycles. If the user re-opens it or switches back to it, then it picks up right where it was before. Assuming that it is like Android (and everything else about Fast App Switching is very similar), then as a developer you might need to save some transient data, like if there is a form that is half-filled by the user. However, often you will not need to do anything to take advantage of this, just recompile with iOS 4.0 as your target.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;But wait, there’s more. You should not count on your app staying suspended indefinitely. In fact, there’s a very good chance it will be terminated (that’s the official word.) This is exactly what happens when you go to the home screen on previous versions of iPhone OS, your app no longer takes up any memory. Now the user can still ‘switch’ back to your app (or re-open of course), but now it will be a re-launch of the app. In other words, it is just like closing your app, then re-opening it on iPhone OS 3.x.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;This can obviously lead to inconsistent app behavior. Sometimes the user might switch away from your app, then switch back and be back at the same screen in your app that they were at before. Other times, they could do the same thing, but instead they are back to the opening sequence of your app. Apple wants you to change your app to remove this potential inconsistency. They’ve kind of given you a way to do this. First, when your app goes from being active to suspended, a new event is fired to your application’s delegate. All you have to do is add this new method (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;applicationDidEnterBackground:&lt;/span&gt;) to your delegate. In that method, you can save the state of your application. However, you might not have enough time. You can wrap your code with a start/end task completion calls, and then get up to ten minutes to finish saving your state. Alternatively, you can incrementally save state. Now truth be told, many apps (especially games) already do this, so that when you restart your app, it always picks up right where the user left off. Apple has essentially taken this pattern that other apps have adopted, promoted it to a best practice, and give you some extra tools to make it a little easier to implement.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;There is one other thing that you might want to do right before your app gets suspended. You can decrease the probability of your app getting terminated by freeing up as much memory as you can. The iOS Terminator is going to kill apps that use more memory first. So free up as much memory as possible, and maybe it won’t kill your app. There’s no guarantees though. If the user launches an app that needs a lot of memory (and don’t they all?) then it doesn’t matter how little memory your app takes up. Everything is getting terminated. Hence Apple’s desire for you to always save state and never rely on being suspended when the user switches back to your app. However, if you do that, then is there any point to freeing up memory? Well theoretically it should be quicker to switch to a suspended app than a terminated one, so by freeing up memory you will be increasing the probability that your users will get a slightly better experience.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is Real Multitasking?&lt;/b&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Well strictly speaking, true multitasking would be to allow any given application to continue running as &amp;nbsp;normal when it is no longer in the foreground. This is what happens on desktop computers, and that sort of sets the expectation for smartphones. I think this is actually how Blackberry works (or it used, it has been many years since I bought a new Blackberry.) It’s not how Android works, and it’s obviously not how iOS 4 works. The major problem with this on more limited devices is that it causes those devices to run out of memory and use virtual memory. This makes everything on the device run sluggishly, as everything becomes gated by the swapping between real and virtual memory. Those non-foreground apps can also consume CPU and network. The CPU consumption might be an issue if you tried to run multiple games simultaneously -- just like it would on your desktop computer. Apple claims the CPU/network access real kill your battery. We’ll examine that later. Regardless, once you decide that a background app can lose its right to memory, it can’t function anyways. CPU/network becomes a moot point. Both Android and iOS terminate background apps to free up memory, something no desktop OS will do.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;So iOS and Android both use similar pseudo-multitasking to make it seem like multitasking to the user. To prevent memory from running out and hosing the system, they terminate background apps at will. Both operating systems give you a way around this, a way for you to continue to execute a program in the background. That is where the similarities end.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;On Android, you can create your own background service. That service can be in its own process, i.e. it gets its own block of memory allocated to it. That way if your application gets terminated, the service lives on. However, a service can be terminated just like an app. So you cannot rely on the service always running, instead the service should be there to enhance your application. Further, Android gives you ways to get your service restarted/pinged on a regular basis to do work.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;On iOS, there are just a couple of types of applications that are allowed to run as a background service. Even then, they do not get their own memory. Instead they stay suspended and the OS sends them events periodically that allows them to run in the background again while they do something. Apple says they do not want to provide the Android style background services, because they (Apple) decided that the great majority of apps would not benefit from this anyways. Further, they think that such an architecture would lead to many background services running, killing the device’s battery. So instead they picked the types of apps that they say will benefit from background processing: music players, navigation, and voice-over-IP. The most ironic part of this is that the enabled a class of app, navigation, that has the most harmful effects to your battery (well maybe games are worse.)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;I’ll talk about battery life in a second. First I want to address this notion that Apple has determined which apps would benefit from background processing, and which would not. As both a developer and a user, this is offensive. Apple has little knowledge of how my app works, or of how my users interact with the app. Further, they are obviously wrong. I can give you three examples of apps that use background services on Android to greatly enhance user experience: eBay, Facebook, and Twitter. You’re probably not surprised that I cited my company’s app, but maybe the other two did surprise you. All three use a background service to periodically download time sensitive data (current price of items, friend requests, status updates, tweets, etc.) So when you launch the apps or switch to them, you do not wait for all of this data to be downloaded -- like you do on all three companies’ apps on the iPhone. Instead you are presented with some fresh data (maybe a few minutes old), while the absolute freshest data is being downloaded in the background. You get to immediately interact with the apps. On iOS it might be possible to allow immediate interaction, but the data can only be as fresh as the last time you ran the app. This will usually be hours old, which makes it virtually useless for these apps.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;There is no question in my mind that user experience can be better on Android than on iOS for these apps, and I don’t think they are unique. I mean c’mon, we’re talking about eBay, Facebook, and Twitter. Perhaps you’ve heard of these companies? It seems obvious that any kind of real-time/interactive/social based website is going to benefit from background processing for their apps. That’s a pretty broad class of apps, but I doubt it’s exhaustive. I’m not smart enough to figure out all of the apps that would benefit from background processing -- and neither is Apple.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Battery Life FUD&lt;/b&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Ok, but what about the last plank in Apple’s argument: battery life. Well, as I pointed out earlier, they enabled a class of application that is devastating on battery life: navigation. These apps require constant high precision GPS information, which is very expensive. So their argument is not consistent with their behavior, still that doesn’t make their argument wrong.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;The apps that I mentioned earlier all are guilty of something that is supposedly deadly to battery life: they periodically use the network to download data. How bad is this? Well obviously it depends on how often, and how many network calls are made, along with how much data is being sent back and forth. I’ve done some experimenting on this -- hey I work on one of the apps on that list of naughty apps. In my experiment I had an app that downloaded 100K+ data every two minutes. The effect on battery life was less than 3%. That’s right. You could let such an app run in the background for days and days, and your phone would still have plenty of battery.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Now wait a minute, I know what you’re thinking. You can’t even go one day without recharging your phone, and you’ve got an iPhone that doesn’t have anything running in the background (by the way this is not true, Apple’s apps have been able to run in the background since the very first iPhone.) Further, you don’t even use it to make phone calls, yet it’s got maybe 12 hours of battery life. What gives? The answer is surprisingly simple, the screen. The screen on your beautiful phone is what drains your battery the most. So anything that involves the screen being on -- which is every kind of app on the iPhone currently -- will significantly drain your battery. Everything else they do has little noticeable effect on battery life, with two exceptions. Anything that rapidly changes that pretty screen will consume your battery even faster. That’s why many games will hammer your battery. I’ve had times where I played Civ on my iPhone for maybe twenty minutes, and it lopped off a third of my battery. That game doesn’t even have that much eye candy. The other battery blaster is the aforementioned GPS, for obvious reasons. All of those Android users with eBay, Facebook, and Twitter installed are doing just fine.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;But You're Gonna Love It!&lt;/b&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;So with all of that being said... users will really appreciate Fast App Switching in iOS 4. Why am I sure of this? Because Android users have always loved it. It’s one of those things where iPhone users don’t know what they are missing. Thus it will be delightful for them, and they will think Apple is full of geniuses. Actually I think it will put some serious pressure on Apple to update the iPad to iOS 4 (or maybe 4.1? Will we ever run the exact same OS on the iPhone and iPad?) People will get used to having Fast App Switching on their iPhone, and they will be so annoyed that they don’t have it on their iPad. I hope we’ll eventually see the same thing with regards to general purpose background processing. Maybe one day this will be part of iOS, and then it will be annoying to use older versions on the OS that don’t have this feature.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; You can &lt;a href="http://www.marco.org/684391075"&gt;add Instapaper&lt;/a&gt; to the list of apps whose developer would like it to be able to run in the background, so that it can improve user experience. Marco has an interesting proposal to tweak iOS to suit the needs of his app, and no doubt many others. It's better than the current situation, but I still think it's foolish to try to figure out all of the types of apps that need background processing, and add special APIs for each such app. While at WWDC, I talked to developers who work on some very popular sports and weather apps, and they too were incredibly disappointed by iOS. One of them proposed a new type of remote push notification that would not be displayed and only processed in the background.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1633630208250114879?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1633630208250114879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1633630208250114879' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1633630208250114879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1633630208250114879'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/06/ios-multitasking.html' title='iOS Multitasking'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-87652320245415697</id><published>2010-06-06T19:03:00.000-07:00</published><updated>2010-06-06T19:03:47.348-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wwdc'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>WWDC Wish List</title><content type='html'>Tomorrow is WWDC. Much like how I had an &lt;a href="http://fupeg.blogspot.com/2010/05/android-wish-list.html"&gt;Android wish list for Google I/O&lt;/a&gt;&amp;nbsp;(and I got my top two wishes!) a few weeks ago, I have one for the iPhone and WWDC. Given that OS 4.0 has been in beta for quite awhile, there is a little less suspense. So my wish list is a little more product based instead of development based.&lt;br /&gt;&lt;br /&gt;1.) iPhone for Verizon. AT&amp;amp;T has nixed the generous data plans for the iPad (as well as for the iPhone,) so really why is there any reason for Apple to stay exclusive with them? In fact one could imagine that AT&amp;amp;T busted out the new pricing last week because they knew their&amp;nbsp;exclusivity&amp;nbsp;was coming to an end. I certainly hope this is the case. Personally I would not switch to Verizon, but I hope that many folks do. Plus I think that if folks had a choice of iPhone on AT&amp;amp;T or iPhone on Verizon, then both companies would compete much harder, improving networks and dropping prices. This is a key but subtle component of the Android strategy that fanboys/apologists often seem to miss.&lt;br /&gt;2.) Non-AppStore apps. No way, right? Don't be so sure. How easy would it be for Apple to give folks a deeply buried user preference for allowing non-AppStore apps on their iPhone? An insignificant number of users would ever enable this "dangerous" option, but it would do so much. From a PR perspective, it would take the heat off Apple. Actually this might not just be PR, it might be legal as well. Want to use Flash to develop for the iPhone? Ok, just distribute it through your own channels to users who want to go outside of the AppStore. Obviously this would really make life easier on developers. The current provisioning process is ridiculous.&lt;br /&gt;3.) Mobile Safari improvements. I expect that we'll hear about how Safari and/or Mobile Safari is fifty-billion percent faster than ... something else. Apple is fond of blowing up micro-benchmarks. I'd like to also see some new features. I'd really like to see Web Workers, especially since Safari already supports them. I'd be thrilled to see the Device API, so that we can get access to the camera (and how about that front-facing camera, too?) and how about access to a user's contacts? It feels like Android'd browser is really pulling ahead of Mobile Safari, so it would be great to see Apple take back their lead.&lt;br /&gt;4.) Real multitasking. I'm probably going to hurl tomorrow when I have to hear Steve Jobs brag about multitasking in iPhone OS 4.0. It's bullshit. As &lt;a href="http://fupeg.blogspot.com/2010/04/thoughts-on-iphone-os-40-and-section.html"&gt;I've said before&lt;/a&gt;, OS 4.0 does not implement multitasking, it implements a handful of multitasking use cases. There is a big difference. Of course there is no chance of this. The multitasking in OS 4.0 is obviously technology designed by marketing and business people, not by engineers. They want to put an end to those obnoxious Motorola Droid commercials that make fun of a "a phone that can't walk and chew gum at the same time." So instead of figuring out how to do multitasking right, so that it enables developers without sacrificing performance, we get a useless feature (unless you happen to be one of the three use cases) that will be hailed as revolutionary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-87652320245415697?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/87652320245415697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=87652320245415697' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/87652320245415697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/87652320245415697'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/06/wwdc-wish-list.html' title='WWDC Wish List'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3271415456604814241</id><published>2010-05-28T11:06:00.000-07:00</published><updated>2010-05-28T11:06:19.147-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Phone Number Fixer for Android</title><content type='html'>One of the curses of working with computers is that you often become The IT person for friends and family. In fact, I should get a commission from Apple for all of the business I've sent their way by getting family members to switch to Mac computers. Ditto for the Firefox browser. I can't make people switch to Mac, after all that's often an expensive proposition, but it's long been a condition of my help that you never even think about using IE. For some of my less computer savvy relatives, I've learned to make IE disappear. This just made my life a lot easier (less things to fix) especially back in the heady days of weekly IE6/ActiveX exploits. Anyways... These days most folks, including friends and family, mostly use web applications and since I've had them on Firefox for a long time now, there aren't too many problems. However, recently I got an unusual request for help from a high school friend Maria.&lt;br /&gt;&lt;br /&gt;She had just switched to a Nexus One -- a phone that she seemed to be extremely happy with. She had imported several contacts from her SIM card that had been in her old phone. The only problem was that for these contacts, their phone number was classified as "Other." That would not be a big deal, but when she would try to send a text to a number, Android's auto-complete would not include these "Other" phone numbers as part of its search domain. So she would have to completely type out the number to send the text to -- which kind of defeats the purpose of having an address book on your phone. She could manually change each of these phone numbers to be of type "Mobile", and this would solve the problem for that number. However as you might guess, she had a lot of numbers and changing each manually would be painful to say the least. And that's where I come in...&lt;br /&gt;&lt;br /&gt;This sounded like an easy enough problem to solve. Find all of the numbers that were of type "Other" and change them to "Mobile." That might not work for everyone -- there might be some people who really want to classify some phone numbers as "Other" -- but it certainly worked for Maria (and I would guess most people, too.) So I cooked up a quick little app. First, I wanted to display all of the numbers that this was going to affect:&lt;br /&gt;&lt;pre class="brush:java" name="code"&gt;ContentResolver resolver = getContentResolver();&lt;br /&gt;String[] fields = new String[]{People._ID, People.NAME};&lt;br /&gt;Cursor cursor = resolver.query(People.CONTENT_URI, fields, null, null, People.NAME);&lt;br /&gt;LinkedHashMap&amp;lt;Integer, String&amp;gt; people = new LinkedHashMap&amp;lt;Integer,String&amp;gt;();&lt;br /&gt;int id = cursor.getColumnIndex(People._ID);&lt;br /&gt;int nameCol = cursor.getColumnIndex(People.NAME);&lt;br /&gt;if (cursor.moveToFirst()){&lt;br /&gt; do{&lt;br /&gt;  people.put(cursor.getInt(id), cursor.getString(nameCol));&lt;br /&gt; }while (cursor.moveToNext());&lt;br /&gt;}&lt;br /&gt;cursor.close();&lt;br /&gt;&lt;/pre&gt;This gives you a LinkedHashMap whose keys are the IDs of each contact, and whose values are the names of the contacts. Why did I bother with these two bits of info? Well, we need the contacts to query the phones, and I wanted something friendly to display to Maria so she knew which numbers were about to get "fixed". Anyways, now it was easy to query the phones:&lt;br /&gt;&lt;pre class="brush:java" name="code"&gt;ArrayList&amp;lt;String&amp;gt; data = new ArrayList&amp;amp;kt;String&amp;gt;();&lt;br /&gt;StringBuilder sb = new StringBuilder();&lt;br /&gt;String[] projection = new String[]{Phones.DISPLAY_NAME, Phones.NUMBER, Phones._ID};&lt;br /&gt;Uri personUri = null;&lt;br /&gt;Uri phonesUri = null;&lt;br /&gt;int displayName = 0;&lt;br /&gt;int number = 1;&lt;br /&gt;int phoneIdCol = 2;&lt;br /&gt;int phoneId = -1;&lt;br /&gt;int cnt = 0;&lt;br /&gt;for (int personId : people.keySet()){&lt;br /&gt; personUri = ContentUris.withAppendedId(People.CONTENT_URI, personId);&lt;br /&gt; phonesUri = Uri.withAppendedPath(personUri, &lt;br /&gt;            People.Phones.CONTENT_DIRECTORY);&lt;br /&gt; cursor = resolver.query(phonesUri, projection, &lt;br /&gt;            Phones.TYPE + "=" + Phones.TYPE_OTHER, null, null);&lt;br /&gt; displayName = cursor.getColumnIndex(Phones.DISPLAY_NAME);&lt;br /&gt; number = cursor.getColumnIndex(Phones.NUMBER);&lt;br /&gt; phoneIdCol = cursor.getColumnIndex(Phones._ID);&lt;br /&gt; if (cursor.moveToFirst()){&lt;br /&gt;  do {&lt;br /&gt;   sb.setLength(0);&lt;br /&gt;   sb.append(people.get(personId));&lt;br /&gt;   sb.append(": ");&lt;br /&gt;   sb.append(cursor.getString(displayName));&lt;br /&gt;   sb.append('|');&lt;br /&gt;   sb.append(cursor.getString(number));&lt;br /&gt;   data.add(sb.toString());&lt;br /&gt;   phoneId = cursor.getInt(phoneIdCol);&lt;br /&gt;   cnt += updateContact(phoneId);&lt;br /&gt;  } while (cursor.moveToNext());&lt;br /&gt; }&lt;br /&gt; cursor.close();&lt;br /&gt;}&lt;br /&gt;ArrayAdapter&amp;lt;String&amp;gt; adapter = new ArrayAdapter&amp;lt;String&amp;gt;(this, R.layout.phone, data);&lt;br /&gt;setListAdapter(adapter);&lt;br /&gt;Toast.makeText(this, cnt + " phone numbers updated", Toast.LENGTH_LONG).show();&lt;br /&gt;&lt;/pre&gt;This code just loops over the contacts we got from the first query. For each of those contacts it queries to see if the contact has any phones that are of type "Other" (Phones.TYPE_OTHER). If it does, it creates a string that shows the contact's name, the phone's display name, and the phone number. This string is added to an ArrayList. Once all of the queries complete, an ArrayAdapter is created using the ArrayList of contact name/phone strings and used to populate a ListView.&lt;br /&gt;You might have also noticed that a there is a counter variable being incremented, and an updateContact method. This is actually the method that fixes the phone number. I probably should have just kept track of the phoneIds and then gave the user a button to initiate the fixes, but I was lazy. Here is the code for updateContact.&lt;br /&gt;&lt;pre class="brush:java" name="code"&gt;private int updateContact(int phoneId){&lt;br /&gt; ContentValues values = new ContentValues();&lt;br /&gt; values.put(Phones.TYPE, Phones.TYPE_MOBILE);&lt;br /&gt; ContentResolver resolver = getContentResolver();&lt;br /&gt; Uri phoneUri = ContentUris.withAppendedId(Phones.CONTENT_URI, phoneId);&lt;br /&gt; return resolver.update(phoneUri, values, null, null);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Too easy. Contacts are an example of a Content Provider in Android. Many people (including my Android in Practice co-author and author of Unlocking Android, Charlie Collins) have criticized Android for exposing too much of the database backing of Content Providers. As you can see from the examples above, you have to deal with cursors (moving, closing), queries, updates, and very thinly abstracted select and where-clauses. Maybe it would have been better to drop down directly to the SQL, or provide a more object oriented API. Now you can create your own Content Provider, and you don't have to use SQL database to back it -- but then implementing the Content Provider contract can be quite awkward.&lt;br /&gt;Anyways, I found that the easiest way to get this little app to Maria was to simply put it on the Market. It's still on there if you happen to have a similar problem (maybe many people switching to Android might experience this?) If you are on your Android phone you can just &lt;a href="http://market.android.com/search?q=pname:com.flexware.fixer"&gt;select this link&lt;/a&gt;. If you are on your computer you can scan this QR code.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://qrcode.kaywa.com/img.php?s=8&amp;amp;d=http%3A%2F%2Fmarket.android.com%2Fsearch%3Fq%3Dpname%3Acom.flexware.fixer" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://qrcode.kaywa.com/img.php?s=8&amp;amp;d=http%3A%2F%2Fmarket.android.com%2Fsearch%3Fq%3Dpname%3Acom.flexware.fixer" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3271415456604814241?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3271415456604814241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3271415456604814241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3271415456604814241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3271415456604814241'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/05/phone-number-fixer-for-android.html' title='Phone Number Fixer for Android'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6760070513400161312</id><published>2010-05-26T22:20:00.000-07:00</published><updated>2010-06-25T11:35:05.704-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Mobile Zealotry</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img2.timeinc.net/people/i/2010/galleries/survivor-allstar/russell-hantz-435.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://img2.timeinc.net/people/i/2010/galleries/survivor-allstar/russell-hantz-435.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;i&gt;"You're either with me or against me!"&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;Does this feel like the rhetoric coming out of Google and Apple lately? Sometimes I wonder if Russell from Survivor is working for these guys. I was at Google I/O last week, and I have to admit that Vic Gundotra delivered a great keynote. It really got the troops excited.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XmwdENwf53s/TCT2eC4hSkI/AAAAAAAAA1U/axGrW7wShYQ/s1600/4628029110_83605f944d_b.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_XmwdENwf53s/TCT2eC4hSkI/AAAAAAAAA1U/axGrW7wShYQ/s320/4628029110_83605f944d_b.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;i&gt;"One man, one company, one device, one carrier would be our only choice ... Not the Future We Want"&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;Indeed. But before you go out and get an Android tattoo, and toss your iPhone off of the Golden Gate Bridge, take a deep breath and remember: You don't work for Google (unless you do, in which case I assume you've already got said tattoo.) You should not care who wins this jihad -- but make sure that you aren't collateral damage.&lt;br /&gt;&lt;br /&gt;If you are a mobile developer, what you should most care about is delivering the best and most useful experience to your users. So first and foremost, you need to care about what kind of devices your users are using. If they are all iPhone users and you really want to build Android apps, well sorry. Further, if they are all Blackberry users, then you can just ignore the drama going on here in the Valley.&lt;br /&gt;&lt;br /&gt;Of course the device of choice for your users today is quite possibly not what they will be using tomorrow. Former Android engineer Cedric Beust makes &lt;a href="http://beust.com/weblog/2010/05/22/more-on-android-and-the-iphone-2/"&gt;the point that the iPhone may well have peaked&lt;/a&gt;. Things look great when you're at your peak, especially if you don't realize that the descent has begun. So you might build a killer iPhone app this year, only to find that your users have moved on next year. Nobody ever said that this was an easy game.&lt;br /&gt;&lt;br /&gt;Hedging your bets and investing in multiple platforms seems like the safe thing to do, if it's practical. But don't forget the other factor: delivering a great app. If you can't deliver a great app on Android, then don't bother. If you can't deliver on the iPhone, then don't bother. Both Apple and Google have gone out of their way to provide developers with fantastic tools and platforms for creating great apps, so this may be a moot point. There are definitely types of apps that are better suited for one platform than the other. For example, the iPhone seems to be superior for games. If you look at the success of consoles, you can see why that kind of environment where hardware and software are highly standardized, translates well to the iPhone. Similarly, the lack of background processing on the iPhone (and don't believe any hype about iPhone OS 4 changing this, it does not except in a few special cases) cripples the capabilities of many iPhone apps.&lt;br /&gt;&lt;br /&gt;The most important thing to keep in mind in all of this is that it is in Apple and Google's best interests to be as divisive as possible. If they can convince you that they are "right" and that you should only develop for their platform, this is a huge win for them. So expect the rhetoric to only get worse. How many days until WWDC?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-6760070513400161312?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/6760070513400161312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=6760070513400161312' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6760070513400161312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6760070513400161312'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/05/mobile-zealotry.html' title='Mobile Zealotry'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XmwdENwf53s/TCT2eC4hSkI/AAAAAAAAA1U/axGrW7wShYQ/s72-c/4628029110_83605f944d_b.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4542902637528466253</id><published>2010-05-15T20:44:00.000-07:00</published><updated>2010-05-17T10:51:54.425-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android Wish List</title><content type='html'>This Wednesday is the first day of Google I/O. Google has a lot of very interesting technologies and many of those will have some new features announced this week. However, it doesn't seem too&amp;nbsp;presumptuous&amp;nbsp;to say that I/O is going to be Android-centric this year -- maybe every year for awhile. Google has pitted itself firmly against Apple and its iPhone/iPad platform. So I/O is Google's WWDC, and in case you missed it &lt;a href="http://arstechnica.com/apple/news/2010/04/wwdc-june-711-heavy-on-iphoneipad-light-on-mac.ars"&gt;WWDC 2010 is all about mobile&lt;/a&gt;. And so it is with I/O.&lt;br /&gt;&lt;br /&gt;There is a lot of chatter about Froyo, or Android 2.2. It's browser will have an &lt;a href="http://www.cooltechzone.com/2010/05/12/android-2-2-froyo-runs-flash-10-1-on-nexus-one/"&gt;integrated Flash plugin&lt;/a&gt;. It's supposed to be insanely fast (courtesy of a JIT and lower RAM usage by the kernel). It will support USB tethering and it can turn any Android phone into a mobile hotspot. That's all great, but none of that really does much for us Android developers, except for the speed increase of course -- especially important for game developers. Speaking of game artistes, Froyo is supposed to bring a lot more OpenGL ES goodness into their hands. So maybe we'll start seeing killer games on Android. Anyways, back to developers. What's Froyo got for us? More importantly, what do you want out of the platform? Here's my list.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Push Notifications. The iPhone has it. Blackberry has had it for what, a decade? The Windows Phone thing that's coming out at the end of the year is supposed to have them too. But what about Android? Background services and polling? Stop F'ing with me.&lt;/li&gt;&lt;li&gt;Apps on SD Card. Yeah we've been asking for this for a long time, and Google has always shot it down. Why is it important? It removes the pressure to keep apps super small, a pressure that has some chilling side effects. On the iPhone, I wouldn't hesitate to use a 3rd party library in an app, even if it added an extra 500KB to the app size. Not so on Android. For me this is particularly acute when it comes to using other languages like Scala on Android. The runtime library size is prohibitive -- because the app can't be saved on to the SD card.&lt;/li&gt;&lt;li&gt;More JDK. Wouldn't it be nice to have JAXB on Android? What about JAI? Yeah I know that sometimes they just wouldn't work because of performance reasons, but sometimes they would. Shouldn't be up to the developer to figure out when to use it or not?&lt;/li&gt;&lt;li&gt;Android for pads/slates/tablets. Yeah I want the Android equivalent of iPhone OS 3.2. I want to see Android on these form factors. As a corollary, I want an end to ChromeOS and that potential distraction. Let's just have one tablet OS from Google, ok? Android: Tablet Edition will have the Mobile Chrome browser in Android, anyways right? Bonus points: A sexy device with the new OS running out given to all of the developers at I/O (I know they gave us Droids already, but I'm greedy.)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;So there's my list. What's yours?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;: I remembered one more thing for my wish list, though this is not directly part of Android. I want Android 2.1 (or 2.2) to be available on all Android devices. I want it running on the G1, for example. There are definitely some SDK features I'd like to take more advantage of, and that's hard to do with 1.5 and 1.6 still on the majority of devices. The Mobile Chrome browser in 2.0+ is infinitely better than what's in 1.6 and lower because it uses HTML5 standards for storage, offline, geolocation, etc. instead of the now defunct Google Gears. So I really want those 1.5 and 1.6 browsers to go away, it's like having to support an ActiveX control for Ajax...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4542902637528466253?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4542902637528466253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4542902637528466253' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4542902637528466253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4542902637528466253'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/05/android-wish-list.html' title='Android Wish List'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-5769147501964985245</id><published>2010-05-14T12:53:00.000-07:00</published><updated>2010-05-14T12:53:07.325-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Awesome Android Presentation</title><content type='html'>... by my "Android in Practice" co-author, Charlie Collins:&lt;br /&gt;&lt;div class="prezi-player"&gt;&lt;style type="text/css" media="screen"&gt;.prezi-player { width: 550px; } .prezi-player-links { text-align: center; }&lt;/style&gt;&lt;object id="prezi_zlwtr-0gqqur" name="prezi_zlwtr-0gqqur" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="550" height="400"&gt;&lt;param name="movie" value="http://prezi.com/bin/preziloader.swf"/&gt;&lt;param name="allowfullscreen" value="true"/&gt;&lt;param name="allowscriptaccess" value="always"/&gt;&lt;param name="bgcolor" value="#ffffff"/&gt;&lt;param name="flashvars" value="prezi_id=zlwtr-0gqqur&amp;amp;lock_to_path=0&amp;amp;color=ffffff&amp;amp;autoplay=no"/&gt;&lt;embed id="preziEmbed_zlwtr-0gqqur" name="preziEmbed_zlwtr-0gqqur" src="http://prezi.com/bin/preziloader.swf" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="550" height="400" bgcolor="#ffffff" flashvars="prezi_id=zlwtr-0gqqur&amp;amp;lock_to_path=0&amp;amp;color=ffffff&amp;amp;autoplay=no"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="prezi-player-links"&gt;&lt;p&gt;&lt;a title="A tour of the Android platform, from kernel and core libraries, to APIs and software development with the SDK. " href="http://prezi.com/zlwtr-0gqqur/unlocking-android-development/"&gt;Unlocking Android Development&lt;/a&gt; on &lt;a href="http://prezi.com"&gt;Prezi&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-5769147501964985245?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/5769147501964985245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=5769147501964985245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5769147501964985245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5769147501964985245'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/05/awesome-android-presentation.html' title='Awesome Android Presentation'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7517855830308259678</id><published>2010-05-02T16:10:00.000-07:00</published><updated>2010-05-02T16:10:54.630-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='adobe'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Apple, Flash, and The Truth</title><content type='html'>I'm sure by now you've read "Steve Jobs"'s &lt;a href="http://www.apple.com/hotnews/thoughts-on-flash/"&gt;Thoughts on Flash&lt;/a&gt;. Did it convince you? Do you think it was truthful? Not me. Sure it has some valid points, especially about Flash being buggy on OSX. As someone who has developed Flash applications using a Mac, I am especially aware of this bugginess, and part of me can't help but get a perverse sense of satisfaction that this bugginess is now coming back to haunt Adobe. However, this doesn't change the fact that Jobs's epistle is far from the truth. It is corporate slander, designed to make Adobe look as bad as possible. Why? So that when devices from&amp;nbsp;competitor's ship with full support for Flash, this technological advantage can be discredited in the eyes of consumers. In other words, this well thought out post by Apple is not some intellectual/technical analysis, it is just marketing designed to boost Apple's profits.&lt;br /&gt;&lt;br /&gt;The most dishonest thing about the post is what Apple says is "the most important reason" to ban Flash from their devices: that it will result in sub-standard apps and hurt their iPhone/iPad OS platform. This is complete bullshit. It's not like developers would suddenly only be able to create iPhone apps using Flash. It's not like they could no longer use all of the tools they use today. The difference is that they would have a choice. They could choose to use Flash. Or they could choose to use Objective-C/Cocoa/XCode.&lt;br /&gt;&lt;br /&gt;But don't forget, that not only would developers have a choice, but so would consumers. If for some strange reason, some developers started choosing to use Flash, &amp;nbsp;it's not like consumers would be forced to buy those Flash-authored apps. No, they could still choose other, traditional apps. In fact, if, as Apple claims, Flash-authored apps would be of such low quality, then one would expect that few consumers would choose to purchase those apps.&lt;br /&gt;&lt;br /&gt;So if Apple allowed developers to use whatever tools and technology they wanted to use, to create apps for the iPhone and iPad, what might happen? Well if Apple's claims are right, then there would be bad apps that nobody would buy (aren't there already a lot of such apps on the App Store?). Consumers aren't idiots, and they won't buy crappy apps when there will be better alternatives. So those Flash-authored apps will lose money. Developers aren't idiots, and they won't keep using technology that produces software that nobody wants. So they would abandon Flash and go back to Cocoa. So Apple's "concerns" would be unwarranted.&lt;br /&gt;&lt;br /&gt;Or perhaps what would happen is that some developers would produce good apps using Flash that consumers bought for their iPhones. Certainly developers would continue to use Flash. However, in this scenario, Apple's "concerns" are proven to be false -- Flash produces some good apps. But wait, what about Flash holding back innovation on the platform? Apple would still be free to add new features to their OS, and make them available to developers through new APIs in the iPhone SDK. Who knows how long it would take Adobe to expose those features through the Flash authoring tools, but who cares? If those features greatly improve apps, and they aren't available in Flash authoring, then what happens? The power of choice wins again. Developers can still choose to use Cocoa, tap into these innovations, and user's can choose to purchase the apps that take advantage of these innovations. If these features are so great, one might expect that Adobe would try to bring them to Flash authoring as quickly as possible. Either way, the notion that the Flash platform would be held back makes no sense.&lt;br /&gt;&lt;br /&gt;So Apple's self-described most important point is so false that it is laughable. Some of their other parts are equally false. For example, the notion of touch and Flash. Yes, many things in Flash are designed for users interacting with a mouse, not a finger. Such things don't work well on touch devices. However, this is not just true for Flash. It is equally true for HTML and JavaScript. If you've done a lot of surfing on your iPhone or iPad, you have surely experienced the "rollover" issues described in Apple's post. Want more examples? Check out this clever little video on HTML 5 and the iPad:&lt;br /&gt;&lt;object height="385" width="640"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rfmbZkqORX4&amp;hl=en_US&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/rfmbZkqORX4&amp;hl=en_US&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;So why all the bullshit? As I said earlier, the reason for the post is to discredit any competitor that provides Flash support on their devices. First and foremost on that list is Android, which &lt;a href="http://www.pcworld.com/article/195130/google_adobe_flash_support_coming_to_android_22.html"&gt;will support Flash in Android OS 2.2&lt;/a&gt;. That doesn't explain why Apple doesn't want to allow developers to use Flash to develop for the iPhone? The answer to that is simple. They want complete control of their platform. If you want to make money off of the iPhone, you have to be in bed with Apple. They saw how the web has hurt Microsoft, and they will not let this happen on the iPhone or iPad.&lt;br /&gt;&lt;br /&gt;Now wait a minute, isn't Apple investing heavily in the web, namely HTML 5? Doesn't that demonstrate that they are willing to give up control of their platform? Yes, and no. Yes, Apple has invested into WebKit, a technology that in various forms implements a decent chunk of the HTML 5 standard. But you see, the key word here is "standard." This is how Apple fools you into thinking that they are providing an "open" alternative to their proprietary system.&lt;br /&gt;&lt;br /&gt;It's easy to get fooled into thinking that any company that implements and open standard is innovative, but just the opposite is true. We think standards=innovation for browsers because of Microsoft IE 6. That browser dominated the world for a long while being completely stagnant. It was both non-standard and non-innovative, but this is an exceptional. It is rare that such technology can flourish. It took the unique nature of Windows, IE, and Microsoft's legal troubles to produce this situation.&lt;br /&gt;&lt;br /&gt;Adopting a standard just means that you either change an existing feature of your technology to comply with the standard, or you copy a feature from others in the space. It is anti-innovation. When it comes to web standards, they are introduced post-hoc. XMLHttpRequest, the key technology behind Ajax, was proprietary Microsoft technology for many years before it became a standard. Many of the features of HTML 5 were introduced by various plugin technologies like Flash or Google Gears before they became part of the HTML 5 spec. You cannot innovate while waiting for some super slow moving corporate&amp;nbsp;committee to vote on a new standard.&lt;br /&gt;&lt;br /&gt;Going back to the iPhone/iPad, Apple is saying: pick either Cocoa and go through the App Store, or stick to the web, but only the "open standards" part of the web. They have given you a choice, but only the weakest, most impotent choice possible. You see this is where the other part of their Flash ban comes into affect. Not only have they recently banned compiling a Flash authored application into a native iPhone application, they have always banned Flash running in the browser. Why? Because with browser plugin technologies like Flash, Silverlight, and yes even Java, you can create user experience's on par with desktop applications. If they allowed Flash in the browser on the iPhone, then developers could create web applications that might rival the native iPhone applications. And we wouldn't want that, now would we? So Apple give you a single alternative to using Cocoa/XCode/AppStore, and then they horribly cripple it, by removing the most innovative parts and tying a design-by-committee-technology weight around its neck. Apple's endorsement of HTML 5 is one of the greatest marketing ruses ever. They stifle innovation, limit choice, and line their own pockets while getting everyone to believe they are being developer friendly and innovative.&lt;br /&gt;&lt;br /&gt;After all of the above, you might think that I am very anti-Apple, anti-iPhone, anti-iPad. I'm not at all. I am anti-bullshit though. I don't like being lied to and treated like a lemming. Apple has every right to keep Flash off of their devices. It's their OS after all. They have very right to ban apps that were authored with Flash from their AppStore. It's their AppStore after all. Just don't lie to me about this stuff. Don't say it's better for developers or better for consumers, when it's actually worse for both. Just tell the truth: it's just better for Apple.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7517855830308259678?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7517855830308259678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7517855830308259678' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7517855830308259678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7517855830308259678'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/05/apple-flash-and-truth.html' title='Apple, Flash, and The Truth'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4662651999475209495</id><published>2010-04-09T17:16:00.000-07:00</published><updated>2010-04-09T17:16:57.391-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Thoughts on iPhone OS 4.0 and Section 3.3.1</title><content type='html'>I'm on vacation right now. Earlier in the week, I took my kids to the Kennedy Space Center:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/S78h_5th3HI/AAAAAAAAAzI/bWTENDw5L50/s1600/DSC_0673.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/_XmwdENwf53s/S78h_5th3HI/AAAAAAAAAzI/bWTENDw5L50/s640/DSC_0673.jpg" width="427" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now I am in my hometown of Panama City, Florida visiting family and friends. However, yesterday Apple released the beta of iPhone OS 4.0. I read about it briefly on my iPhone while riding around town yesterday. Saw that it supported multi-tasking -- yay! Saw some nice features, like unified inbox, multiple Exchange accounts, geo-tagged pictures, etc. I was psyched, and planned on reading more about it later.&lt;br /&gt;&lt;br /&gt;Later came, and I started reading more details on my laptop. Of course what everyone was talking about was Section 3.3.1. Soon I went from being psyched about OS 4.0, to being very annoyed about it. Now I know that &lt;a href="http://daringfireball.net/2010/04/iphone_agreement_bans_flash_compiler"&gt;some people do not think Apple is singling out Adobe&lt;/a&gt;, but it damn sure seems like a reaction to Flash CS5. Let's not forget that Apple also made several barely-disguised jabs at Google-owned AdMob while unveiling Apple's own iAd platform. OS 4.0 is all about Apple going after other big software companies that are making money or trying to make money off of the iPhone. However, in the process, Apple is going to take out other companies like Appcelerator. Not that Apple cares...&lt;br /&gt;&lt;br /&gt;So yeah, Apple is screwing lots of other people who are trying to make a dime while at the same time enabling more developers to support the iPhone/iPad platform. Nothing to see here, move along. A number of people have pointed out that Microsoft in all of its monopolistic, evil ways never tried to pull anything like this. In fact, this is polar opposite of Microsoft. For all of their faults, Microsoft always supported developers. Sure they wanted to sell you Visual Studio, but if you wanted to use Java Swing or GTK or C++ using make, they did not care. Heck, they even weighed down Windows for years and years to maintain backwards compatibility APIs used by 3rd party developers.&lt;br /&gt;&lt;br /&gt;Enough negativity... there are many good things about OS 4.0. The most obvious thing is its multi-tasking. To be honest though, it is fundamentally flawed. It is an "OS" feature that is purely designed around use cases. It's like Apple saw ads by Google/Verizon and Palm, that showed users listening to Pandora in the background, or using GPS, or receiving VOIP calls, and told their engineers "Can we do this without really enabling background processing?" Background apps are limited to these use cases: Pandora (music), Garmin/Magellan (GPS), and Skype (VOIP). That is lame. Background apps are also prohibited from networking (wait does this screw Pandora after all?) Better than nothing? Yes, but lame.&lt;br /&gt;&lt;br /&gt;As part of this background processing stack, Objective-C blocks have finally come to the iPhone. Yep, that means closures. Of course, it's grafted on top of Cocoa, so that means you can't just take a button and set its event handler to a block of code. But again, better than nothing. Maybe we'll see some Cocoa evolution that will allow developers to take advantage of this.&lt;br /&gt;&lt;br /&gt;Back to the meat of the background processing... One of the use cases mentioned above is geolocation. One of the new features added in OS 4.0 is advertising via iAd. As mentioned earlier, this is a clear attack on Google's AdMob platform. The impending explosion of advertising and constantly location-aware applications suggests that location based advertising could also see an explosion. Of course a background app that is location aware cannot make network calls, a prerequisite for fetching relevant ads. Ah, but they have iAd! Apple has positioned itself quite well to take advantage of mobile advertising.&lt;br /&gt;&lt;br /&gt;Finally, I've probed the new version of Safari. It's version 532 of WebKit, up from build 528 in iPhone 3.1.3 and 531 in Safari 4.0.4. However, it still doesn't support Web Workers... Shortly after OS 4.0 was announced, Apple also announced WebKit2. This appears to be WebKit built on multi-processing, a la Chrome. No word on when it will come to the iPhone and iPad, but perhaps that is where Apple's efforts are these days.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4662651999475209495?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4662651999475209495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4662651999475209495' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4662651999475209495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4662651999475209495'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/04/thoughts-on-iphone-os-40-and-section.html' title='Thoughts on iPhone OS 4.0 and Section 3.3.1'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XmwdENwf53s/S78h_5th3HI/AAAAAAAAAzI/bWTENDw5L50/s72-c/DSC_0673.jpg' height='72' width='72'/><thr:total>0</thr:total><georss:featurename>Upper Grand Lagoon, FL, USA</georss:featurename><georss:point>30.162790584371756 -85.76408386230469</georss:point><georss:box>30.144238084371757 -85.79326636230469 30.181343084371754 -85.73490136230468</georss:box></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-8360209993426170057</id><published>2010-03-31T10:24:00.000-07:00</published><updated>2010-03-31T10:24:41.131-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><title type='text'>iPad Web Applications</title><content type='html'>So you might have heard about this... This Saturday, April 3, there's &lt;a href="http://www.apple.com/ipad/"&gt;a new computer&lt;/a&gt; coming out from Apple. You might have &lt;a href="http://fupeg.blogspot.com/2010/01/ipad-brave-new-world.html"&gt;heard about it&lt;/a&gt;. Anyways, lots of iPhone developers have been scrambling to port their iPhone apps or write new iPad apps. A lot of folks have been predicting that developers would start to shun Apple after all of the &lt;a href="http://www.macworld.com/article/141939/2009/07/googlevoice_apps.html"&gt;controversies&lt;/a&gt; surrounding iPhone app submissions and the "walled garden" approach that Apple has taken. On the other hand, &lt;a href="http://fupeg.blogspot.com/2010/03/mixation-sensation.html"&gt;Microsoft has decided that a controversial walled gardens are once again the way to go&lt;/a&gt;, and is diligently copying Apple. Well if the iPad is any indicator, developers continue to agree with Apple and Microsoft. There is a lot of interest in developing native applications for the iPad.&lt;br /&gt;&lt;br /&gt;Still, if you're like me and a big part of your job is to figure out how to build web applications for all kinds of devices, you have probably been spending a lot of time trying to figure out what to do about the iPad. On one hand, it's a big enough device that most websites will &lt;i&gt;look&lt;/i&gt; just fine on it.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XmwdENwf53s/S7N_mvZxNDI/AAAAAAAAAy4/iA7XEL_7620/s1600-h/Screen+shot+2010-03-31+at+9.41.41+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://4.bp.blogspot.com/_XmwdENwf53s/S7N_mvZxNDI/AAAAAAAAAy4/iA7XEL_7620/s640/Screen+shot+2010-03-31+at+9.41.41+AM.png" width="616" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I think you must agree that the above looks a heck of a lot better than a "mobile optimized" site like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/S7N_2XxREQI/AAAAAAAAAy8/TldEqH6Zbf0/s1600-h/Screen+shot+2010-03-31+at+9.41.46+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/_XmwdENwf53s/S7N_2XxREQI/AAAAAAAAAy8/TldEqH6Zbf0/s640/Screen+shot+2010-03-31+at+9.41.46+AM.png" width="616" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This seems great at first -- no work! Just make sure that if you are using any browser sniffing/redirecting code that it does not redirect for the iPad. However, there are some disadvantages to this. First, there are some issues with 'normal' sites that will not translate well to the iPad. There is the &lt;a href="http://www.pcworld.com/article/188185/apples_ipad_and_the_flash_clash.html"&gt;obvious thing with Flash&lt;/a&gt;... There are more subtle things like, "hovers", i.e. mouse-overs. That is when you toss up a UI layer when a user hovers their mouse over a link, or an image, or whatever. These are pretty popular, and they are not going to work on the iPad. Apple has quite figured out how to detect a finger hover... There are other events that are different on the iPad as well. There is also the question of how to best use the real-estate on the device, and the related question of dealing with landscape mode.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/S7OBt5liJzI/AAAAAAAAAzA/sj2PslOdFv0/s1600-h/Screen+shot+2010-03-31+at+10.08.49+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="518" src="http://1.bp.blogspot.com/_XmwdENwf53s/S7OBt5liJzI/AAAAAAAAAzA/sj2PslOdFv0/s640/Screen+shot+2010-03-31+at+10.08.49+AM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;I think a lot of sites will look great in landscape mode, but that doesn't mean that they couldn't look better. It might be more optimal to go to a multi-column layout. That could let a site place useful content "above the fold", i.e. visible so the user does not have to scroll to get to it.&lt;br /&gt;&lt;br /&gt;There's also the possibility of "embracing the native" on the web. There are a lot of iPhone-optimized websites that do a good job of making their website look and feel like a native iPhone application. Joe Hewitt's excellent iUi JS/CSS framework is an easy way to do this. The iPad has some of its own metaphors not found in the iPhone. Take a look at this native iPad app:&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/a5IcZF-BS9Y&amp;hl=en_US&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/a5IcZF-BS9Y&amp;hl=en_US&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Notice all of those columns? We've kind of touched on that already. Did you notice the pop-over menus? These are likely to be ubiquitous on the iPad. Here is a picture of them from one of Apple's iPad apps, Numbers:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://images.apple.com/ipad/features/images/numbers_charts_20100225.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://images.apple.com/ipad/features/images/numbers_charts_20100225.jpg" width="288" /&gt;&lt;/a&gt;&lt;/div&gt;Obviously there is nothing in HTML-land that is quite like that. However, it is certainly possible to craft something similar. In a way, it's kind of like the mouse-over menus that are popular on the web, only the interaction model is slightly different and the UI is definitely more rich than the average mouse-over menu.&lt;br /&gt;&lt;br /&gt;So what to do? Just stick with your "normal" site? Develop an iPad optimized site? Tweak your iPhone-optimized site to suck less on the iPad? Tweak your normal site to suck less on the iPad?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-8360209993426170057?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/8360209993426170057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=8360209993426170057' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8360209993426170057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8360209993426170057'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/03/ipad-web-applications.html' title='iPad Web Applications'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XmwdENwf53s/S7N_mvZxNDI/AAAAAAAAAy4/iA7XEL_7620/s72-c/Screen+shot+2010-03-31+at+9.41.41+AM.png' height='72' width='72'/><thr:total>1</thr:total><georss:featurename>Kooser, San Jose, CA, USA</georss:featurename><georss:point>37.25014416051372 -121.9062066078186</georss:point><georss:box>37.24800916051372 -121.9098546078186 37.25227916051372 -121.9025586078186</georss:box></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-8421349960664158943</id><published>2010-03-26T19:16:00.000-07:00</published><updated>2010-03-26T19:16:54.653-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='logic'/><category scheme='http://www.blogger.com/atom/ns#' term='fallacies'/><title type='text'>Programming and fallacies</title><content type='html'>Today I read &lt;a href="http://stu.mp/2010/03/nosql-vs-rdbms-let-the-flames-begin.html"&gt;a blog pos&lt;/a&gt;t by &lt;a href="http://twitter.com/joestump/"&gt;@joestump&lt;/a&gt; where he attempted to refute &lt;a href="http://www.yafla.com/dforbes/The_Impact_of_SSDs_on_Database_Performance_and_the_Performance_Paradox_of_Data_Explodification/"&gt;claims that Digg had been "doing it wrong"&lt;/a&gt; when they could not scale their database and went with a NoSQL attack instead. I'm not going to get into that flame war. I will say that folks at Digg should have expected exactly this kind of scrutiny when they decided to start bragging about their technology decisions. If a company has a technology blog, that is all they are trying to do -- brag. Anyways, back to the blog post... I was immediately &lt;a href="http://twitter.com/michaelg/status/11103638562"&gt;disappointed to see&lt;/a&gt; that it was riddled with logical fallacies. I see logical fallacies all the time, and sometimes I forget that many folks are actually not very familiar with them. In particular, I would say that programmers are not very familiar with the "formal" concept, despite the fact that programmers tend to have very strong logical reasoning. Here is my attempt to do something about that.&lt;br /&gt;&lt;br /&gt;First off, I am not going to answer &lt;a href="http://www.nizkor.org/features/fallacies/"&gt;what is a logical fallacy&lt;/a&gt;. You can follow that link, or find many other descriptions and enumerations of fallacies. Instead I want to talk about why programmers may not be aware of fallacies, and why it is important for them to learn about them. I think the reason that programmers may not know much about fallacies is that they are generally taught in classes on writing, public speaking, or debating. In other words, even though these are concepts tied to logical reasoning, including induction and deduction, they are not included in classes on mathematical logic. You cannot generally express a fallacy using symbols and computational expressions. This might lead some to believe that the fallacies are subjective, but this is not really true.&lt;br /&gt;&lt;br /&gt;So why are fallacies important if they are not easily expressed mathematically, and thus difficult to represent programmatically? I suppose that if all you do is program on your own, then perhaps they are not relevant to you. If instead you work on a team with other programmers (or non-programmers for that matter,) then you will have ideas that are argued/debated. In this case, you need to understand fallacies -- so that you can express your arguments without committing a fallacy and so that you can recognize when people arguing against you are committing fallacies.&lt;br /&gt;&lt;br /&gt;If you have an argument, and you find yourself committing a fallacy, then of course you will want to "fix" your argument to remove the error. This will inevitably draw out the assumptions in your argument, and strip out that which is not essential and true. Sometimes this will leave you with nothing, and you will be forced to question your own argument. Perhaps it was false or more likely mostly based on subjective statements, not fact. That can be a bummer, but wouldn't you rather realize that you are wrong than have somebody else point it out? Or worse, have nobody point it out...&lt;br /&gt;&lt;br /&gt;You need to recognize when others are committing fallacies. At the very least you need to strike this from your own mental record of their argument. Does their argument make sense without the fallacy, or is it essential? Of course if you start noticing these kind of fallacies, then you may be tempted to point them out and use that to assert that their argument is false and thus your argument must be right. Oops, you just &lt;a href="http://www.nizkor.org/features/fallacies/poisoning-the-well.html"&gt;poisoned the well&lt;/a&gt; and committed a &lt;a href="http://www.nizkor.org/features/fallacies/false-dilemma.html"&gt;false dilemma&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Once you start noticing fallacies, you might notice that people commit them a lot. Sometimes this may seem to be true irrespective of the perceived intelligence of the committers. It is easy to make these mistakes when you are unaware of them. They are also much more common when people are "thinking on their feet." In fact, I had a professor who once joked that those who were good at thinking on their feet, were simply good at synthesizing fallacies. I'm not sure if that is a fair generalization, but you get the point. I think people are also much more likely to make these kind of errors when emotion has entered into the argument. I think that was the most likely case in the blog post that inspired this post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-8421349960664158943?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/8421349960664158943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=8421349960664158943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8421349960664158943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8421349960664158943'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/03/programming-and-fallacies.html' title='Programming and fallacies'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4641428586283005360</id><published>2010-03-21T09:58:00.000-07:00</published><updated>2010-03-21T09:58:35.125-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='ie9'/><category scheme='http://www.blogger.com/atom/ns#' term='mix'/><title type='text'>MIXation Sensation</title><content type='html'>This past week was Microsoft's MIX conference. I almost went to it, and I would have gone if it was not the same week as my oldest son's birthday. You gotta have priorities. Anyways, the reason I almost went was not because I have suddenly embraced ASP.NET development (even though I must admit my admiration for &lt;a href="http://weblogs.asp.net/Scottgu/"&gt;Scott Gu&lt;/a&gt;). No, my interest is all browser related and MIX was browser heavy this year.&lt;br /&gt;&lt;br /&gt;On the browser front, the big news was the early preview of IE9. For web enthusiasts, it's fun to wax poetic about the mind blowing speed of V8 or the brilliance of TraceMonkey, but these technologies will always be secondary at best. If you are a web developer the most important browsers are the ones from Microsoft, because they dominate the market. They form the baseline that you develop against. If you want to do something that these browser do not support, you have got &lt;a href="http://www.ibm.com/developerworks/opensource/library/wa-aj-flash/"&gt;to get creative&lt;/a&gt; or be willing to live with your work simply being a toy. Simply put, IE9 news is more important than all of the Firefox, Safari, Chrome, and Opera news combined.&lt;br /&gt;&lt;br /&gt;Luckily, Microsoft did not disappoint with IE9. It is obviously a far from finished product, and Microsoft was a little too dodgy on sharing its roadmap for my taste, but I can empathize with their position. Still they showed a browser with significant speed improvements and with support for a lot of standards based, visual eye candy. I'm talking about a lot of CSS3 features and most surprisingly, an amazing SVG implementation. They whipped out some classic Microsoft tricks, i.e. using their intimate relationship with their operating system to tap into GPU acceleration. You might think it's not a fair trick for them to do, but who cares? The boys at Mozilla, Apple, and Google have to accept this challenge, even if it will be super painful to pull of across platforms -- and Linux will surely suffer here once again.&lt;br /&gt;&lt;br /&gt;I was a little disappointed in some of the other JavaScript features. In particular, I was really hoping that Web Workers would be included with IE9, and I was cautiously optimistic that geolocation would also be included. Neither is included in the IE9 preview that Microsoft made available to developers.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/S6ZPt6TZ7ZI/AAAAAAAAAyk/Yk3c1T0OdGA/s1600-h/1QXV.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="77" src="http://1.bp.blogspot.com/_XmwdENwf53s/S6ZPt6TZ7ZI/AAAAAAAAAyk/Yk3c1T0OdGA/s400/1QXV.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Of course that definitely does not mean that these features are out of IE9. I think there is a lot more to come. Microsoft has done some amazing work to give IE9 a lot of graphics features, but they have left out Canvas. Further intense graphics programming would benefit from the multi-threaded programming model supplied by Web Workers. So it would make a lot of sense for both of these to be added. I'm even optimistic that Microsoft will implement these standards directly, and not offer some proprietary alternative.&lt;br /&gt;&lt;br /&gt;All of this makes you wonder about IE9 as a compelling graphics/gaming platform. I think that some serious tooling will be needed to make this viable. That's an area that Microsoft excels at. However, would this not put Microsoft in conflict with their own efforts around Silverlight? It's like the HTML 5 vs. Flash war could be played out in miniature within Microsoft's walls, only it would be IE9 vs. Silveright. Speaking of Silverlight...&lt;br /&gt;&lt;br /&gt;The other big news, from my perspective at least, that came out of MIX was a lot more information about the Windows Phone platform. As a mobile developer, I have very mixed feelings about Windows Phone. On one hand, I really like the idea of using Silverlight as the application platform. This is a mature application platform, with fantastic tooling. You get to use a beautiful programming language -- C# (oh an maybe other .NET langs, like F#?) that has a decent runtime that includes garbage collection. However, Microsoft looks like they are copying Apple's approach. A lot of the restrictions being placed on non-Microsoft applications are very similar to the restrictions placed on iPhone applications.&lt;br /&gt;&lt;br /&gt;Back to the browsers... Microsoft shipped a preview of tools for building Windows Phone applications. Again, major props to Microsoft for getting this software ready out at MIX, even if it is a little rough in places. I don't like companies using end users as a substitute for QA, but this is different. Getting tools into the hands of developers is critical. In this case, the tools include a Windows Phone emulator, which includes *drumroll please* the Windows Phone browser! As a mobile developer, this is the most important thing that can be included. I'll have to support your browser before I have to support your application platform.&lt;br /&gt;&lt;br /&gt;However, the Windows Phone browser is not very promising. It seems to be based on IE7. It does not seem to support many HTML 5 features at all. No geolocation. No local storage. No application cache. No web workers.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XmwdENwf53s/S6ZP4t3a19I/AAAAAAAAAys/gBl7KqIqTvo/s1600-h/1RE2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://1.bp.blogspot.com/_XmwdENwf53s/S6ZP4t3a19I/AAAAAAAAAys/gBl7KqIqTvo/s400/1RE2.jpg" width="202" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Maybe some of these things will be added by this fall, but I'm not as optimistic about this. Even the documentation that is included emphasizes building web applications that are designed to work on legacy browsers. They seem to be saying, don't go looking for coolness in the browser!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4641428586283005360?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4641428586283005360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4641428586283005360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4641428586283005360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4641428586283005360'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/03/mixation-sensation.html' title='MIXation Sensation'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XmwdENwf53s/S6ZPt6TZ7ZI/AAAAAAAAAyk/Yk3c1T0OdGA/s72-c/1QXV.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7323715071166567851</id><published>2010-03-03T13:02:00.000-08:00</published><updated>2010-03-03T13:02:51.890-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='geolocation'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Testing Geolocation for Mobile Web Apps</title><content type='html'>Using geolocation in a web application is really cool. The JavaScript API is quite simple. Testing it, can be a different story. Here are some useful tips:&lt;br /&gt;&lt;br /&gt;If you only need to get the user's location once, testing is not too bad at all. First, you can actually use Firefox 3.5+. However, make sure that you are using wi-fi, or otherwise you will never get a location. Your app will just seem to hang. Anyways, being able to use Firefox for testing is great because it is a full desktop browser with awesome developers tools like Firebug. Often you will have some pretty complex JavaScript in a web application that uses geolocation, so being able to debug with Firefox/Firebug is invaluable.&lt;br /&gt;&lt;br /&gt;Of course you will also want to test on mobile browsers. You can definitely use the iPhone simulator that is part of the iPhone SDK. Geolocation works great on this, but it gives you a bogus location -- the location of Apple's HQ in Cupertino, CA. If you actually live near Cupertino, this can be really misleading. Anyways, it will only give you this location, never anything else. So it is somewhat limited.&lt;br /&gt;&lt;br /&gt;Testing on an Android emulator is another possibility. However, in my experience, it is currently broken. On an Android device, when a web page wants your location, the browser brings up a window to prompt you for permission. On the emulator's browser, I never see this permission window and the app just hangs and never returns a location. That's a bummer, since the Android SDK makes it possible to send mock GPS coordinates to an Android emulator. It would be great if web developers could take advantage of this.&lt;br /&gt;&lt;br /&gt;Testing on an actual devices is of course a possibility. Your web application needs to be reachable by the device. This could mean using wi-fi on your device, so you are in the same intranet as your development sever, or it could mean deploying your app somewhere public. I like using the Google App Engine for the latter, and then test on the assortment of devices that I have laying around.&lt;br /&gt;&lt;br /&gt;If you need to test location updates, i.e. when the user moves you want your web application to know about it and respond in some way, then things get trickier. The iPhone simulator is out of the question. An Android emulator still suffers from the same problems. So now you are down to devices. There is no way to send mock GPS to an iPhone, so to test on an iPhone, you need to actually change your physical location. Coding and driving FTW!&lt;br /&gt;&lt;br /&gt;However, it should be possible to test on an Android device. The Android SDK theoretically allows you to send mock GPS to a real device. The command that should work is "adb -s XXX shell geo fix AAA BBB" where XXX is the serial number of your device (get it by doing "adb devices"), and AAA/BBB are the fake latitude/longitude. Sounds good, right? I tried this on my Nexus One, and got a big fat permission denied. Turns out you need to be root to do this on a real device. Ok, so I rooted my Nexus One. Then I tried it. Result? "gps: not found." Suddenly the gps command was not recognized. So ... coding and driving FTW!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7323715071166567851?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7323715071166567851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7323715071166567851' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7323715071166567851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7323715071166567851'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/03/testing-geolocation-for-mobile-web-apps.html' title='Testing Geolocation for Mobile Web Apps'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-2027012103480533938</id><published>2010-02-24T16:32:00.000-08:00</published><updated>2010-02-24T16:32:52.340-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><category scheme='http://www.blogger.com/atom/ns#' term='0-guard'/><category scheme='http://www.blogger.com/atom/ns#' term='bill simmons'/><category scheme='http://www.blogger.com/atom/ns#' term='nba'/><title type='text'>The 0-Guard</title><content type='html'>Last week I was reading &lt;a href="http://sports.espn.go.com/espn/page2/story?page=simmons/100208/two"&gt;an excellent article&lt;/a&gt; by &lt;a href="http://sports.espn.go.com/espn/page2/simmons/"&gt;Bill Simmons&lt;/a&gt; on the "true" trade value of NBA players. While talking about likely rookie-of-the-year Tyreke Evans, Simmons dubbed him 0-guard. I thought that this was quite clever, and several other players immediately came to mind. Simmons went on to list three other players as 0-guards: Gilbert Arenas, Dwayne Wade, and Brandon Roy. I thought of some others. Here are what I would call the defining characteristics of the 0-guard:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1.) They must have the ball in their hands. These are players who generally useless on offense without the ball. They are not good spot-up shooters. They aren't going to move well without the ball to get open or get teammates open. They generally look lost in a half-court offense if the ball is not in their hands at all times.&lt;/div&gt;&lt;div&gt;2.) They are not good passers. Now many 0-guards rack up a lot of assists. However that is just because the ball is always in their hands. The only way they pass the ball is if the defense is all over them and teammates are wide open, hence the assists. However, they don't always do this very effectively. For example, in his best years Arenas averaged 6 assists/game, but also 3.5 turnovers/game while averaging 21 shots/game and 10 free throw attempts/game. Last year, Dwayne Wade averaged 7.5 assists/game, but that came with 5 turnovers/game, while taking 22 shots and 10 free throws per game.&lt;/div&gt;&lt;div&gt;3.) They can get their shot -- easily. This kind of goes without saying. All of these guys are effective at creating for themselves/getting open off the dribble, around screens, etc. If they couldn't do this, they would not be playing at all. Often they are spectacularly good at this -- Dwayne Wade for example.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These are the three obvious 0-guard characteristics. However, there are some other more subtle shared characteristics.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;4.) They are poor rebounders. These guys want to get out in transition, so they do not hit the defensive glass and they make no attempts to box out anyone.&lt;/div&gt;&lt;div&gt;5.) They are defensive liabilities. Sort of a continuation from #4. All of their energy goes into scoring, not much is left for defense. Now some guys may average a lot of steals, but that is a notoriously misleading statistic when it comes to defense.&lt;/div&gt;&lt;div&gt;6.) Point guard size. Maybe this helps to explain #5 and #4, but these guys generally don't have the size to match up against shooting guards. This does not necessarily imply being short -- Wade is 6-4 and Evans is 6-6.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Given the above, I don't think Brandon Roy belongs on the list. For his career he has averaged 5 assists but only 2 turnovers per game, while taking 16 shots and 6 free throw attempts per game. That does not sound like a guy who has to have the ball in hand -- or maybe I'm wrong and he's just not a very good 0-guard. I think Simmons put him on the list because Roy demands the ball in his hands at the end of games.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are some other obvious guys who belong on this list. Starting locally, Monta Ellis is definitely a 0-guard. This year he has averaged 5 assists / 4 turnovers per game, while taking 22 shots and 6 free throw attempts per game. This is definitely Arenas/Wade country. Brandon Jennings is borderline. So is Derrick Rose, but in both cases these guys are young enough to "grow out of it." Rodney Stuckey is a 0-guard, but not a very good one. Jason Terry also qualifies, but he doesn't realize it. He thinks he can spot-up and shoot, but he can't.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally, I think Bill Simmons got it wrong when he said that Gilbert Arenas invented the 0-guard position. To me, the quintessential and original 0-guard was Allen Iverson. He had a season (01-02) where he averaged 5.5 assists / 4.0 turnovers to go with 28 shots and 10 free throw attempts per game! Now late in his career, he did become a better passer, but was still more of a 0-guard than a point guard.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-2027012103480533938?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/2027012103480533938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=2027012103480533938' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2027012103480533938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/2027012103480533938'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/0-guard.html' title='The 0-Guard'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3276017251617512848</id><published>2010-02-18T14:28:00.000-08:00</published><updated>2010-02-18T14:28:28.825-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='ebay'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>eBay Mobile for Android</title><content type='html'>&lt;div&gt;I have been working on mobile at eBay since the fall of 2008. Almost immediately upon joining the team, I started running my mouth about how we needed to create an Android application. At the time, the G1 had just come out, and let's be honest. It was definitely a cut below the iPhone -- the standard that all phones are measured against whether they like it or not. The development environment was attractive, but we had to be pragmatic about things. eBay Mobile for iPhone was a big hit, and we had tons of ides for improving it. So Android had to wait. Yesterday, the wait was over and eBay Mobile for Android became available for download from the Android Market. It requires Android 1.6, and we have not rolled it out in all of the countries that our iPhone app is available in, so depending on your device and your location, it may not yet show up in the Market. If you're on 1.6, just be patient, hopefully we'll be in your country soon. If you're on 1.0/1.1/1.5... well your carrier needs to upgrade you to 1.6 :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The app was the result of a lot of hard work by some very talented engineers. If you have an Android phone, then of course I am hoping you will go try it out. One of the cool features of the Android platform that we took advantage of is integration with the system level QuickSearch. This makes it possible for popular search terms on eBay to be automatically suggested to you as type in the QuickSearch box on the home screen of your phone. However, this is one of those kind of curious features in Android. It is relatively easy to do (though making it fast, for something dynamic like popular search terms on eBay, can be tricky -- our engineers did an awesome job on this), but it is not something that you can "enable" by default. What I mean is that any application can become a provider for the QuickSearch box, but the applications cannot get their suggestions to automatically appear. Instead the user must manually enable add the provider, and this is not the most obvious thing to do. To give you an idea, I did a short video that shows you how to do this:&lt;/div&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/_vlzgmJIvTo&amp;hl=en_US&amp;fs=1&amp;color1=0x006699&amp;color2=0x54abd6"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/_vlzgmJIvTo&amp;hl=en_US&amp;fs=1&amp;color1=0x006699&amp;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;See what I mean? It's hard to expect that most users will figure this out on their own. Maybe we could put some kind of message in the app instructing them how to do this, but it is not something you can really describe succinctly. Anyways, as you see in the video, one you add eBay to your list of search providers, the results from eBay will only appear at the bottom of the list of suggestions. Once again, it would be very easy for a user to not even know that they are there. If they scroll down and find them, and do this a few times, then supposedly Android is smart and starts putting the eBay results closer to the top of the list...&lt;br /&gt;&lt;br /&gt;I think this is something that Android could definitely improve on, since I think it is a great idea to allow other apps to hook into the "global" search if you will. I can definitely imagine the Facebook app and various Twitter apps doing this too. However, one could understand if apps did not do this, given how difficult it is for an apps' contributions to surface in the search suggestions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3276017251617512848?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3276017251617512848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3276017251617512848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3276017251617512848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3276017251617512848'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/ebay-mobile-for-android.html' title='eBay Mobile for Android'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6436766715697517157</id><published>2010-02-17T09:53:00.000-08:00</published><updated>2010-02-17T14:57:54.636-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='nexus one'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Nexus One vs. iPhone</title><content type='html'>I recently purchased a Nexus One, primarily for Android development. I needed a device for developing Android 2.0+ on. The 2.0 SDK has been out for almost three months now, and yet it is still not available for my old developer phone, the Android Dev Phone One. I had gotten pessimistic about HTC making Android 2.1 (since apparently 2.0 is being skipped) for the ADP1, which is essentially the G1, so it was time to buy a new phone for development. I decided to spend some quality time with the phone, i.e. as a user, not a developer, and share my thoughts.&lt;br /&gt;&lt;br /&gt;First, a caveat... I plopped in my AT&amp;amp;T SIM card into the N1 before turning it on. That worked just fine -- with some known limitations. By working just fine, I mean that the N1 recognized the SIM card and configured itself for AT&amp;amp;T's APN without me doing anything. This was not the case with the ADP1, which was actually a pain to get working initially. You see, every Android phone that I have used wants you to sign in to Google before doing anything else. This can be a real problem if it cannot use the SIM card to access a data network. Anyways, it was no problem at all for the N1. However, as Google has pointed out, the N1 is not able to access AT&amp;amp;T's 3G network. It does not have the right radio for this. I have no idea why this is the case, but I will say this. Let's just imagine that I loved the N1 so much, that I decided that I wanted it to be my everyday phone instead of my iPhone. Even if that was the case, there is no way I would do this, since I would have to switch service to T-Mobile in order to access a 3G network on the G1, and for me (as well as most iPhone users) that would meaning breaking my contract with AT&amp;amp;T. On the other hand, if Google/HTC had only put the right radio in the N1, so that it could access AT&amp;amp;T's 3G network, then that would not be an issue. I bring all of this up now, because it does make it more difficult to compare the two phones. If you have one phone that is on 3G and another on Edge, you will prefer the 3G one unless the Edge phone is just way better in every other way.&lt;br /&gt;&lt;br /&gt;Ok, so the good news is that the N1 is definitely a phone that I could live with. It is fast, I mean really fast. Navigating between applications, applications execution, startup, etc. are all very fast on this phone. I would say it is noticeably faster than my iPhone 3GS. In fact, I did some mini-benchmarking between the eBay Mobile app for the iPhone and our new eBay Mobile app for Android, running on the 3GS and N1 respectively. I put both phones on the same Wi-Fi network for this test. The N1 app was definitely faster than the 3GS app. Now the code is different, as our Android app takes advantage of some the Android features to speed up some common things in the app. Still, the Android app is running in an interpreted environment, the Dalvik VM, not as native code like the iPhone app. So even though it was definitely an apples to oranges comparison, I still found it relevant. Our app on the ADP1 (Android 1.6) was much slower.&lt;br /&gt;&lt;br /&gt;The phone is also aesthetically pleasing. It is a pleasure to use. It looks nice. It is incredibly thin. In fact, the iPhone feels very chunky in my hand, after using the N1. Using the phone was very intuitive, but of course I have been using Android phones for over a year now, so I am certainly used to the OS. As a phone, it is on par with the 3GS, which is to say it is ok, nothing to brag about. The soft keyboard is easy to use for me, probably because I am used to using an iPhone. The word suggestions on Android are really nice, and it took me no time to start using them aggressively, thus saving myself a lot of typing.&lt;br /&gt;&lt;br /&gt;My favorite part about the phone is the email. We use MS Exchange at work, and I am a long time GMail user for my personal email. With the N1, I could setup both to be in a push mode. On my iPhone, I can only setup one or the other to be in push. So on my iPhone, I have to check my mail to know if I have new GMail, but I immediately know about it on the N1. Also, I think email for both of my accounts looks better on the N1.&lt;br /&gt;&lt;br /&gt;However, this brings me to a negative for the N1. It will connect to our MS Exchange server with no problems and can sync both email and contacts from Exchange, but not calendar. I have been told that this should be possible, but all solutions I have seen involved either 3rd party software, or using a workaround like syncing my Exchange calendar to a Google calendar first, and then syncing the Google calendar to the N1. I don't want workarounds, I just want something that works easily, so this is a huge negative for me. When I am at work, I often go from one meeting to another, and it is invaluable for me to be able to look at my phone to know when/where my next meeting is.&lt;br /&gt;&lt;br /&gt;Speaking of apps, the Android Market is growing rapidly. The Facebook app for Android is very nice, and its use of the OS to allow you to integrate your friends list with your address book on the N1 is excellent. There are a lot of Twitter apps for the N1, I personally liked Swift. There are a lot of other quality apps out there as well. Here is a handy &lt;a href="http://docs.google.com/View?id=ajmh7zht8f5f_3dbdpf6xv"&gt;equivalency table of apps between iPhone/Android from Alex Payne&lt;/a&gt;. Still, this is definitely an area where the iPhone has a huge advantage. For me, the advantage is most pronounced for games. There are so many more games on the iPhone, with more well known titles (often backed by big companies like EA.) Also, the games seem to be much higher quality. The number/quality of titles will likely improve over time. Hopefully the quality of the games will too. Perhaps this is an area where the Dalvik VM gets in the way, though you can certainly go native for games, potentially reusing code developed for the iPhone.&lt;br /&gt;&lt;br /&gt;A couple of more things, both good and bad... The browser on the N1 is excellent, definitely on par with the iPhone's. That is both from a user perspective and a developer perspective. Having multi-touch in the browser makes a huge difference for users. Adopting HTML 5 standards makes a big difference for developers. I never saw any pages that rendered noticeably differently on the N1 than they did on my 3GS. Usually it was the same only faster. Overall the browser, like most other things, tend to look better on the N1 than the 3GS simply because the screen is so much better... On the downside, the camera was a little more inconsistent for me on the N1. There have been times where I took pictures on it that came out completely out of focus. They certainly did not look out of focus when I took the picture. Maybe this is bad luck. The N1 has a 5MP camera, but I would not say that rates it above the 3GS. Don't get fooled the megapixel myth. I think pictures on both cameras were of similar quality -- except when the N1 would get things out of focus. The flash on the N1 seems useful however.&lt;br /&gt;&lt;br /&gt;So there it is. If I lost both of my phones and AT&amp;amp;T cancelled my contract, it would actually be a tough decision between the 3GS and the N1. I would go with the 3GS because of the calendar issue and its big advantage in number of apps/games available for it. The calendar issue seems like an easy issue to address, and the apps/games discrepancy is become less pronounced. It's not like the Android Market needs to have parity with the App Store, at least not in terms of quantity. Also my issues are far from universal. So I could definitely see a lot of people picking the N1 over the 3GS.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-6436766715697517157?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/6436766715697517157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=6436766715697517157' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6436766715697517157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6436766715697517157'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/nexus-one-vs-iphone.html' title='Nexus One vs. iPhone'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6396433314862682216</id><published>2010-02-14T21:33:00.000-08:00</published><updated>2010-02-14T21:33:53.110-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbook'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><title type='text'>The Anti-Netbook</title><content type='html'>For Christmas this year, I bought my kids (ages 4 and 5) their first computer: an Acer Revo. I call this the anti-netbook, but it actually shares a lot of things with a netbook. First is its processor, an Intel Atom clock in at 1.6 GHz. This helps to make for an incredibly small form factor, especially for a desktop computer. It has a 160 GB hard drive, but no optical drive.&lt;br /&gt;&lt;br /&gt;When I bought the computer, I had exactly one reason for it. I wanted my kids to play educational games on it. That was all. The Revo came with Windows XP installed on it, and this was perfect. I needed Windows on there to get the largest number of potential games for it. Windows 7 seems to be much less of a resource hog than Vista, but I am still wagering that XP comes with less overhead.&lt;br /&gt;&lt;br /&gt;I had another somewhat unusual plan for the Revo. It is completely isolated. No network access, not even local intranet. This is why I call it the anti-netbook. I want no Internet on it, I only want software that I personally installed to ever run on it. It is like a miniature Battlestar Galactica. Now I know there are a lot of websites with great games for kids, but I don't need them. I can find plenty of shrink-wrapped software to buy at incredibly cheap prices. However, this did lead me to some problems with the computer.&lt;br /&gt;&lt;br /&gt;The first problem was how to install all of this software, since I had no optical drive. I was prepared for this. I simply copied the software to a flash drive and plugged that into one of the four USB ports on the Revo. This is where I encountered my first problem. Many of these titles require the original CD to be inserted into an optical drive in order to run the game. I suppose this is an anti-piracy tactic, but it really caused me problems. For a couple of the games, I could leave the flash drive plugged in and they were happy. This did not work for most of the games.&lt;br /&gt;&lt;br /&gt;So I bought an external optical drive that could be connected via USB. This worked perfectly well, but it does mean that to change the games, one has to generally change discs in the external drive. This is not something that I trust my kids to do yet... I had one more nasty surprise in store for me. Many, actually most games published these days require the game to connect to the Internet, either to install or to play or both. There was a PBS Kids game we bought that was like this, and it was complete fail when we tried to install on the anti-netbook. So I had to make sure to only buy games that did not explicitly list an Internet connection as a hardware requirement, which generally meant buying a lot of older games. Still I found plenty of such games to choose from.&lt;br /&gt;&lt;br /&gt;At some point I will want my kids to be able to do more with a computer. They will need a word processor. Of course I would like to teach them both to program. I would like to get them something like Mathematic/MatLab. And of course by then, they will need a computer that is connected to the Internet. When that day arrives, I will get them a Mac -- but probably not an iPad. I will teach them the old school ways!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-6396433314862682216?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/6396433314862682216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=6396433314862682216' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6396433314862682216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6396433314862682216'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/anti-netbook.html' title='The Anti-Netbook'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3950852886953316062</id><published>2010-02-12T09:35:00.000-08:00</published><updated>2010-02-12T09:35:25.960-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='safari'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><title type='text'>The Truth About Europe</title><content type='html'>Earlier this week I read &lt;a href="http://www.quirksmode.org/blog/archives/2010/02/the_iphone_obse.html"&gt;yet another fascinating post by Peter-Paul Koch&lt;/a&gt;. In this post, @ppk takes on developers who think that developing for mobile just means developing for the iPhone. He points out that the iPhone has a small market share, in terms of number of devices being bought or in use. He tackles the obvious counter-argument that the iPhone dominates in terms of mobile Internet usage in the US. In particular he points out that the US does not matter, since Asia and Europe account for a much higher percentage of mobile users worldwide. He is completely right, but if you are a mobile web developer, these facts are completely irrelevant.&lt;br /&gt;&lt;br /&gt;It does not matter how many mobile web users there are in North America, Asia, or Europe. This has no bearing on how you design your site or what kind of technologies you choose to adopt. All that matters are the users of your site and what kind of devices they use. There can be 100x more smartphones in Japan than in Spain, but if all of your users are in Spain, then you should not care about Symbian's market share in Japan.&lt;br /&gt;&lt;br /&gt;For a lot of sites, it is very easy to figure out where their users are because they are not localized. If your site is focussed on Brazil, then it's a good bet that most of your users are in Brazil. For sites that are international, things get trickier. This is a problem that I have had to deal with at eBay. Fortunately my job was easier because we already had a mobile site that was setup almost ten years ago. It is designed to support all devices, from old school WAP devices all the way up to iPhones and Droids. It has a presence in all of the countries where eBay has a presence. So there I had a lot of data to use where I could say "this % of our users are using iPhones, this % are using Blackberries" etc.&lt;br /&gt;&lt;br /&gt;Most people do not have this luxury. If you do not have a specialized site for mobile, you can still look at your server logs and figure out what mobile devices are being used to access your site. However, you should be cautious with this data. If you do not have a specialized site, chances are your main site does not work properly on a lot of devices (especially true if you use a lot of JavaScript.) So chances are your users that use those devices will not use your site from their devices. However, chances are that your site does work properly on an iPhone, even if it is far from optimized for it. So iPhone users may be over-represented in your data. &amp;nbsp;You might want to fall back to using X% of users are from A, Y% from B, and the devices breakdowns in A and B are... Now if your site relies on Flash...&lt;br /&gt;&lt;br /&gt;Let's get back to the @ppk's post and the iPhone for a moment. He makes a nice analogy to IE6 back in the day. When doing analysis on mobile eBay traffic and our strategy for the future, I actually made a similar analogy. There is one huge difference. The iPhone's browser, Mobile Safari, has been a front-runner in adopting HTML 5 standards. If you are optimizing for the iPhone, there is a good chance that you are in fact using HTML 5 standards. In other words, optimizing for the iPhone does not mean adopting a plethora of technologies that are proprietary to Mobile Safari. It's just the opposite in fact. This is the fundamental difference between Mobile Safari today and IE6 circa 2002. That is not to say that there aren't some technologies that are unique to Mobile Safari. There are. However, those are the exception, not the norm. Most of the code that you could write for Mobile Safari that would not work on other mobile browsers is actually standardized APIs that other browsers simply have not yet implemented. So yes, you could be excluding users -- this is where you need to figure out what devices your users are using -- but you are not putting up an iPhone-only wall. You are putting up a wall, but it is a "modern device that supports web standards" wall.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3950852886953316062?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3950852886953316062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3950852886953316062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3950852886953316062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3950852886953316062'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/truth-about-europe.html' title='The Truth About Europe'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-8050606348387396547</id><published>2010-02-10T21:28:00.000-08:00</published><updated>2010-02-10T21:28:12.876-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='startups'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>On Open Floor Plans</title><content type='html'>Way back in 2006, I was working for a startup, originally called Sharefare and later renamed to Ludi Labs. When I first joined Sharefare, we had an old office space in Los Altos. It was a "traditional" office space, divided up into offices, with only two large open areas. One was the front reception, and other was a break room area. While there, we had around ten engineers. We would put 2-3 engineers per office. It worked pretty well.&lt;br /&gt;&lt;br /&gt;After I had been at Sharefare a few months, we received another round of funding, but it came with a catch. Our board wanted us to hire a "real" CEO, since our CEO/founder was a very technical guy, not an MBA type at all. Our CEO came from &lt;a href="http://www.underarmour.com/"&gt;Under Armour&lt;/a&gt;, you know the sports apparel maker. He was an east coast guy, who I'm sure we paid a ton to relocate to the Bay Area. When he arrived, we were running out of space in our little old office in Los Altos. So he decided that one of his first priorities would be getting us a new office. He had a vision for the new office -- the floor of the Wall Street stock exchange. He wanted an open floor plan that would encourage collaboration and keep everyone energized. So we moved into a brand new office (we were the first&amp;nbsp;tenants) with a completely wide open space.&lt;br /&gt;&lt;br /&gt;Now I always attributed this hubris to our CEO being an east coast guy who had never really been around engineers. You see, engineers do not work well in hectic, loud environments like the floor of the Wall Street stock exchange. A very large part of their job is thinking, and people running around making noise does not help an engineer think. Lots of &lt;a href="http://www.joelonsoftware.com/articles/BionicOffice.html"&gt;other folks have written&lt;/a&gt; about what kind of environment does work well for engineers, so I won't go too much into it. I'm just here to tell you what does not work.&lt;br /&gt;&lt;br /&gt;The open floor plan is complete fail. The most obvious problem is the noise. First, most companies have some non-engineers who work for them. Some of these non-engineers really need to do a lot of talking to do their job. They need to be on the phone ordering office supplies, or talking to potential business partners, or screening new hires. These people constantly generate noise. Put that in an open floor plan, and there is always noise. This is a constant drain on other folks, like engineers and designers, whose work requires them to think a lot.&lt;br /&gt;&lt;br /&gt;The next problem is that engineers and designers, do indeed need to talk sometime as well. Sometimes this is talking about work stuff, but there is also a lot of non-work stuff that engineers talk about. Maybe they are debating closures in Java or the merits of Python vs. Ruby. You want engineers who bullshit about stuff like that. Or maybe they are just talking about the Super Bowl or Lost. There is value in this too (y'know that whole "team building" thing.) Anyways, when you are in an open environment where noise is already problem, then it really discourages this kind of engineering conversations. If you are lucky enough to need to talk to your fellow engineer when it is relatively quiet in the office, you may be reluctant to engage him/her because you want to relish the peace. If instead it is during a typically noisy time, you will ask yourself if whatever topic is really worth talking about if it means shouting over the din. Instead of encouraging collaboration, the open floor plan does the opposite.&lt;br /&gt;&lt;br /&gt;Back to Sharefare... It did not take long for everyone to realize that the open office was not working. First, we tried to put the engineers and non-engineers at opposite ends of the office. We had a handful of real offices that were intended for execs. Instead they were kept open, so that people could use them for longer phone conversations. I personally spent a lot of time in those rooms, doing phone interviews with potential new hires. Finally, the CEO came clean and admitted that the whole thing had been a bad decision on his part. He bought everyone Bose noise&amp;nbsp;canceling headphones, supposedly out of his own pocket. This was his high point of popularity with engineering. Now when you walked into the office, everyone constantly had the Bose headphones on. I think this also hurt collaboration. I know I am personally less likely to try to start a conversation with somebody with headphones on.&lt;br /&gt;&lt;br /&gt;Anyways, that was our failed experiment. It seems like the idea has been picked up more and more in the Valley. A lot of companies are opting for this configuration. I think some do it as a cost cutting measure. You can spend a lot less on furniture with an open floor plan, and you can pack in a lot more people in a given space. Others claim that it is all about encouraging collaboration. Again, my experience is that it will do the opposite. Still others do it because they want to break away from the traditional cubicle environment. To those folks I would say: "function over form." An ugly office full of productive engineers is better than a stylish office full of miserable engineers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-8050606348387396547?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/8050606348387396547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=8050606348387396547' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8050606348387396547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/8050606348387396547'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/on-open-floor-plans.html' title='On Open Floor Plans'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1001123504403173472</id><published>2010-02-05T13:54:00.000-08:00</published><updated>2010-02-05T13:54:31.830-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><title type='text'>It's 2010, where's my HTML5?</title><content type='html'>This morning, one of my co-workers related to me that there had been mention of HTML 5 on an NPR broadcast that he heard. He joked that this morning there were probably lots of advertisers asking their designers about using HTML 5 for their next whiz-bang ad campaign. So obviously we are still in the early part of a hype cycle on HTML 5. So what's the state of the technology and where is it heading?&lt;br /&gt;&lt;br /&gt;In terms of pure technology, there is a lot of notable progress. Google did the right thing recently and axed Gears. They had some nice innovations in Gears that have since been rolled up into the HTML 5 standard. Now it makes perfect sense to abandon their proprietary implementation, and embrace the standard. Gears is important because it is (or was) part of Chrome. Thus there are essentially five browsers that now implement a significant subset of HTML 5: IE8, Firefox 3.5, Safari 4, Chrome 4, Opera 10. According to the latest browser share numbers, that means that 53% of users out there are using a browser that supports a lot of cool features, like local storage and selectors. That's more than half! It's tempting to extrapolate from that, but don't get too carried away.&lt;br /&gt;&lt;br /&gt;The #1 browser of the HTML 5 browsers, is IE8 -- which does not support a lot of the features that the other browsers support like canvas, video tag, and web workers. For those would be HTML 5 advertisers out there, you better scale back your expectations. For desktop browsers, a lot of the most compelling HTML 5 capabilities are far from being widely supported. How long until IE9 comes out? How much more of HTML 5 will it support? How long until there is high adoption of it? That's too many questions to be comfortable with. Ask me again this time next year.&lt;br /&gt;&lt;br /&gt;However, it's fun to pretend sometimes. Let's pretend that IE 9 did come out soon and that it supported everything supported by Firefox and Chrome. Let's even pretend that Microsoft was able to awaken some of their old monopolist mojo and somehow force people to upgrade. So we have a world full of canvas. Will the next great annoying ad use this? If you read &lt;a href="http://fupeg.blogspot.com/2010/02/flash-haters.html"&gt;my last post on Flash hate&lt;/a&gt;, you probably realize the answer is no. As Terry pointed out in the comments there, the Flash authoring tools really empower designers over developers. So before we see an explosion of canvas magic, there will have to be huge strides made in tooling. Now what about video? Even in our dream world, there are issues known as codecs. There is no common video format that will run on both Firefox and Chrome right now, and who knows what Microsoft will do here (WMA FTW!) So we are going to need some technical consolidation here. Let's summarize all of the things that we need to see happen to open up the golden age of HTML 5.&lt;br /&gt;&lt;br /&gt;1.) New version of Internet Explorer that supports much more of the HTML 5 specification.&lt;br /&gt;2.) This new version of IE needs to become the dominant flavor of IE.&lt;br /&gt;3.) Outstanding tooling developed to enable designers to leverage HTML 5 capabilities.&lt;br /&gt;4.) Standardization on video codecs by browser vendors.&lt;br /&gt;&lt;br /&gt;Don't get too bummed out about all of this. I actually think there is real progress happening on #1 and #3. #4 probably has to wait for #1 to happen. #2 is the most problematic. Since we're dreaming, maybe if IE 9 came out with H.264 support, Google could dramatically drop support for anything else on YouTube, and thus nudge all IE users to upgrade?&lt;br /&gt;&lt;br /&gt;If you want to drink the HTML 5 Kool-Aid, and this is bumming you out, I'm sorry. You might feel better to know that the HTML 5 situation is significantly better on mobile devices. &lt;a href="http://metrics.admob.com/2010/01/december-2009-mobile-metrics-report/"&gt;According to AdMob&lt;/a&gt;, 81% of internet usage in North America was either on iPhones or Android devices. Now, most of those Android devices are running Android 1.5 or 1.6, whose browsers (can we call it Mobile Chrome please?) still use Gears -- not HTML 5. Let's &amp;nbsp;hope that most of those are upgraded (by their carriers) to Android 2.1 soon, and then we're in business. We've got all kinds of HTML 5 goodness available to 80%+ of the users out there.&lt;br /&gt;&lt;br /&gt;The bad news is that the mobile market is fundamentally different than the desktop (though, &lt;a href="http://fupeg.blogspot.com/2010/01/ipad-brave-new-world.html"&gt;that may be changing&lt;/a&gt;.) Here mobile websites compete directly against native applications. Desktop users rarely face the question, should I use an app or a website to do XYZ? Normally XYZ dictates one or the other. So for a company, there may be a lot of cool stuff you can do with HTML 5 on a mobile browser, but there are even more cool things you can do in a native app. Not only are the native apps more powerful, they are generally easier to build because of superior tooling and cohesive architecture. Maybe JavaScript vs. Objective-C vs. Java is a matter of taste, but HTML 5 has nothing even resembling the application models presented by Cocoa and Android. Instead it has the DOM APIs in JavaScript. Now throw on the differences in tooling, and you can see why for many companies it is cheaper and easier to build an iPhone app and an Android app instead of building one HTML 5 app. That's not even considering the hypothesis that the "app store" model is more appealing to end users than the browser model.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1001123504403173472?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1001123504403173472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1001123504403173472' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1001123504403173472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1001123504403173472'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/its-2010-wheres-my-html5.html' title='It&apos;s 2010, where&apos;s my HTML5?'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-3584743654384339666</id><published>2010-02-03T14:17:00.000-08:00</published><updated>2010-02-03T14:17:20.935-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>The Flash Haters</title><content type='html'>The iPad announcement had lots of subtleties to it. One of them was that the iPad browser, presumably Safari, does not include a Flash plugin. This has lead to a lot of &lt;a href="http://blogs.adobe.com/conversations/2010/02/open_access_to_content_and_app.html"&gt;people from Adobe getting upset&lt;/a&gt;. What has amazed me through all of this, is that there is even more hate for Flash than ever before. As somebody who has done a fair amount of Flash development in my career, this has really struck me as odd. Why all of the hate for Flash?&lt;br /&gt;&lt;br /&gt;In some ways, I can actually understand why Apple would hate Flash. The Flash plugin on OSX is nowhere near as good as the Flash plugin on Windows. Now Adobe will counter they spend a&amp;nbsp;disproportionate amount of money on Flash for OSX, i.e. they spend more money per OSX user than they do per Windows user. So what? There are a lot of other technologies out there that work equally well on both Windows and OSX. Just focussing on web technologies, Firefox and Chrome on the Mac are very comparable to their Windows versions. So is the Java plugin. Some other products, like Opera and Skype, tend to trail in terms of features on OSX, but not in terms of quality. If these other companies can do this, why can't Adobe? It's obviously either lack of ability or prioritization. My guess is the latter, and hence you must expect hate from Mac users. And from Apple. So it should not be so surprising that Flash is left off the iPad, iPhone, etc. If Adobe really wanted to get Flash on those devices, an obvious first step would be to make Flash on OSX as good as Flash on Windows. That is something that Adobe can do all by themselves. Instead it seems like they would rather&amp;nbsp;publicly&amp;nbsp;bemoan their exclusion on the iPad. Now is there a&amp;nbsp;guarantee&amp;nbsp;that if they improved Flash on OSX, Apple would care? No, of course not. However, there is no way they will get on those devices without this first step, IMO.&lt;br /&gt;&lt;br /&gt;Ok, so Mac user hate for Flash is understandable. Along the same lines, I would guess that Linux user hate is also understandable. That is, if there were actually any Linux users out there. I digress. I see a lot of hate from developers. What about that? That one is not so easy for me to understand. As a web developer, Flash has been opening doorways for me for a long time. Need to cache 30 KB of data on the client? For a long time this was impossible unless you used Flash (or maybe Java.) Need to make a cross-domain call? That is still generally impossible from the browser, unless you use Flash. Need to show 2D/3D graphs and visualizations? Again, this is still generally impossible, except through Flash. Oh and video... The only way to show a video that can be played on all of the top five web browsers (IE8, IE7, Firefox 3.5, IE6, Firefox 3.0) is to use Flash.&lt;br /&gt;&lt;br /&gt;But, but, but, what about HTML 5? Many people think it will kill/replace/maim Flash. Apparently this list includes a certain Steve Jobs. As I have said before, I hate web standards. I mean, I love them, too. But I hate them mostly. Standards are the opposite of innovation, and perhaps its enemy. However, they are the engineer's best friend. Flash has provided a lot of innovation, that HTML 5 will simply copy and standardize. That is the best possible function of standards. However, the story is not so simple. Some things, like local storage, &amp;nbsp;are already supported by IE8, Firefox 3.5, and Safari 4. This is like Flash's SharedObjects, though slightly less powerful (but good enough.) Not everything is so rosy; canvas and video playback&amp;nbsp;immediately&amp;nbsp;come to mind. Canvas is particularly a hot topic. You can do some amazing things with it, but it requires payment in blood. I cannot imagine what it would be like to program Farmville in JavaScript using Canvas. Maybe somebody will come up with tools for that. In fact, I would be surprised if Adobe did not do this. Of course, we still need to hope and pray that canvas is supported in IE9...&lt;br /&gt;&lt;br /&gt;So back to the original point. Why do developers hate Flash? It certainly enables them to do more stuff in web applications. Even if that list of extra features is being shrunk by the HTML 5 monster, it's still there. So shouldn't they love it? Well, you would think so, but they don't. Here are some guesses as to why:&lt;br /&gt;&lt;br /&gt;1. Expensive tools -- Most of the tools used by a lot of developers are free. The Flash authoring tools are far from it. That can be annoying. You have to throw down a lot of money just learn something. That's not cool.&lt;br /&gt;2. Bad tools -- At least from a developer perspective. The Flash authoring tools have historically been aimed at designers. That changed with Flex Builder/Flash Builder, but the damage was done. Also, those tools were aimed more at application development, which largely seemed like a waste of Flash.&lt;br /&gt;3. Back to the Mac &amp;nbsp;-- A lot of developers use Macs, and we all know about Flash on OSX...&lt;br /&gt;4. Accessibility -- Unfortunately this doesn't mean much to most developers. But it should. I must admit, that a year ago I probably wouldn't have listed this. However, as I have learned more, I have learned how Flash is such a huge problem for accessibility. This is actually one area where HTML 5 really shines, with the inclusion of the ARIA standards.&lt;br /&gt;5. Design envy -- This kind of goes back to #2. Flash has had all the awesome capabilities for years, but they have largely gone untapped in web applications. Maybe by playing to designers all of those years, Flash has earned enemies. Imagine a developer being asked to scope some radical web feature. They give a typically large scope for it. His manager turns around and gets a designer, &lt;i&gt;a freakin' designer&lt;/i&gt;, to do it in half the time.&lt;br /&gt;&lt;br /&gt;What have I missed? Why do web developers hate Flash so much?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-3584743654384339666?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/3584743654384339666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=3584743654384339666' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3584743654384339666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/3584743654384339666'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/02/flash-haters.html' title='The Flash Haters'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-399185905324189866</id><published>2010-01-29T12:07:00.000-08:00</published><updated>2010-01-29T12:07:43.488-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>The iPad: A Brave New World</title><content type='html'>Has any piece of technology ever been more anticipated than the iPad? Has anything created as many extreme reactions? Has anything generated as much immediate ridicule?&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XmwdENwf53s/S2M0lkQSgjI/AAAAAAAAAvo/DWcWeTgT5BM/s1600-h/60598919.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="331" src="http://2.bp.blogspot.com/_XmwdENwf53s/S2M0lkQSgjI/AAAAAAAAAvo/DWcWeTgT5BM/s400/60598919.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyways, there are a lot of opinions out there, including some very good ones. I really like &lt;a href="http://al3x.net/2010/01/28/ipad.html"&gt;Alex Payne's take on the iPad&lt;/a&gt;. His post led me to &lt;a href="http://danieltenner.com/posts/0015-ipad-an-apple-for-mom.html"&gt;Daniel Tenner's analysis&lt;/a&gt;, which is probably the closest thing I have seen to my own opinion. While we are at it, I think &lt;a href="http://timothyblee.com/?p=2169"&gt;Timothy Blee's case against the iPad&lt;/a&gt; is definitely worth a read. Adobe's &lt;a href="http://www.mikechambers.com/blog/2010/01/28/some-personal-thoughts-on-apple-and-the-trend-towards-closed-platforms/"&gt;Mike Chambers has a very predictable reaction&lt;/a&gt;, but is still worth a read as well. But who cares about those guys, you're reading this because you want my brilliant insights, right?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think the iPad is Apple's boldest move since the 80's. In the 80's, they liberally borrowed a lot of existing ideas and added some of their own twists to reinvent personal computing. It was no longer the command line driven process. There no need for Unix or DOS. The iPad is equally ambitious.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Over the last two years, Apple has had a chance to experiment with a new kind of computing. The iPhone is accurately described as very capable personal computer that fits in your pocket. With it, Apple changed the way a user interacted with their computer. There was no more mouse, yet the keyboard was rarely needed. There was very little physical media to interact with, i.e. no floppy disks, CDs, or DVDs, only a very occasional physical linking to a desktop/laptop. Apple gave software developers a much more limited environment than they had ever had to deal with. Compared to desktop computer software, iPhone software is amazingly limited in how it can interact with the system (the iPhone). The distribution model was also controlled in a way rarely seen before. Apple had to approve your applications before they could be sold to users.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Yet even in this most restricted of environments, software developers have flourished. Why? As &lt;a href="http://joehewitt.com/post/ipad/"&gt;Joe Hewitt wisely points out&lt;/a&gt;, many of these restrictions really are for the best. I can install any app from the App Store, and I don't have to worry about it harming my iPhone. This is in stark contrast to desktop software, particularly the ubiquitous world of Windows.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But wait, it's worse. At least if you're a software developer. The Draconian distribution machine that is the App Store and its approval process is a key part of this peace of mind given to iPhone users. It also makes their lives much easier. Just go to the App Store, and you can find whatever kind of software that you are looking for. Or just browse the games, or maybe lifestyle or social media apps, and you can find something interesting. Reviews are built right into the system. It could get better, and Apple is working on this with their Genius system, but it beats the heck out of anything else out there.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The iPad takes this new model of personal computing and packages it into a personal computer. The iPad does not invent a new category. Just like the iPhone, it is going after an existing huge category, only this time it is the desktop/laptop category. Yes, this happens to be a category that Apple already plays in and is having a lot of success in. That is part of why this is so bold. The iPad is not going after the statistically insignificant category known as netbooks. Apple does not aim so low. Instead it is going after every person who owns a laptop.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Perhaps you think I am overstating, that Apple is not as bold as I claim. There were four new apps that Apple unveiled along with the iPad. One of those is iBooks, and I won't bother too much with that. The other three were Pages, Numbers, and Keynote. This is Apple's office suite. These are&amp;nbsp;competitors of Microsoft's Word, Excel, and PowerPoint. Now you can read many Office documents on an iPhone, but it is largely a read-only experience. These are not read programs. These are content creation programs. If you think about the history of Apple, could there be anything more symbolic than them shipping a word processing application with their new computing platform?&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I bought my wife a laptop a couple of years ago. It was essential for her to have Office on it. Word processors and spreadsheets are the meat and potatoes of desktop software. Of course she uses photo management and media management software too. All of these things are available on the iPad. The truth is she could easily replace her laptop with an iPad. It would be easier for her to carry around, have better battery life, and the 3G would work even if she was visiting her mother (who does not have wi-fi.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Think about all of the people whose job involves a computer. For most people, could they not do their job on an iPad? Wouldn't it even be easier in many cases? Of course it would be more convenient, again because of the size, battery life, and always being connected.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now there will definitely be some people who cannot use an iPad for their job. I am one of those people. Maybe you could write code on it ok, but compile/debug? Don't think so. Designers who do intense things with Illustrator, Photoshop, etc. will need more than an iPad, too. Ditto for scientists, engineers, etc. There are more groups as well, but it's still probably a minority. For all of those people who have to do a lot of typing? Well there's a dock for that. You get the idea.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Apple is offering a new model for personal computing. They are attempting to disrupt an entire industry, once again. The iPad is not a big iPod Touch or a big iPhone. It is not Apple's attempt to go after Amazon's Kindle. It is an attempt to dominate in a way that even Microsoft never got close to. Apple is going to every person who owns a computer and saying "look there's another, better, easier way." I think it's an all-or-nothing bet. The iPad is either a world changer, or a total failure. Which one will it be?&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-399185905324189866?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/399185905324189866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=399185905324189866' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/399185905324189866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/399185905324189866'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/01/ipad-brave-new-world.html' title='The iPad: A Brave New World'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XmwdENwf53s/S2M0lkQSgjI/AAAAAAAAAvo/DWcWeTgT5BM/s72-c/60598919.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-5118164036299762866</id><published>2010-01-20T13:00:00.000-08:00</published><updated>2010-01-20T13:00:56.687-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='javaone'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='jvmone'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>JVMOne</title><content type='html'>This morning, my co-worker &lt;a href="http://twitter.com/swartzrock"&gt;Jason Swartz&lt;/a&gt; had the great idea of a&lt;a href="http://twitter.com/swartzrock/status/7995602305"&gt; conference focussing on JVM languages&lt;/a&gt;. This seemed like a particularly good idea, given the uncertainty&amp;nbsp;surrounding JavaOne. Personally, I think the JavaOne powers-that-be have done a good job showcasing other languages, especially the last two years. Anyways, I joked that we could probably host it at our north campus, since it has proper facilities and regularly hosts medium sized conferences, &amp;nbsp;and that we just needed the support of folks from the Groovy, JRuby, Scala, and Clojure communities. A lot of folks seemed to like the idea, and had some great feedback/questions. So let me phrase some of these questions in the context of "a JavaOne-ish replacement, focussing on alternative languages on the JVM, but ultimately driven by the community". Ok here are some of the questions.&lt;br /&gt;&lt;br /&gt;1.) What about Java?&lt;br /&gt;2.) What about languages other than Groovy, JRuby, Scala, and Clojure?&lt;br /&gt;3.) What about first class technologies with their roots in Java, like Hadoop, Cassandra, etc.?&lt;br /&gt;&lt;br /&gt;Certainly I have opinions on some of these, but obviously any kind of effort like this requires huge participation from the developer community. So what do you think? What other questions need to be asked? If there is enough interest, I will definitely try to organize it. So please leave comments below!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-5118164036299762866?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/5118164036299762866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=5118164036299762866' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5118164036299762866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5118164036299762866'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/01/jvmone.html' title='JVMOne'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6108524578945880592</id><published>2010-01-19T22:12:00.000-08:00</published><updated>2010-01-19T22:12:54.180-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='ie'/><title type='text'>Stop the IE6 Hate</title><content type='html'>For a long time now, it has been common for developers to go on and on about how they hate IE6 and how users needed to be discouraged from using. It's gotten old. It's trite. It's time to move on.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;IE6 has become a non-factor for most sites. It trails far behind IE7 and IE8, not to mention Firefox. And of course, its numbers are always shrinking. I know that at a certain popular website that I happen to work for, we no longer test for IE6. It's been that way for us for 6+ months. It's over.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So now that it's over, there are some things that I want to see. First, I want to see all of those JavaScript libraries that everyone uses, drop their IE6 code branches. Shouldn't jQuery, Prototype, ExtJS, Dojo, etc. all be able to shave off a huge amount of their code? Shouldn't these libraries now progress even faster since they don't have to worry about IE6? Similarly, GWT and similar libraries should benefit as well. Websites should be able to remove some CSS hacks as well, though not all of them...&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, I want to see the same passionate disdain directed towards IE7. Now IE7 is not the bug ridden beast that IE6 was. Instead, IE7 is basically a properly patched IE6. As a developer, you would definitely prefer to deal with IE7. It works differently from all other browsers, but it is relatively consistent in the way it works. You could not say this about IE6. However, IE8 is much closer to the rest of the world. If IE7 were to drop off to obscurity like IE6 has done, then imagine the benefits. There would be far less need to write things in a different way for IE. There would be far less need for conditional CSS.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So stop hating on IE6. Move on. Start taking advantage of a world where IE6 is irrelevant. &amp;nbsp;And if you still want to hate, start hating on IE7. With a passion.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-6108524578945880592?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/6108524578945880592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=6108524578945880592' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6108524578945880592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/6108524578945880592'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/01/stop-ie6-hate.html' title='Stop the IE6 Hate'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4127765109212729046</id><published>2010-01-18T19:48:00.000-08:00</published><updated>2010-01-18T19:48:56.619-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Strikethrough Android</title><content type='html'>There are a lot of people working on mobile applications these days. Some of them are experienced mobile developers. Maybe they were doing J2ME or Brew apps in the past, and now they are probably happy to be doing iPhone or Android development. However, I would wager that a majority of current iPhone and Android developers were not doing mobile a few years ago. Maybe they were doing desktop development, or maybe they were doing web development. For these folks, it can be very surprising how tricky it is to do some (seemingly) simple things. Case in point, &lt;s&gt;strikethrough text&lt;/s&gt;.&lt;br /&gt;&lt;br /&gt;If you ever need to do this in Android, here is how you do it, or at least a relatively simple way I found to do it. If you just search the Android documentation, you will find &lt;a href="http://developer.android.com/guide/appendix/faq/commontasks.html"&gt;this reference page&lt;/a&gt;. As you can see for static text, it really is quite simple. It is very similar to doing it in HTML.&lt;br /&gt;&lt;pre class="brush:xml" name="code"&gt;&amp;lt;resource&amp;gt;&lt;br /&gt;    &amp;lt;string id="@+id/strike_one"&amp;gt;&amp;lt;strike&amp;gt;Strike one!&amp;lt;/strike&amp;gt;&amp;lt;/string&amp;gt;&lt;br /&gt;&amp;lt;/resources&amp;gt;&lt;br /&gt;&lt;/pre&gt;Nice! Android rocks! But what if your text is dynamic? Well if you keep reading the documentation referenced above, you get into the world of &lt;a href="http://developer.android.com/reference/android/text/Spannable.html"&gt;Spannable&lt;/a&gt;. This sounds good at first, because it sounds like it's again inspired from HTML. If you look at the sample, it is not so simple. Still, it's not too hard, maybe just a little awkward. But wait, there's more. The class most commonly used for text, &lt;a href="http://developer.android.com/reference/android/widget/TextView.html"&gt;TextView&lt;/a&gt;, is not a Spannable. Instead, you must use an &lt;a href="http://developer.android.com/reference/android/widget/EditText.html"&gt;EditText&lt;/a&gt;, which is a subclass of TextView. This is a class that you would not normally use for normal text on the screen, instead you would use it for a text input field.&lt;br /&gt;Turns out there is an easy way to strikethrough a TextView after all. Well easy, if you don't mind use some bit twiddling:&lt;br /&gt;&lt;pre class="brush:java"&gt;TextView someLabel = (TextView) findViewById(R.id.some_label);&lt;br /&gt;someLabel.setText(someDynamicString);&lt;br /&gt;someLabel.setPaintFlags(someLabel.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);&lt;br /&gt;&lt;/pre&gt;What is going on here? For painting text, there are several bit flags for doing things like bold, italics, and yes strikethrough. So to enable the strikethrough, you need to flip the bit that corresponds to this flag. The easiest way to do this is to use a bitwise-or on the current flags and a constant that corresponds to a set of flags with only the strikethrough flag enabled. For any other bit flags that are already set, this will have no effect. Actually if the strikethrough flag happened to be already set, this will have no effect. However, if it is not set, then it will flip it, so that it will be set and thus add a nice strikethrough effect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4127765109212729046?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4127765109212729046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4127765109212729046' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4127765109212729046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4127765109212729046'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2010/01/strikethrough-android.html' title='Strikethrough Android'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-5689422594497013188</id><published>2009-12-19T22:02:00.000-08:00</published><updated>2009-12-19T22:02:11.504-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Music of the Decade</title><content type='html'>In alphabetical order (more or less) ...&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;Favorite Songs&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Rehab -- Amy Winehouse&lt;br /&gt;The Rising -- Bruce Springsteen&lt;br /&gt;Yellow -- Coldplay&lt;br /&gt;The Scientist -- Coldplay&lt;br /&gt;Clocks -- Coldplay&lt;br /&gt;Stan -- Eminem&lt;br /&gt;Bring Me To Life -- Evanescence&lt;br /&gt;Where'd You Go -- Fort Minor&lt;br /&gt;Crazy -- Gnarls Barkley&lt;br /&gt;Feel Good, Inc. -- Gnarls Barkley&lt;br /&gt;Izzo (H.O.V.A.) -- Jay-Z&lt;br /&gt;D.O.A. (Death of Auto-Tune) -- Jay-Z&lt;br /&gt;Gold Digger -- Kanye West&lt;br /&gt;Gone -- Kanye West&lt;br /&gt;On Call -- Kings of Leon&lt;br /&gt;Dance With My Father -- Luther Vandross&lt;br /&gt;Paper Planes -- MIA&lt;br /&gt;Float On -- Modest Mouse&lt;br /&gt;Hey Ya! -- Outkast&lt;br /&gt;Young Folks -- Peter Bjorn and John&lt;br /&gt;Dani California -- Red Hot Chili Peppers&lt;br /&gt;Killing the Blues -- Robert Plant &amp;amp; Alison Krauss&lt;br /&gt;So Says I -- The Shins&lt;br /&gt;Lazy Eye -- Silversun Pickups&lt;br /&gt;City of Blinding Lights -- U2&lt;br /&gt;Beverly Hills -- Weezer&lt;br /&gt;The Joker &amp;amp; The Thief -- Wolfmother&lt;br /&gt;Seven Nation Army -- The White Stripes&lt;br /&gt;In Da Club -- 50 Cent&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Favorite Albums&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Neon Bible - Arcade Fire&lt;br /&gt;The Rising -- Bruce Springsteen&lt;br /&gt;Parachutes -- Coldplay&lt;br /&gt;A Rush of Blood to the Head -- Coldplay&lt;br /&gt;Viva La Vida -- Coldplay&lt;br /&gt;The Crane Wife -- The Decemberists&lt;br /&gt;American Idiot -- Green Day&lt;br /&gt;The Black Album -- Jay-Z&lt;br /&gt;The Blueprint -- Jay-Z&lt;br /&gt;Late Registration -- Kanye West&lt;br /&gt;The National -- Boxer&lt;br /&gt;The Slip -- Nine Inch Nails&lt;br /&gt;Year Zero -- Nine Inch Nails&lt;br /&gt;Speakerboxxx/The Love Below -- Outkast&lt;br /&gt;Backspacer -- Pearl Jam&lt;br /&gt;Wolfgang Amadeus Phoenix -- Phoenix&lt;br /&gt;In Rainbows -- Radiohead&lt;br /&gt;Kid A -- Radiohead&lt;br /&gt;Stadium Arcadium -- Red Hot Chili Peppers&lt;br /&gt;Carnavas -- Silversun Pickups&lt;br /&gt;Gimme Fiction -- Spoon&lt;br /&gt;Is This It -- The Strokes&lt;br /&gt;Toxicity -- System of a Down&lt;br /&gt;All That You Can't Leave Behind -- U2&lt;br /&gt;No Line on the Horizon -- U2&lt;br /&gt;Vampire Weekend -- Vampire Weekend&lt;br /&gt;Elephant -- The White Stripes&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-5689422594497013188?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/5689422594497013188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=5689422594497013188' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5689422594497013188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/5689422594497013188'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2009/12/music-of-decade.html' title='Music of the Decade'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7636424102744343912</id><published>2009-11-24T13:39:00.000-08:00</published><updated>2009-11-24T13:39:44.327-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='web applications'/><category scheme='http://www.blogger.com/atom/ns#' term='desktop applications'/><title type='text'>Web Developers Are Stupid and Arrogant</title><content type='html'>The past couple of days has seen &lt;a href="http://www.quirksmode.org/blog/archives/2009/11/apple_is_not_ev.html"&gt;an amusing rant by PPK&lt;/a&gt;, that then turned into &lt;a href="http://www.quirksmode.org/blog/archives/2009/11/native_iphone_a.html"&gt;a retraction and call to action&lt;/a&gt;. The original rant included a condemnation of iPhone developers as being stupid and arrogant. &lt;a href="http://almaer.com/blog/iphone-developers-are-not-arrogant-and-stupid"&gt;Others&lt;/a&gt; have adequately refuted PPK, so I won't bother with any of that. His post made me realize that it is in fact web developers who are mostly commonly guilty of stupidity and arrogance. Here's what I mean.&lt;br /&gt;&lt;br /&gt;It's easy to look at the world today and say that web applications have won. This is web developer arrogance. Stupidity is to think that web applications have won because web applications are superior to desktop applications. Smarter, but probably still arrogant developers would point to web applications as &lt;a href="http://en.wikipedia.org/wiki/Disruptive_technology"&gt;disruptive technologies&lt;/a&gt;. This involves admitting that web applications are inferior, but good enough, and present enough other "cheaper" advantages to compensate for their inferiority.&lt;br /&gt;&lt;br /&gt;To understand why the "web apps have won" claim is dubious. There are definitely a lot of awesome web applications out there. Many of them were created back in the mid/late 90's, The "features" of these applications were the key to applications, not the user interface. Now these days, most of these web applications offer APIs/web services/RESTful interfaces/whatever you want to call them. In many cases it is possible to build desktop applications that tap into the same features as these web applications. However, this was certainly not the case 10-15 years ago.&lt;br /&gt;&lt;br /&gt;So if APIs make it possible to build desktop apps that offer the same features as popular web applications, why haven't people switched? The first most obvious answer is inertia. If you are used to accessing Google or Amazon on the web, that's probably the way that you will always use it. Something else to consider is that for many web applications, it does not make sense for them to offer all of their features through APIs because it hurts their core business. This is most obviously true for advertising based companies like Google, Yahoo, and Facebook. Their web applications not only provide very useful features to end users, but they serve ads that make money for the companies. If all of their users switched to using desktop applications that only offered the features with no ads, then the companies would lose their revenue streams. Their business is connected at the hip with their UI, so it is in their best interest to make sure people use their UI -- which is a web application.&lt;br /&gt;&lt;br /&gt;However, there are other very successful web applications whose main revenue does not come from ads. Their business is distinct from their UI. E-commerce companies like Amazon and my employer, eBay are obvious examples. For example, eBay offers &lt;a href="http://developer.ebay.com/products/trading/"&gt;trading APIs&lt;/a&gt; that provide almost all of the trading features of eBay. This is particularly true for selling on eBay. This makes sense, as eBay does not need a seller to use the eBay UI to sell something, as the UI is not what makes money for eBay. As a result, around 50% of all items for sale on eBay come through 3rd party applications built on top of the eBay trading APIs. The vast majority of these (especially the popular ones) are desktop applications. Give people a choice, and a lot of people choose desktop applications.&lt;br /&gt;&lt;br /&gt;For another interesting example, just look at Twitter. This is a company that came into an existence after web APIs had become the norm. So Twitter has provided a comprehensive set of APIs since early in its existence. Further, they have not pursued an advertising model that would marry their web based UI to any revenue streams. So they have kept their APIs in sync with their features. For example, they recently added list and retweet features to their site, and added them to the APIs at the same time. As a result, there are a huge number of desktop applications for accessing Twitter. Indeed, Twitter says that 80% of their traffic is from APIs -- either desktop or mobile applications. For most Twitter users, there have always been feature-equivalent desktop alternatives to Twitter's web based UI, so many users chose desktop applications over the web.&lt;br /&gt;&lt;br /&gt;Finally, let's look at one more example: existing desktop apps. There has been an incredible amount of money spent on creating web applications that provide similar functionality to traditional desktop applications: email, word processing, etc. Heck, Google has spent a lot in this space just by itself. These are useful applications, but it is rare for people to choose these apps over their desktop equivalents. In most cases these apps try to go the disruptive route, i.e. don't try to be as good, but good enough and cheaper. They have had little success so far. Of course, inertia is a valid argument here, too. The one case where there has been success is GMail. In my opinion its success is not because people like it's web UI over a desktop UI, or even that the web UI is "good enough" and cheaper. No, it's success is because it has offered innovative features over other web and desktop based alternatives: fast search, stars/labels, threaded conversations, etc. Even give all of that, many people still choose to use desktop clients to access their GMail (I'm definitely not one of them.) Anyways, once again it's the features, not the UI.&lt;br /&gt;&lt;br /&gt;I am not going to sit here and claim that desktop wins over web all the time. I'm not arrogant or stupid enough to make such claims. However, be wary of claims that web apps win over desktop apps. One could argue that with the preponderance of APIs (especially spurned on by mobile apps) and the popping of the advertising based web 2.0 bubble, that the future will hold even more opportunities for desktop alternatives to web applications. Maybe web applications have jumped the shark. So don't put up with web developers who insist that web applications have won (especially if they try to extrapolate this flawed argument to the mobile world). They can go on and on about technology, standards, interoperability, etc. Just remind them that it's the users who matter, and when given a choice, the users do not always choose web applications. Time to polish off your MFC and Cocoa skills!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7636424102744343912?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7636424102744343912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7636424102744343912' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7636424102744343912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7636424102744343912'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2009/11/web-developers-are-stupid-and-arrogant.html' title='Web Developers Are Stupid and Arrogant'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1441975679856658846</id><published>2009-11-21T22:30:00.000-08:00</published><updated>2009-11-21T22:30:34.328-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='jvm'/><title type='text'>Passing on the Duby</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.nparikh.org/pub/images/giant-doobie.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="386" src="http://www.nparikh.org/pub/images/giant-doobie.jpg" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Last week I had &lt;a href="http://www.bettween.com/headius/michaelg/conversation/1302403"&gt;a fun conversation with Charles Nutter&lt;/a&gt;. It was about "java.next" and in particular, Charlie's requirements for a true replacement for Java. He &lt;a href="http://twitter.com/headius/status/5671504509"&gt;stated his requirements&lt;/a&gt; slightly before that conversation, so let me recap:&lt;br /&gt;&lt;br /&gt;1.) Pluggable compiler&lt;br /&gt;2.) No runtime library&lt;br /&gt;3.) Statically typed, but with inference&lt;br /&gt;4.) Clean syntax&lt;br /&gt;5.) Closures&lt;br /&gt;&lt;br /&gt;I love this list. It is a short list, but just imagine if Java 7 was even close to this. Anyways, while I like the list as a whole, I strongly objected to #2 -- No runtime library. Now, I can certainly understand Charlie's objection to a runtime library. It is a lot of baggage to drag around. All of the JVM langs have this issue. JRuby for example, has an 8 MB jar. Groovy has a 4 MB jar. Clojure has two jars totaling 4.5 MB. Scala is also around 4 MB. These become a real issue if you want to use any of these languages for something like Android development. &lt;a href="http://www.ibm.com/developerworks/opensource/library/os-eclipse-scala/index.html"&gt;I've written about this issue&lt;/a&gt; as well.&lt;br /&gt;&lt;br /&gt;However, there is a major problem with this requirement. The building blocks of any programming language includes primitives and built-in types. Those built-in types are part of the runtime library of the language. So if your JVM based language cannot have a runtime library, then you will have to make do with primitives and Java's built-in types. Why is this so bad? Java's types (mostly) make sense in the context of Java, its design principles and syntax. I don't think they would make sense in the java.next hypothetical language described above. The easiest example of this are collection classes. Don't you want a list that can make use of closures (#5 requirement above) for things like map, reduce, filter, etc. ? Similarly, if you static typing, you probably have generics, and wouldn't you like some of your collections to be covariant? You can go even further and start talking immutability and persistent data structures, and all of the benefits these things bring to concurrent programming. This is just collections (though obviously collections are quite fundamental to any language,) but similar arguments apply to things like IO, threading, XML processing, even graphics (I'd like my buttons to work with closures for event handling thank you very much.)&lt;br /&gt;&lt;br /&gt;One argument against this is that you can just include the runtime library of your choice. Pick your own list, hash map, thread pool, and file handler implementations. This is what I'd like to call the C++ solution -- only worse. At least in C++ you can generally count on the STL being available. The thing that is so bad about this is that it really limits the higher-order libraries that can be built. Java, Ruby, and Python all have a plethora of higher order libraries that have been built and widely used. These libraries make extensive use of the built-in types of those languages. Imagine building ORMs like Hibernate or ActiveRecord if you did not have built-in types (especially collection classes) that were consistent with the language. You could not do it. If all you could rely on was the Java built-in types, then at best your libraries would have a very Java-ish feel to them, and doesn't that defeat the purpose?&lt;br /&gt;&lt;br /&gt;Charlie gave an alternative to this -- leverage the compiler plugins. Now it is certainly true that with a pluggable compiler, you could do this like add a map method to the java.util.List interface, and all of the JDK classes that implement this interface. It can be done. However, if you are going to build higher order libraries on top of this language, then you need to be able to count on these enhancements being present. In other words, the compiler plugin needs to be a required part of the compiler. Fine. Now what is it that we were trying to avoid? Extra runtime baggage, right? Well if you have a compiler that is going to enhance a large number of the classes in the JDK, hello baggage. Maybe it won't be as much baggage as 4 MB runtime library, but it might not be a lot less either. Also, it raises the potential problem of interoperability with existing Java libraries. If I import a Hibernate jar that gives me a java.util.List, that list is not going to be enhanced by my compiler -- because it wasn't compiled with my javac.next, it was compiled with javac.old. What's going to happen here?&lt;br /&gt;&lt;br /&gt;Now there is an obvious happy way to deal with the runtime library question: rt.jar. If java.next was Java, and the super revamped collections, IO, threading, etc. classes were part of the JDK, then there is no need for a runtime library since now it has been included with the JDK. However, given the incredibly uncertain state of Java 7, not to mention the long term prospects of Java, does this seem remotely possible to anyone? I don't think so. I think the heir apparent to Java cannot be Java, and I think because of that, it's gotta have a runtime library of its own.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1441975679856658846?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1441975679856658846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1441975679856658846' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1441975679856658846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1441975679856658846'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2009/11/passing-on-duby.html' title='Passing on the Duby'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-4745333253738328253</id><published>2009-11-16T22:22:00.000-08:00</published><updated>2009-11-16T22:22:32.910-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobile web'/><category scheme='http://www.blogger.com/atom/ns#' term='geolocation'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Cross Browser Geolocation</title><content type='html'>You might have heard that &lt;a href="http://www.techcrunch.com/2009/11/11/joe-hewitt-developer-of-facebooks-massively-popular-iphone-app-quits-the-project/"&gt;Joe Hewitt has given Apple the finger&lt;/a&gt;, and is moving on (or more accurately moving back to) mobile web development. You can do a lot on mobile web browsers -- more than you can do on desktop browsers. This can seem counterintuitive at first. However, flavors of WebKit have a huge share of mobile web use, and it supports a lot of features that you can't count on in the IE-dominated world of desktop browsers. One of those coveted features is geolocation. However, geolocation support is far from standardized even among the high end WebKit based browsers.&lt;br /&gt;&lt;br /&gt;Geolocation on Mobile Safari is nice, or more accurately it is "standardized." It follows the W3C standard. All you have to do is access the navigator.geolocation object. Here is a super simple example:&lt;br /&gt;&lt;pre class="brush:js" name="code"&gt;var gps = navigator.geolocation;&lt;br /&gt;    if (gps){&lt;br /&gt;        gps.getCurrentPosition(successHandler);&lt;br /&gt;    } &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function successHandler(position){&lt;br /&gt;  var lat = position.coords.latitude;&lt;br /&gt;  var long = position.coords.longitude;&lt;br /&gt;  doSomethingUseful(lat, long);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Pretty easy, huh? This will work on Mobile Safari running on iPhone OS 3+. As mentioned, it is standard. It will also work on newer versions of Firefox, which presumably includes Mobile Firefox, a.k.a. &lt;a href="https://wiki.mozilla.org/Fennec"&gt;Fennec&lt;/a&gt;. However, that is the limit of the portability of this code. It will not work in Android's browser.&lt;br /&gt;Android's flavor of WebKit, does not support the standard. However, it does support geolocation via Google Gears. That's right, instead of supporting the open standard, it implements the same feature using a proprietary technology. Shocking, I know. So if you are going to run JS that should access geolocation on both the iPhone and one of the zillion Android phones out there, you will need to include the gears_init.js bootstrap file. Then you can re-write the above like this:&lt;br /&gt;&lt;pre class="brush:js" name="code"&gt;function load(){&lt;br /&gt;    var gps = navigator.geolocation;&lt;br /&gt;    if (gps){&lt;br /&gt;        gps.getCurrentPosition(successHandler);&lt;br /&gt;    } else {&lt;br /&gt;        if (window.google &amp;amp;&amp;amp; google.gears){&lt;br /&gt;            gps = google.gears.factory.create('beta.geolocation');&lt;br /&gt;            gps.getCurrentPosition(function (position){&lt;br /&gt;               successHandler({coords : position});&lt;br /&gt;            }) ;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function successHandler(position){&lt;br /&gt;  var lat = position.coords.latitude;&lt;br /&gt;  var long = position.coords.longitude;&lt;br /&gt;  doSomethingUseful(lat, long);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So this is pretty close to the standard, but not quite. The Gears variant also supports the getCurrentPosition API. However, the object that it passes to the success function is different. It is a flatter structure. So in the above example, we wrap it inside another object so that we can reuse the same handler.&lt;br /&gt;I haven't tried the webOS browser, yet or the Nokia WebKit variant yet. Here's hoping they are close to the standard used by Safari.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-4745333253738328253?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/4745333253738328253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=4745333253738328253' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4745333253738328253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/4745333253738328253'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2009/11/cross-browser-geolocation.html' title='Cross Browser Geolocation'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-7573175256535273851</id><published>2009-11-10T17:04:00.000-08:00</published><updated>2009-11-10T17:05:52.766-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='javaone'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>Clojures Primes Shootout</title><content type='html'>Back in May, I was working on my &lt;a href="http://fupeg.blogspot.com/2009/06/javaone-talk-performance-comparisons-of.html"&gt;JavaOne talk on JVM language performance&lt;/a&gt;. The first comparison was a &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;prime number sieve&lt;/a&gt;. If you look back at the slides, you might notice that I did not include a Clojure implementation. There were a couple of reasons for this. First, I was dumb. Not only dumb, but especially dumb when it came to Clojure. I had recently learned it -- mostly on an airplane to Israel earlier that month. Second, realizing that I was dumb, I was at least smart enough to reach out to the Clojure community for help. I got some great help on the other algorithms, but the prime sieve was unsatisfactory. The implementations I got were just too different from the algorithms used for the other languages, that it did not seem like a good comparison. I have been meaning to go back and come up with a satisfactory implementation. And before you ask, I know about &lt;a href="http://clj-me.cgrand.net/index.php?s=Primes"&gt;this blazingly fast one&lt;/a&gt;:&lt;br /&gt;&lt;pre name="code" class="brush:clj"&gt;(defn lazy-primes []&lt;br /&gt;  (letfn [(enqueue [sieve n step]&lt;br /&gt;            (let [m (+ n step)]&lt;br /&gt;              (if (sieve m)&lt;br /&gt;                (recur sieve m step)&lt;br /&gt;                (assoc sieve m step))))&lt;br /&gt;          (next-sieve [sieve candidate]&lt;br /&gt;            (if-let [step (sieve candidate)]&lt;br /&gt;              (-&gt; sieve&lt;br /&gt;                (dissoc candidate)&lt;br /&gt;                (enqueue candidate step))&lt;br /&gt;              (enqueue sieve candidate (+ candidate candidate))))&lt;br /&gt;          (next-primes [sieve candidate]&lt;br /&gt;            (if (sieve candidate)&lt;br /&gt;              (recur (next-sieve sieve candidate) (+ candidate 2))&lt;br /&gt;              (cons candidate&lt;br /&gt;                (lazy-seq (next-primes (next-sieve sieve candidate)&lt;br /&gt;                            (+ candidate 2))))))]&lt;br /&gt;    (cons 2 (lazy-seq (next-primes {} 3)))))&lt;br /&gt;&lt;/pre&gt;and &lt;a href="http://paste.lisp.org/display/69952"&gt;this one that is very close to what I wanted&lt;/a&gt;:&lt;br /&gt;&lt;pre name="code" class="brush:clj"&gt;(defn sieve [n]&lt;br /&gt;  (let [n (int n)]&lt;br /&gt;    "Returns a list of all primes from 2 to n"&lt;br /&gt;    (let [root (int (Math/round (Math/floor (Math/sqrt n))))]&lt;br /&gt;      (loop [i (int 3)&lt;br /&gt;             a (int-array n)&lt;br /&gt;             result (list 2)]&lt;br /&gt;        (if (&gt;= i n)&lt;br /&gt;          (reverse result)&lt;br /&gt;          (recur (+ i (int 2))&lt;br /&gt;                 (if (&amp;lt; i root)&lt;br /&gt;                   (loop [arr a&lt;br /&gt;                          inc (+ i i)&lt;br /&gt;                          j (* i i)]&lt;br /&gt;                     (if (&gt;= j n)&lt;br /&gt;                       arr&lt;br /&gt;                       (recur (do (aset arr j (int 1)) arr)&lt;br /&gt;                              inc&lt;br /&gt;                              (+ j inc))))&lt;br /&gt;                   a)&lt;br /&gt;                 (if (zero? (aget a i))&lt;br /&gt;                   (conj result i)&lt;br /&gt;                   result)))))))&lt;br /&gt;&lt;/pre&gt;and of course &lt;a href="http://github.com/richhickey/clojure-contrib/blob/dd497fb5154f8a26f9a09af7361981cb196bdf67/src/clojure/contrib/lazy_seqs.clj"&gt;the one from contrib&lt;/a&gt;: &lt;br /&gt;&lt;pre name="code" class="brush:clj"&gt;(defvar primes&lt;br /&gt;  (concat &lt;br /&gt;   [2 3 5 7]&lt;br /&gt;   (lazy-seq&lt;br /&gt;    (let [primes-from&lt;br /&gt;   (fn primes-from [n [f &amp; r]]&lt;br /&gt;     (if (some #(zero? (rem n %))&lt;br /&gt;        (take-while #(&amp;lt;= (* % %) n) primes))&lt;br /&gt;       (recur (+ n f) r)&lt;br /&gt;       (lazy-seq (cons n (primes-from (+ n f) r)))))&lt;br /&gt;   wheel (cycle [2 4 2 4 6 2 6 4 2 4 6 6 2 6  4  2&lt;br /&gt;   6 4 6 8 4 2 4 2 4 8 6 4 6 2  4  6&lt;br /&gt;   2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10])]&lt;br /&gt;      (primes-from 11 wheel))))&lt;br /&gt;  "Lazy sequence of all the prime numbers.")&lt;br /&gt;&lt;/pre&gt;Instead I came up with my own bad one...&lt;br /&gt;&lt;pre name="code" class="brush:clj"&gt;(defn primes [max-num](&lt;br /&gt;  loop [numbers (range 2 max-num) primes [] p 2]&lt;br /&gt;    (if (= (count numbers) 1)&lt;br /&gt;      (conj primes (first numbers))&lt;br /&gt;      (recur (filter #(not= (mod % p) 0) numbers) (conj primes p) (first (rest numbers))))))&lt;br /&gt;&lt;/pre&gt;Why is this so bad? Well it is horribly inefficient. It creates a list of integers up to the max-num that is the only input to the function. It then loops, each time removing all multiples of each prime -- just like a sieve is supposed to. However, most sieves take a prime p and remove 2p, 3p, 4p, etc. (often optimized to 3p, 5p, 7p, since all the even numbers are removed at the beginning.) This does the same thing, but it uses a filter to do it. So it goes through each member of the list to check if it is divisible by p. So it does way too many calculations. Next, it is constantly generating a new list of numbers to pass back into the loop. Maybe Clojure does some cleverness to make this not as memory inefficient as it sounds, but I don't think so. &lt;br /&gt;So what is it that I did not like about the other many examples out there or suggested by the community? Most of them used a lazy sequence. That's great and very efficient. However, it's not a concept that is easy to implement in other, less functional languages (Go Clojure!) On the other hand, the Rich Hickey example is much closer to what I wanted to do. However, it uses Java arrays. There is no duplication of the list and the non-primes are eliminated efficiently. Using Java arrays just seems non-idiomatic to say the least. The other examples did for JavaOne all used variable length lists instead of arrays.&lt;br /&gt;Anyways, I am satisfied to at least have a seemingly equivalent, idiomatic Clojure implementation. I looked at optimizing it through using type hints. I actually had to use a lot  of type hints (4) to get a 10% decrease in speed. Anyways, not that this is out here, others will improve it, as that shouldn't be too hard to do!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-7573175256535273851?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/7573175256535273851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=7573175256535273851' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7573175256535273851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/7573175256535273851'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2009/11/clojures-primes-shootout.html' title='Clojures Primes Shootout'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-1345243523016672431</id><published>2009-11-03T21:34:00.000-08:00</published><updated>2009-11-03T21:34:23.439-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Persistent Data Structures</title><content type='html'>A few weeks ago I blogged about &lt;a href="http://fupeg.blogspot.com/2009/10/concurrency-patterns-java-scala-and.html"&gt;concurrency patterns and their relative tradeoffs&lt;/a&gt;. There were some really poor comments from Clojure fans -- the kind of abusive language and trolling that reminded me of Slashdot in its heyday. In fact, for the first time in a very long time, I had to actually delete comments... A lot of people get confused by the fact that I used Clojure as a representative for software transactional memory, and thought that I was talking about concurrency in Clojure. Anyways, I was flattered that Stuart Halloway commented on my blog. He said I needed to watch &lt;a href="http://www.blogger.com/"&gt;&lt;span id="goog_1257210959999"&gt;&lt;/span&gt;Rich Hickey's talk on persistent data structures&lt;span id="goog_1257210960000"&gt;&lt;/span&gt;&lt;/a&gt;. So I did. I wanted to embed it on my blog, but it didn't look like InfoQ supports that. So I stole his slides instead:&lt;br /&gt;&lt;div id="__ss_2407465" style="text-align: left; width: 425px;"&gt;&lt;a href="http://www.slideshare.net/michael.galpin/persistent-data-structures-and-managed-references" style="display: block; font: 14px Helvetica,Arial,Sans-serif; margin: 12px 0 3px 0; text-decoration: underline;" title="Persistent Data Structures And Managed References"&gt;Persistent Data Structures And Managed References&lt;/a&gt;&lt;object height="355" style="margin: 0px;" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=richhickeypersistentdatastructuresandmanagedreferences-091102191105-phpapp02&amp;stripped_title=persistent-data-structures-and-managed-references" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=richhickeypersistentdatastructuresandmanagedreferences-091102191105-phpapp02&amp;stripped_title=persistent-data-structures-and-managed-references" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="font-family: tahoma,arial; font-size: 11px; height: 26px; padding-top: 2px;"&gt;View more &lt;a href="http://www.slideshare.net/" style="text-decoration: underline;"&gt;documents&lt;/a&gt; from &lt;a href="http://www.slideshare.net/michael.galpin" style="text-decoration: underline;"&gt;michael.galpin&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;A little after all of this, I learned that persistent data structures were coming to Scala. So a lot of folks seem to think that these are pretty important. So why is that exactly? It was time to do some homework...&lt;br /&gt;&lt;br /&gt;You can read some &lt;a href="http://en.wikipedia.org/wiki/Persistent_data_structure"&gt;basic info on Wikipedia&lt;/a&gt;. You can go to the original source, &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.20.4164"&gt;Phil Bagwell's paper&lt;/a&gt;. The latter is very important. What's amazing is that these are relatively new ideas, i.e. the science behind this is less than ten years old. Anyways, I would say that the important thing about persistent data structures is that they are data structures designed for versioning. You never delete or for that matter change anything in place, you simply create new versions. Thus it is always possible to "rollback" to a previous version. Now you can see how this is a key ingredient for software transactional memory.&lt;br /&gt;&lt;br /&gt;Going back to the original ideas... Bagwell's VLists are the foundation for persistent arrays and thus persistent hashtables in Clojure. These form the foundation of Clojure's Multi-Version Concurrency Control, which in turn is the basis of its STM.&lt;br /&gt;&lt;br /&gt;These are not just persistent data structures, they are a very efficient implementation of the persistent data structure concept. Each incremental version of a list shares common data with the previous version. Of course you still pay a price for getting the built-in versioning, but this is minimized to some degree.&lt;br /&gt;&lt;br /&gt;Scala fans should also be interested in persistent data structures. They are coming to Scala, which is supposed to be available in beta by the end of this month. The aforementioned Bagwell did his work at EPFL -- the same EPFL that is the epicenter of Scala. Indeed, Bagwell himself has contributed to improving the implementations of VLists in Scala. With VLists in tow, Scala STM is just around the corner.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5819005-1345243523016672431?l=fupeg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fupeg.blogspot.com/feeds/1345243523016672431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5819005&amp;postID=1345243523016672431' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1345243523016672431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5819005/posts/default/1345243523016672431'/><link rel='alternate' type='text/html' href='http://fupeg.blogspot.com/2009/11/persistent-data-structures.html' title='Persistent Data Structures'/><author><name>Michael Galpin</name><uri>https://profiles.google.com/116207116265059961468</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-6K6_RCszUu0/AAAAAAAAAAI/AAAAAAAACe0/-vHobqI_yh8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5819005.post-6165567619446999109</id><published>2009-10-27T16:00:00.000-07:00</published><updated>2009-10-27T16:00:33.900-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Minimalism? Programming? Huh?</title><content type='html'>Last week, I was at the Strange Loop conference, and it was a great conference. It &lt;a href="http://fupeg.blogspot.com/2009/10/concurrency-patterns-java-scala-and.html"&gt;inspired one blog post &lt;/a&gt;that managed to piss some Clojure people off. So here is another. This time I'm going after the closing keynote, Alex Payne. Here are his slides, including detailed notes.&lt;br /&gt;&lt;div id="__ss_2338110" style="text-align: left; width: 425px;"&gt;&lt;a href="http://www.slideshare.net/al3x/strange-loop-2009-keynote-minimalism-in-computing" style="display: block; font: 14px Helvetica,Arial,Sans-serif; margin: 12px 0 3px 0; text-decoration: underline;" title="Strange Loop 2009 Keynote: Minimalism in Computing"&gt;Strange Loop 2009 Keynote: Minimalism in Computing&lt;/a&gt;&lt;object height="355" style="margin: 0px;" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=strangeloop2009-091024174029-phpapp02&amp;stripped_title=strange-loop-2009-keynote-minimalism-in-computing" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=strangeloop2009-091024174029-phpapp02&amp;stripped_title=strange-loop-2009-keynote-minimalism-in-computing" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="font-family: tahoma,arial; font-size: 11px; height: 26px; padding-top: 2px;"&gt;View more &lt;a href="http://www.slideshare.net/" style="text-decoration: underline;"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/al3x" style="text-decoration: underline;"&gt;Alex Payne&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;So where to begin... Even though I am going to harsh on this, I will give it very high marks. Why? Because it was thought provoking. If something makes you think long and hard about how and why you do your job, that is a good thing. I worry about people who do not question their assumptions on a regular basis.&lt;br /&gt;Ok, so now on to what you've been waiting for -- the harshness. I hate software engineering analogies. Well, not all, but most. I hate when people try to romanticize about what they do by making a far-fetched analogy to something more glamorous. If you're a programmer, you're not a rock star. You're not an artist. You're not a musician. You're not even a scientist. Sorry. Despite having the word "architect" in my official job title, I would add that you're not an architect either.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XmwdENwf53s/Sudxt52NKkI/AAAAAAAAAso/g4KIIxraz34/s1600-h/mugshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XmwdENwf53s/Sudxt52NKkI/AAAAAAAAAso/g4KIIxraz34/s400/mugshot.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;You're a programmer. At best, you're an engineer, and that is really stretching it at times.&amp;nbsp;So obviously if I find it ridiculous to compare programming to things like creating art or making music, it seems even more ridiculous to compare the output of programming to art or music.&lt;br /&gt;&lt;br /&gt;That being said, I enjoy programming. It is not just a job. I also take pride in my work. I like to show off my code as much as the next guy.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XmwdENwf53s/SudzEPqtqrI/AAAAAAAAAsw/Q_EtXQsIjUk/s1600-h/flasher2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XmwdENwf53s/SudzEPqtqrI/AAAAAAAAAsw/Q_EtXQsIjUk/s400/flasher2.gif" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;From this perspective, I can definitely appreciate Alex's thoughts on minimalism. Or perhaps more generally, associating some subjective qualities with programming. If an analogy to art or construction or whatever helps one express those subjective qualities, then fine. Just don't forget who you are, and maybe even try to find some pride in just that.&lt;br /&gt;&lt;br /&gt;Now I should really end this post now, on kind of a feel good note. But I won't. Instead, I want to touch on some of the *ahem* deeper thoughts that Alex's talk provoked. I was reminded of a paper I read several years ago that tried to explain two obviously overly general (and probably not politically correct) things: why Americans are good at software but not cars, while the Japanese are good at cars, but not software. I tried to find a link to this paper, and was quite sure that I had saved it in Delicious. However I could not find, and I'm convinced that Delicious lost it. Maybe it &lt;a href="http://fupeg.blogspot.com/2009/10/social-technology-fail.html"&gt;fell out of cache&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;Anyways, the crux of the argument is that Americans are good at getting something done quickly, even though the quality may be poor. So we are good innovators, but terrible craftsmen. This is a good fit for software, but obviously not cars.&lt;br /&gt;&lt;br /&gt;If you accept this idea, and it has its merits, then in a world of low quality, rapidly written code, is there any room for subjective qualities? Why should you take any pride in your work at all if its value is directly proportional to how quickly you can produce it, throw it away, and move on to something else? To some degree, doesn't the software world's affection with agile development codify these almost nihilistic ideals? Perhaps the propensity to try and compare programming to ar
