Tag Archives: Android

Meap, Meap

MEAPAfter several runs of building native mobile apps for Android and iOS, I’m again using cross-platform (hybrid) solutions for those apps that don’t need heavy native capabilities. Mobile Enterprise App Platforms (MEAPs) based on Cordova are common, and a good place to start for corp-rat work.

IBM’s MEAP is Worklight (now called the MobileFirst Platform), and I’ve been running it through the paces. The Eclipse-based Studio is a free download from the Eclipse Marketplace, the online tutorials are quick, and the documentation is complete.

MobileFirst’s frameworks and structure are well-designed, helping keep as much apps code as possible in common JavaScript/HTML5/CSS, and pushing customization to platform-specific environments and device-specific skins. It has jQuery included, and convenience support for jQuery Mobile, Dojo, and Sencha Touch. But it’s possible to use just about any JavaScript framework. It provides good client-side (WL) support classes for JavaScript as well as native Android and iOS.

Server-side adapters can also be coded in JavaScript, with good libraries and tooling. I ran into a few adapter issues, such as exceptions using default data sources with z/OS DB2 connections, and namespace errors for SOAP adapters generated from WSDL. But these were easy enough to fix, and the benefits were worth the trouble.

The suite includes libraries and server apps for app management and updates, analytics, authentication, push notifications, and other “back end” responsibilities. It takes awhile to learn how to correctly package apps and then production-deploy everything, but I got by with help from the doc and StackOverflow.

Worklight is a mature product that’s continually being improved. And with IBM’s backing and focus, it’s a good choice for all your MEAPing.

Smackdown

In today’s action, I wrote a new Google Cloud Messaging (GCM) server interface to the GCM Cloud Connection Server (CCS) via XMPP. GCM CCS offers several benefits over GCM HTTP including one of my key requirements, bidirectional messaging.

My app server didn’t yet have a XMPP interface, so I followed Google’s sample and plugged in Smack. Then the fun began. I immediately started getting exceptions (see Smackdowns below). These varied based on state and configuration, but basically the result was the same: the GCM CCS server was abruptly closing the connection during authentication. How rude; Smack was getting smacked down.

I dug in but ran into several red herrings. For example, Smack’s stream headers didn’t match Google’s doc (no tag close); Google’s doc is wrong. I debugged Smack, tried different Smack versions, tried other XMPP clients, tweaked configurations, studied XMPP protocols and SASL authentication, and updated authentication parameters and allowed IPs. Ultimately, I had a minor error in one of the authentication parms. I found it by Base64-decoding the auth value in Google’s example and comparing it to my own traces.

This would have been a quick fix if CCS had just given an authentication error message rather than just slamming the door. It must be a security thing. Oh well, on to the next adventure.

Smackdowns 

No response from the server.: 
	at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:73)
	at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:357)
	at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:221)
java.net.SocketException: Connection closed by remote host
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkWrite(Unknown Source)
	at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
	at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
	at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
	at sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
	at sun.nio.cs.StreamEncoder.flush(Unknown Source)
	at java.io.OutputStreamWriter.flush(Unknown Source)
	at java.io.BufferedWriter.flush(Unknown Source)
	at org.jivesoftware.smack.util.ObservableWriter.flush(ObservableWriter.java:48)
	at org.jivesoftware.smack.PacketWriter.writePackets(PacketWriter.java:168)
java.io.EOFException: no more data available - expected end tag  to close start tag  from 
                                      line 1, parser stopped on END_TAG seen ...... @1:344
	at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:3035)
	at org.xmlpull.mxp1.MXParser.more(MXParser.java:3046)
	at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1144)
	at org.xmlpull.mxp1.MXParser.next(MXParser.java:1093)
	at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:279)

Android Studio

I’ve been waiting months for a “ready for prime time” version of Android Studio. Its move from “Preview” to “Beta” (version 0.8) on June 26 became my signal to dive in deep and use it for real work. After all “beta” in Google terms usually means a level of quality some products don’t achieve with years of “GA” releases.

Android Studio inherits many of its benefits from IntelliJ. I like the speed and stability, the quality of the development and rendering tools, the productivity, the rich static code analysis, and all the other benefits that come from its IntelliJ underpinnings.  I’ve bounced back and forth between Eclipse keymaps and IntelliJ defaults, but settled on the IntelliJ’s, with the cheat sheet on hand. “When in Rome,” don’tchaknow, although I haven’t yet joined the Darcula side. Even from a few days’ use, I’m sold on IntelliJ and certainly don’t miss Eclipse’s crashes and stalls.

I’m also pleased with the Gradle-based build system and AAR support. After fighting with Maven plugin bugs, apklib hacks, and other Eclipse-Maven clashes, it’s refreshing to have a build system that is elegant, is backed by Google, and just works. The factoring of content across build.gradle files, manifests, etc., is clean and DRY, and the Android-specific checks guide you toward best practices.

The main downside is that there is no automatic nor incremental build as with Eclipse, so builds are slower and many errors aren’t discovered during editing. Build speed will likely improve as it exits beta (perhaps with the help of parallel builds), but the rest is just the IntelliJ way.

Still, I’m happy with both IntelliJ and the Android Studio so far. Now if I could only switch from MyEclipse to IntelliJ for server-side code…

Time’s Up

I recently needed to add an inactivity timer to a pair of new apps. If the user was logged in but inactive past a configurable period, the app should display an error when resumed and return to the login screen. It must be non-intrusive and not interrupt any foreground apps. It could not require a background service.

For Android, this fit well into the standard activity architecture. In particular, well-behaved activities should normally remain quiet when paused and should finish themselves rather than be killed by some other activity.  So I created the following simple utility class to enable this.  The primary hooks are:

  • initialize – Called when the first (main) activity starts.
  • startMonitoring – Called when the user logs in.
  • monitor – Called from each activity’s onResume.  I added it to my common fragment superclass.

It also has an optional requestExit to request an immediate exit based on some other criteria.

The deus ex machina is the simple activity.finish().  This ripples through all active activities so that they politely exit whenever the sShouldExitNow flag is set.

public class UserActivityMonitor {
 
    private static long sUserTimeoutMillisecs = 5 * 60 * 1000;	// Default to 5 minutes
    private static boolean sIsMonitoring = false;
    private static boolean sShouldExitNow = false;
    private static long sLastActionMillisecs = 0;
 
    /**
     * Initialize monitoring. Called at app startup.
     */
    public static void initialize(long timeoutMillisecs) {
        sUserTimeoutMillisecs = timeoutMillisecs;
        sIsMonitoring = false;
        sShouldExitNow = false;
        sLastActionMillisecs = 0;
    }
 
    /**
     * Start monitoring user activity for idle timeout.
     */
    public static void startMonitoring() {
        sIsMonitoring = true;
        sLastActionMillisecs = System.currentTimeMillis();
    }
 
    /**
     * The given activity is at the foreground.
     * Record the user's activity and, if necessary, handle an exit or timeout request.
     * If timed out, start the postTimeoutActivity (if provided) on a new task.
     */
    public static void monitor(Activity currentActivity, Intent postTimeoutActivity) {
        if (sShouldExitNow) {
            // Calls here will ripple through and finish all activities
            currentActivity.finish();
        } else {
            if (sIsMonitoring) {
                checkForIdleTimeout(currentActivity, postTimeoutActivity);
            }
        }
        sLastActionMillisecs = System.currentTimeMillis();
    }
 
    /**
     * Request to exit the app by triggering all activities to finish.
     */
    public static void requestExit() {
        sShouldExitNow = true;
    }
 
    /**
     * Check for an inactivity timeout.
     * If we have timed out, display a message, finish the activity,
     * and set the "should exit now" flag so that other activities quit.
     * If timed out, start the postTimeoutIntent (if provided) on a new task.
     */
    private static void checkForIdleTimeout(final Activity activity,
                                            final Intent postTimeoutIntent) {
        if (User.getCurrentUser().isLoggedIn() && sLastActionMillisecs > 0) {
            long idleMillisecs = System.currentTimeMillis() - sLastActionMillisecs;
            if (idleMillisecs > sUserTimeoutMillisecs) {
                // The first time we detect a timeout, display a popup message
                UiUtils.showError(activity.getString(R.string.msg_timeout),
                        activity.getString(R.string.msg_timeout_title), activity, 
                         new IErrorDisplayListener() {
                            @Override
                            public void onResponse(int buttonClicked) {
                                sShouldExitNow = true;
                                activity.finish();
                                if (postTimeoutIntent != null) {
                                    postTimeoutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                                            Intent.FLAG_ACTIVITY_CLEAR_TASK);
                                    activity.startActivity(postTimeoutIntent);
                                }
                            }
                        });
            }
        }
    }
}

Such Little Things

After many Android app versions with perfectly-good icons, it came time to replace them: new launcher icons, new store listing graphic, new action bar icons, and in some cases, removing the icon from the action bar altogether.

For the latter, I preferred an easily-customized manifest entry:

android:icon=”@color/transparent”

This worked nicely for local and ad-hoc installs. So I was surprised when publishing to the Google Play store failed with the obscure yet common error:

Your APK cannot be analyzed using ‘aapt dump badging’.  Error output:

Failed to run aapt dump badging: Error getting ‘android:icon’ attribute: attribute is not a string value

You wouldn’t know it from the message nor from any online suggestions, but that @color/transparent trick was the root cause. So instead I created a 1×1 transparent PNG (ic_empty.png) and used it instead:

android:icon=”@drawable/ic_empty”

BTW, when it’s “icon update” time, I’ve found the quickest way to get scaled icons is to create the 512×512 web version, and point the New Android Application wizard at it.  It’ll create the mdpi, hdpi, xdpi, and xxhdpi sizes for you.

22.6.2, Maybe?

The recent 22.6 Android Developer Tools (ADT) update broke quite a few things: AVD creation and editing, ProGuard, performance, etc.  Rather than revert to 22.3 like many folks, I decided to muddle through with some work-arounds and hold out for the fixes in 22.6.1.

Well, 22.6.1 has arrived and at least fixed the AVD issues, but ProGuard still fails with:

Error: Unable to access jarfile ..\lib\proguard.jar

Fortunately, working around that bug is easy: simply edit proguard.bat and provide an absolute path to the JAR.

Back Up

Enabling Up (ancestral) navigation in Android apps is straightforward for the typical case: just specify parent activities in the manifest and send setDisplayHomeAsUpEnabled(true). But non-typical cases (like dynamic parents) require extra steps.

Today I implemented some non-typical cases and experimented with overriding action bar callbacks, tweaking the back stack, etc. But in most cases I simply wanted up navigation to behave like back navigation whenever there was no fixed parent defined. For that, I developed a simple recipe:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
	switch (item.getItemId()) {
		case android.R.id.home:
			if (NavUtils.getParentActivityName(getActivity()) != null) {
				NavUtils.navigateUpFromSameTask(getActivity());
			} else {
				getActivity().onBackPressed();
			}
			return true;
		default:
			return super.onOptionsItemSelected(item);
	}
}

Open for Repairs

Although Android Libraries are the recommend way to package and use larger components, there’s no clean way to handle them in a Maven-based Eclipse or Jenkins environment. Sure, JARs are easy enough, but not the co-requisite resource files. Checking these into source control is just wrong, and full Maven support for these libs in incomplete, even with m2e, m2e-android, and android-maven-plugin in place.

Apklibs provide a decent stopgap, so I settled on that approach: loading the zips (ahem, apklibs) to Nexus and creating scripts to link things up during build. It requires one manual step in Eclipse, but no biggie. Yet there are greener pastures ahead…

The upcoming new Android Build System addresses this problem with AARs. Of course, it goes much further, ditching Maven for Gradle, ADT for Android Studio, Eclipse for IntelliJ, and XML for Groovy. I like new things, but while we’re waiting on the new house, I wish Google would finish fixing the plumbing in the current one.

Droid Units

JUnit testing of model and service classes under Android/Dalvik is straightforward, but when it comes to testing UIs (activities and fragments), the basic support is just too low-level. Fortunately, Robotium (think Selenium for droids) provides a most-excellent adjunct for this.

Yet Robotium should be used with care to create maintainable tests that aren’t brittle. To that end, I’ve developed some UI automation practices:

  • Write true unit test classes that cover only a single activity or fragment. Of course, many UI actions will take you to the next activity (and you should assert that), but leave multi-activity testing for separate integration tests.
  • Stub back-end behaviors using standard mock and dependency injection techniques. For my current app, I kept it simple/lightweight and wrote my own code, but I’ve also used Mockito (with dexmaker) and Dagger (with javax.inject); these are nice Android-compatible frameworks.
  • Rather than repeating the same raw Robotium calls directly from your tests, wrap them in descriptive helper methods like enterUserID(String id), enterPassword(String password), clickLoginButton(), etc. This DRY approach makes for more readable tests and simplifies updates when your UI changes.
  • Since you probably use common superclasses for your activities and fragments, also create parent test case classes to factor common testing behaviors. See below for snippets from one of mine.

I haven’t found a good tool for measuring code coverage for apps (Emma under Android is flakely), so I’d love to hear your recommendations.

public abstract class BaseActivityTest<T extends Activity> 
                             extends ActivityInstrumentationTestCase2<T> {
 
	protected Solo mSolo;	
 
	public BaseActivityTest(Class<T> activityClass) {
		super(activityClass);
	}
 
	protected void setUp() throws Exception {
		// Reset your DI container and common mocks here...		
		mSolo = new Solo(getInstrumentation(), getActivity());
	}
 
	protected void tearDown() throws Exception {
		mSolo.finishOpenedActivities();
	}
 
	public void testLayoutPortrait() {
		mSolo.setActivityOrientation(Solo.PORTRAIT);
		verifyViews(getLayoutViews());		
		verifyViews(getPortraitViews());
	}
 
	public void testLayoutLandscape() {
		mSolo.setActivityOrientation(Solo.LANDSCAPE);
		verifyViews(getLayoutViews());		
		verifyViews(getLandscapeViews());		
	}	
 
	// ...
}

Playgroups

There are several options for over-the-air distribution of in-progress apps to internal testers. For Android, you can start simple with a link to the APK on a web site, but this misses the benefits of the Google Play store: automatic updates, consistent store listings, crash reports, support links, etc. Fortunately, we now have Google’s new Private Channel Distribution: a protected area for distributing apps as they develop and get ready for the larger “real world” of public distribution.

The service is easy to use, but does require a few setup steps:

  1. You must be a Google Apps user with administrator access. If you don’t already have it, sign up and pay the man.
  2. You must be registered as a Google Play developer with an account belonging to your Google Apps domain. Here again, sign up and pay the man.
  3. Sign into your Google Apps Console and enable the Google Play Private Channel. The process changed again recently with the new admin console, but you can find the latest instructions here.
  4. Log in to the Google Play Developer Console and create, configure, and publish your app. Check the box under Pricing & Distribution – Restrict Distribution.

To install, add your Google Apps account to your phone (for example, Play Store – menu – settings –  Account – Add Account – OK – Existing).  You should then see the private apps for your Google Apps domain under Apps – Categories (this, too, has changed recently).

You can use the Recent changes section of the app listing to describe updates to testers, and include a link to a video walk-through. Perhaps soon WebEx’s Android app will provide mobile screen sharing for live demos; until then Android Screencast works well with WebEx PC desktop sharing.  It’s not as nice as Reflector, but it is free and lightweight.

Worth the Weight

With many Android apps, there often seems to be little correlation between the size of the package and the value it provides. Multi-megabyte apps that do almost nothing leave me wondering, “what’s in there?”

Unpacking with dex2jar and JD-GUI often provides answers, and frequently it just means the developer forgot to enable Proguard when building. An overabundance of ill-compressed drawables are another common source. But beyond these, the habits of server-side re-use (freely expanding POMs and dropping in FOSS JARs) are a key source of bloat.

I try to be stingy when it comes to Android app libs, often taking a tougher route to avoid bringing in large JARs that might otherwise be useful. Such was the case recently when I needed to do a multi-part post to a REST web service that consumed a mix of binary image data and JSON. Multipart HTTP is conceptually simple, but the markup is obscure enough to make generating it directly from a business app just wrong.

Fortunately, though, Apache HttpMime is just 26K, and makes the process simple. For example:

MultipartEntity entity = new MultipartEntity();
entity.addPart("request", new StringBody(request));
entity.addPart("image", new ByteArrayBody(image, "image/jpeg", filename));
...
mpEntity.writeTo(connection.getOutputStream());

To avoid duplicate class errors at Proguard time, exclude the dependent httpcore in your pom.xml, like so:

	<dependency>
		<groupId>org.apache.httpcomponents</groupId>
		<artifactId>httpmime</artifactId>
		<version>${httpmime.version}</version>
		<exclusions>
			<exclusion>
				<groupId>org.apache.httpcomponents</groupId>
				<artifactId>httpcore</artifactId>
			</exclusion>
		</exclusions>			
	</dependency>

I don’t always add JARs to Android apps, but when I do, I prefer light ones.

Gingerbread

Android 2.3 (a.k.a., Gingerbread) and the 9.1 APIs were released this week with an array of new features for gaming, multimedia, communication and new platforms.  Many of the enhancements are quantitative and behind-the-scenes improvements that I won’t really notice until I have it running on my phone or do some further development.  But there were enough usability improvements to interest me in giving it a spin.  So I downloaded the SDK and previewed it in my Eclipse AVD.

Not surprisingly, upgrading my Eclipse development environment also required an ADT plug-in upgrade.  But this is a familiar and easy process where the waiting is the hardest part.  A few downloads and restarts later, I had 2.3 running in my virtual device.

I instantly noticed the subtle color and contrast differences which, apart from graininess in some areas, make things more consistent and readable.  It’s become standard MO that each Android release changes the look and feel enough that you can typically identify the version at a glance.  I really like the text selection improvements, as I had otherwise nearly given up on accurate copy/paste.  The on-screen keyboard looks and behaves differently (apart from having to turn off the default Japanese IME settings), but it’s hard to get a true feel for the changes in an emulator.

For us Task Manager / pstat junkies, access to Manage Applications – Running is now quicker than a Windows Ctrl+Alt+Delete.  The release notes boast of improvements to the battery use monitor (formerly Settings – About Phone – Battery use), but I was unable to judge this on the emulator.

I didn’t / couldn’t try some of the platform enhancements like native support for AAC (new life for my abandoned iTunes downloads?), NFC tags, and SIP calls.  Those will wait until it’s on my phone.

But thus far it looks like Gingerbread is a nice addition to the Android dessert menu, and I’ll look forward to the Droid port and Verizon pushing it out (or, if I get impatient, rooting and loading it myself).  I’d be interested in your impressions of it, or even your predictions for the J release name: jello or jalebi, anyone?

App Inventor

There are some things I try just for the sheer novelty.  As a fan of both Android and visual programming (when done right), I couldn’t resist giving Google’s App Inventor a try.

I confess that I don’t quite understand the “market” for App Inventor; after all, the “regular” Android development environment (the Eclipse ADT plug-in atop the Android SDK) is really nice.  I’m not sure there’s a need to oversimplify and hide things, but perhaps there are a lot non-programmers out there who want to develop Android apps.  Or programmers who don’t like Java.  Or Oraclers who don’t like Harmony.  At any rate, while none of my kids have their own Android smart phones, I suppose it could be a nice learning environment for any youngsters wanting to start with “building blocks” instead of code.

Perhaps the only challenge to Android development setup is getting the ADB USB driver working (in my case, under Windows 7 64-bit): it requires some manual work-arounds.  Since App Inventor uses the same drivers, this might entangle some; for me, that was a price I had already paid back when I installed the Android SDK.  I suspect Google will soon get Microsoft’s blessing to make the Windows automatic driver install work, to benefit both tools.

“Developing” with a web page and a small Java app (the Java-web-started Blocks Editor) feels a bit claustrophobic, but I was pleasantly surprised at how functional this “IDE” is.  Unlike the Eclipse ADT, the App Inventor web tool doesn’t provide virtual devices (AVDs): everything goes directly to my phone as I work, courtesy of the JNLP.  This is smooth and interesting, but was a nuisance when I got a phone call while working.

Still, the Scratch-inspired Blocks Editor is an interesting paradigm, the shapes are really cool, and interlocking them is like assembling a jigsaw puzzle.  I found myself writing meaningless “programs” just to experiment and see how large a mousetrap I could create.  At some (early) point this breaks down, hits limits, or becomes unwieldy, so it’s back to “real” Android development when that happens.  It would be nice if App Inventor and the ADT were somehow integrated; that way, if you run out of visual programming “steam” (and simply must code), you wouldn’t have to start over.

App Inventor is a very nice tool for what it does, so I recommend it to anyone who wants to build a simple Android app, or just wants to dip a toe into the Android development pond.

Battling Droids

Given recent questions about my Droid phone, perhaps it’s time to post again about it.  This time, I’ll offer tips on battling two common Droid demons.

1. The condensation poltergeist. The tiniest amounts of condensation can make Droid’s touch screen act possessed.  The Ghost of Droid will scroll automatically, start apps, search for things, make phone calls, and wreck all sorts of direct-manipulation havoc.  And there’s no point in fighting it: it’s much faster than you, and when it takes over, it’s usually impossible to win the battle and override it.  A locked screen offers some protection against emailing your boss or calling Tokyo without your consent; in this case, it can only repeatedly try to draw out your unlock pattern, usually resulting in a series of “wait 30 seconds” holds.  It’s entertaining to watch, but annoying to say the least.

This weird phenom has been ascribed to viruses, chargers, and other hardware and software issues, but, in my experience, it’s always due to condensation on the touch screen.  And since it requires so little moisture, it’s hard to predict when it will happen.  It has happened to me upon walking into an indoor pool area, and inside my car after a long run.

As long as you keep your Droid at 70 degrees and 40% humidity (perhaps in the raised floor area of your personal data center), you’ll be fine.  For those of us in the real world (and who like Georgia summers), just stop using it when it happens, turn it off, be patient, and wait for it to dry out.  You can help it along by bringing it back into the air conditioned indoors or using a blow dryer on a cool setting.

2. The grim reaper ringer. That “slide to answer” control and dexterity test works great at preventing accidental unlocks and butt calls.  So great that if you try it while driving, you’re as likely to annihilate as answer.  An early Android update made it slightly easier (straight rather than curved slide), but it’s still difficult.  Most bluetooth headsets provide an alternative, but if you’re not headsetting it, it’s best to just pull over before attempting to answer, or simply miss the call and return it later.  Answering that call is not worth crashing into the ditch or oncoming traffic.

I’ve heard that the latter problem will be fixed soon in an Android (software) update, but the touch screen issues will probably have to wait for a new phone (gotta love “new every two”).  My next phone will almost certainly be an Android, but probably won’t be a Motorola Droid.

Nike++

There are plenty of good GPS running tools for the Android; my favorites are SportyPal and the new Google MyTracks.  Both measure pace, distance, and route, and display results on Google Maps.  With them, I get the benefits of a GPS running watch, but with more features and no extra cost.

But I’ve had mixed results with GPS tracking.  Sometimes I can’t get reliable signals, even in open areas with no overhead obstructions (MyTracks can revert to determining location by cell and Wifi signals, but that’s a very weak approximation).  Sometimes inaccurate map data and other things can throw distance off; that’s most noticeable when I run places where I know the exact distance of the course.  And sometimes, the truly weird happens, like the run shown at right.  The red (for “fastest”) lines depict how I left the course for a half mile sprint through fences, houses, and rough terrain at 27.3 miles per hour (then quicky returning to the track, of course).  MyTracks reported a recent 5 mile street run as 785.16 miles in just over 39 minutes (I was ready to give up at the 784 mile mark).  And tight loops on small tracks are almost never right with GPS tracking.  Obviously, such failures get in the way in trying to maintain a good read on my pace.

So I decided to go with the Nike+ Sportband.  Its accelerometer technology is not dependent on GPS signals for measurement: it’s nice and simple.  That’s helpful because I don’t always like to carry my phone with me, nor fiddle with it while running.  But I do miss the automatic mapping, especially when exploring new areas.  So when running new routes, I carry both: Nike+ for accurate pace tracking, and my GPS Droid for route tracking.  Call it Nike++.

Once the new wears off, I’ll probably settle into a “just one at a time” mode: Nike+ for running and Droid GPS for walking, hiking, and kayaking.  But, for now, it’s belt and suspenders, and that allows for some often interesting comparisons.

Droid Does

A friend and fellow Droidian asked me today what my favorite free Android apps were.  I really didn’t know where to begin because I use so many of them so regularly.  This includes, of course, the preloaded ones: music, calendar, gmail, browser, maps, navigation, talk, contacts, messaging, YouTube, Picasa, etc., etc..  But to answer the question, I thought I’d jot down a list of some of my favorite free Market downloads here:

– Scoreboard – All my sports scores, all the time.
– Pandora and Slacker – Personalized internet radio, love it.
– Google Places – Must… find… coffee.  Perfect GPS compliment to Maps and Navigation.
– Flixster Movies – What’s on and what will be on.
– Weather Channel – Faster than looking out the window.
– Google Sky Map, Clear Sky Droid – For my astronomy fixes.
– Google Goggles – Still under development, but fun to try.
– androidVNC and ConnectBot (ssh) – The remote access classics.
– Shop Savvy – Barcodes R us.
– NewsRob, wpToGo, Google Listen, Read Later – For feeds, blogs, podcasts, and news.
– KeePassDroid – The world’s most portable password safe.
– Evernote – Snap a photo or jot a note, and it’s on the web in seconds.
– “Commercial news” readers: Thomson Reuters, BBC News, USA Today, Fox News, etc.
– Toys and Games – Compass, Labyrinth, DailyStrip, Jewels, Sudoku, Solitaire, Frozen Bubble, etc., etc.
– And, of course, lots of mainly pointless apps like Run, Zombie, Run and Talking Parrot.

Of course, half the fun is searching Android Market for any app you can think of that just might be out there.  There’s a good chance it is.