Android: Making Espresso Tests Work With Runtime Permissions

The new Runtime Permissions introduced in Android Marshmallow is a great addition to the platform. However, if your app is targeting SDK version 23 and you have Espresso Tests, it could create some complications.

Likely, your current Espresso tests assume that all permissions have been granted at install time. This is fine when running your tests on devices lower than Marshmallow. However, your tests will fail when running on M devices since none of the permissions are granted by default.

One way to make this work is by granting permissions using adb.

$ adb pm grant com.example.myapp android.permission.<PERMISSION>
$ adb install -g com.example.myapp

This would work if you are running your own test infrastructure. However, if you are using an external service, you’ll likely to not have the ability to run adb commands.

To start making Espresso Tests work with any device including Marshmallow (or N), we need to make our Permissions code easy to swap.

We should make an interface for the Permissions.

public interface PermissionsModule {
    boolean isLocationGranted(Context context);
    boolean shouldShowLocationPermissionRationale(Activity activity);
    void requestLocationPermission(Activity activity, int requestCode);

In the app, we implement the PermissionsModule with the real code:

public class DefaultPermissionsModule implements PermissionsModule  {
    public boolean isLocationGranted(Context context) {
        return ActivityCompat.checkSelfPermission(context, Manifest.permission.            ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;

    public boolean shouldShowLocationPermissionRationale(Activity activity) {
        return ActivityCompat.shouldShowRequestPermissionRationale(activity, 

    public void requestLocationPermission(Activity activity, int requestCode) {
        ActivityCompat.requestPermissions(activity, new String[]{
            Manifest.permission.ACCESS_FINE_LOCATION}, requestCode);

While in the Espresso test module, we implement the PermissionsModule with its mock version.

public class MockPermissionsModule implements PermissionsModule {
    private boolean locationGranted = false;
    public boolean isLocationGranted(Context context) {
        return locationGranted;

    public boolean shouldShowLocationPermissionRationale(Activity activity) {
        return false;

    public void requestLocationPermission(Activity activity, int requestCode) {    }

    public void setLocationGranted(boolean locationGranted) {
        this.locationGranted = locationGranted;

The value that will determine if the Location Permission has been granted can be easily changed using setLocationGranted depending on what we need to test.

Before running any test, we need to set MockPermissionsModule as the Permission Module.

MockPermissionsModule permissionsModule = new MockPermissionsModule();
public void setUp() {

Inside the test, set the value for locationGranted depending on the test we need to do.

public void shouldShowLocationGrantedText() {

public void shouldShowRequestLocationButton() {

See sample code for the test here.

We would also want to test if our app works when a user grants or denies a permission. However, Espresso cannot access the System Permissions UI.

This is where UIAutomator comes in. Fortunately, we can mix UIAutomator code with Espresso. For it to work though, the minSdkVersion of our app should be at least 18.

To write tests specifically for devices that handles the Runtime Permissions, we need to annotate our tests with @SdkSuppress.

@SdkSuppress(minSdkVersion = 23)
public class PermissionsTest {

For the Permissions test, we have to use the real implementation of the PermissionsModule. With it, the System Permissions UI will be invoked and we will use UIAutomator to interact with the views.

public void grantLocationPermission() {
    App.setPermissionsModule(new DefaultPermissionsModule());
    UiObject2 btnAllow = device.wait(Until.findObject(
        By.res(INSTALLER_PACKAGE_NAME, "permission_allow_button")), 500);

        UiObject2 tvLocationPermissionGranted = 
            "tvLocationPermissionGranted")), 10000);


You can view the full code for PermissionsTests here.

With this, we can easily create a test when a user denies a permission. We’ll have to use the view id “permission_deny_button” instead to interact with the Deny button.

What is missing currently is the ability to test onRequestPermissionsResult. We cannot stub onRequestPermissionsResult in the same way we do with onActivityResult using Espresso Intents.

While Runtime Permissions is a great benefit to the user, it has added an additional complexity to us Android Developers. Espresso and UIAutomator helps us handle this complexity by allowing us to write tests making sure we handle permissions properly.

The full code for this project is available at Github along with my other Espresso samples.

Espresso: Matching Views in RecyclerView

I have been diving into Espresso at my current job at Foursquare. Our team also recently started using RecyclerView instead of ListView.

RecyclerView support is still pretty limited on Espresso through RecyclerViewActions.

Through RecyclerViewActions, you can perform actions on an item by position. However, there’s nothing built-in to perform actions on a specific view in an item.

For ListView, there’s onData  that gives you a DataInteraction object and allows you to go deeper into a list item by position.

There’s currently no equivalent for that in RecyclerView.


After trying out different solutions, I opted for a more generic solution so that it would work with any ViewMatchers.  You can see how I arrived to this solution on this commit.

RecyclerViewMatcher gets a reference to the RecyclerView and the child view based on position. Then, it determines if the view matches the child view or the view matches the target view in the child view.

public boolean matchesSafely(View view) {
    this.resources = view.getResources();
    if (childView == null) {
        RecyclerView recyclerView (RecyclerView)
        if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
            childView = recyclerView.getChildAt(position);
       else {
          return false;
    if (targetViewId == 1) {
       return view == childView;
    } else {
       View targetView = childView.findViewById(targetViewId);
       return view == targetView;
If you have an alternative solution, let me know in the comments.



Facebook Login: Lightweight Facebook Library for Android

Integrating Login With Facebook is a common feature in almost every app we develop at Green Halo Labs. More often than not, what we really need is just the Facebook user’s Access Token.

The current Facebook Android SDK has 2,942 methods (181 of those from the Bolt framework). With the current Dex Limit issue most Android developers are having, saving a few thousand methods makes a difference.

My friend Eric Butler (@codebutler) suggested that I extract only the Login part from the Facebook SDK.

The result is this library which only has 250 methods. All it does is return the Access Token after the user authorizes the app. Like the official SDK, it launches the Facebook Android app if it is installed, Otherwise, it uses a Web View.

The library is available on Maven Central and the source code can be viewed at GitHub:


Why It’s Time To Support Only Android 4.0 and Above

Part of developing on the Android platform is dealing with the dreaded “F” word which is FRAGMENTATION.

It’s what tech blogs mention when they write about Android. It’s the word that scares some developers away from the platform. It’s what Apple love to put in a pie chart in their product launches to prove that iOS is the most amazing mobile OS yet.

Personally, I’d rather see a Fragmented Android than a Fragmented Mobile OS ecosystem. It’s likely that without Android, we’d be developing apps for Sony OS, Samsung OS, HTC OS, and so on. I can’t imagine that Apple would actually let other companies build phones using iOS.

But still, Fragmentation is a pain. If it can be minimized or eliminated entirely, I’d be happier.

Until recently, I was working at Wedding Party ( as an Android Developer. The app was supporting Android version 2.3 and above.

To create consistent UI for all versions, we used the ActionBarSherlock and HoloEverywhere libraries. Animations should be carefully done since one that runs smoothly on 4.x would, more often than not, be sluggish on 2.3.

The Wedding Party app also deals with a lot of images. High-resolution images were out of the question because it uses a lot of resources & using multiple of these images in one screen would almost certainly crash on older devices.

At Google I/O back in May, Jeff Gilfelt started giving away stickers that says ‘minSdkVersion=”14”’. It was a well-received campaign among Android developers that got this conversation started.

In the same vein was Reto Meier’s talk “Android Protips: Making Apps Work Like Magic”.

What struck me the most was Meier’s advice: “Skate where the puck is going” and “Create the best possible app for every user especially those on the latest devices.”

Jeff’s minSdkVersion=14 sticker campaign and Reto Meier’s talk made me think about the Wedding Party app.

Because we were supporting older Android versions, it was holding us back. We were skating where the puck was. Before we develop new features for the app, we needed make sure first that it would work on older devices.

After Google IO, I pitched the minSdkVersion=14 idea to the Wedding Party team. There were some hesitation at first but after looking at our Android stats and the pace of our development (development of Android app was at least six months behind the IPhone), we were convinced that minSdkVersion=14 was the way to go.

Installs for the Wedding Party app is constantly growing since its release for all versions of Android. While the overall number is getting bigger, Android 2.x’s slice of the pie is shrinking. Share of the Android 4.x devices, on the other hand, is growing at a fast pace.

What we did was create two versions of our code. Our current code would be for 2.x devices and we created a new branch of the code for 4.0 and above.

As a developer, it made my life easier.

We removed all the 3rd-party compatibility libraries and purged all code specific to supporting older devices. We became more adventurous with the UI especially with the animations. We switched to using high-resolution images without much issue.

Our automated (Robotium) tests run more consistently. (On Android 2.x, we had to use longer timeouts so the tests would not fail.) We also had fewer phones to do our manual testing in.

Overall, our development time was a lot quicker. For a good stretch of time, we were able to do weekly releases except when developing major features.

While we only actively developed for 4.0 and above. Our 2.x users can still download an old version of the app since Google Play has Multiple APK support.

When we made the decision to stop supporting older devices, we made several assumptions.

Owners of older devices do not expect a high-quality app. Fortunately, there wasn’t much complaints from users on why some features are not available on their phones.

Since a large part of Wedding Party users are in the US and US smartphone users would likely have newer devices, Android 2.x share would continue to shrink over time. (Android 2.x % for Wedding Party have been dropping a few percentage points every month).

Our decision was made a lot easier knowing that several developers went in the same direction.

Popular apps like Vine & the latest version of Holo Sudoku  only supports 4.0 and above and there wasn’t much of an uproar.

More recently, Square Cash and Flyne have the same requirement.

Jake Wharton, who works on Android at Square, also popularly known for his ActionBarSherlock library, said that developer productivity was the main factor on why the Cash app only supports 4.0 and above.

Developer productivity is #1. The app cannot ship unless it gets finished. Cash was developed primarily by one person with a tiny bit of support from other Android engineers. Could we have supported Android 2.x and hit our ship date? Probably. Could we hit our ship date only supporting Android 4.x+. Absolutely. Cash is a beautiful app. This can be achieved on Android 2.x but it requires more effort.” says Jake.

The type of app Cash is was also something they considered. According to Jake, “We conducted some simple research into our user base and have seen that the kinds of people who would be willing to download an email-based money moving product on Android are overwhelmingly on 4.0 and above.”

NPR will also support only 4.0 and above in their upcoming app which will have streaming audio and video.

According to Mike Seifollahi, one of developers building the NPR app, “codec support on older devices is hit or miss.  When trying to deliver the best user experience for our streaming audio and video content, being able to support the right codecs is essential.  Having to write/deal with software decoding for older device support is not a good use of resources.”

Android 4.0+ APIs also shows the maturity of the platform.

”Android 4.0 is a grass-is-greener ideal that actually is the greenest damn thing you’ll see. APIs are sane and normalized. There are new APIs for rich, dynamic, declarative development that allows you to engage the user more effectively. This version of Android is the first which actually helps you write better apps.” added Jake.

Jeff Gilfelt shares the same sentiment. “API 14 is when Android got serious. When design became a first class citizen and the default wasn’t ugly. It was a milestone release in many ways, and in 2013 I think it is a sensible line in the sand. Furthermore, multiple APK support in Google Play means you can still distribute a stable legacy version of your app to new customers who are running older platform versions.”

There may be some cases where supporting only 4.0 and above may not apply. If your app relies on network effects (similar to Twitter or Facebook) and/or target a worldwide audience (specifically India and China), you might need to support older versions.

If your app does not fall in the above categories, the positives of minSdkVersion=14 greatly outweigh the negatives.

With the holiday season coming, expect the share of Android 2.x devices to fall sharply. A huge number of Android device activations happen during this time and all of them would have at least Android 4.0. I won’t be surprised if 2.x share would be in the single digits by January 2014.

To reiterate Reto Meier’s point above, let’s start building the best possible Android app for every user.

Now go to your AndroidManifest.xml and change the minSdkVersion to 14!

How I Built My 1st Glassware: Glass To Phone (Part 1 of 2)

I received my Google Glass in May 8 which finally gave me access to the Mirror API. After a week of using it, I finally had an idea for what app I should be building for it.

On Glass, there are only limited options to which social networks you can share your pictures. Among them are Google+, Facebook and Twitter.

I wanted a way to share my photos to pretty much any app I wish. For me to do that is by having access to my photos on my phone.

This is why I built Glass To Phone ( It’s a pretty simple app that acts as a Contact in your Glass.


When you share your photo to Glass To Phone, it will be downloaded to your phone and you can share it to any of your Android apps or move it to your photo gallery.

Glass To Phone has web and Android apps. The web app was developed using Python and Django and is hosted on Heroku.

Android was done natively with Google Play Services for authentication, Kevin Sawicki’s http-request for Http & Square’s Picasso for image loading. You can download the Android app on Google Play.



The database used by both the web and Android apps is powered by Parse.

Initially, I wanted it to be just an Android app. However, Google Play Services does not allow your app to request offline access so I was forced to have a web client.

The web app has the authentication to access the Glass Timeline. I also needed offline access for the callback page that the Mirror API hits when a user shares to my app.

For Part 2, I’ll go into detail on how I built the web & android apps including the code.

Sign In With Google & Get User Info from Google+ Profile

At the start, authentication options for our site Burp ( include regular email/password & Facebook Connect. For quite a while, I’ve been wanting to integrate Google Accounts Authentication.

I’ve looked at django-socialauth ( but it uses OpenID. I prefer a pure OAuth2 implementation similar to what Facebook & FourSquare uses.

Looking at Google’s documentation, it’s not easy to figure out. The Federated Login ( is just a pain to implement.

Google recently streamlined their API & they have libraries for every major programming language. Implementation is too complex though which includes a separate model to store credentials (see

OAuth2 implementation by FourSquare & Facebook is so simple that there must be a way to do that with Google: Get an authorization url, Get a code back & Exchange that for an access token. Then use that access token to access the API. Google has documentation for OAuth2 but it actually lacks information on how to get a user’s email address (

After scouring the internets, I finally stumbled into a PHP implementation. It has the scope ( that I’ve been looking for which is missing from Google’s documentation ( The OAuth2 steps are pretty standard except that the access token can be added to the header of the request instead of as a parameter in the url (

This, however, only gets me the email address of the user. I also want to get the user’s name, location, gender, etc.

Luckily, Google just opened up an API for Google+.

By adding the scope – – to the OAuth2 call, our app will have access to the public info the user provided in their Google+ Profile. The People:get method ( will provide you with the user’s Display Name, Location, and Profile Picture Url among others.

You can view the sample Django project at

Taskyo: Access Google Tasks on your mobile device

I’m a big user of Google Tasks. It’s barebones but I like it mainly because of its integration with GMail & Google Calendar. However, Google doesn’t have a mobile-friendly site to use Google Tasks.

Over the weekend, I built Taskyo ( It is not meant to replace the main Google Tasks site but instead supplement it. This is why the features for Taskyo is limited – no editing of lists, ordering of tasks among others. Being able to create a list, create a task, marking a task as ‘Complete’ and deleting a task pretty much covers everything you need when accessing it on the go.

I built this using Python on App Engine and JQuery Mobile. It works well on the phone and on the tablet too.

Developing this app also allowed to me play with the new Google APIs for the first time. I really like what Google did. All the APIs are consistent and centralized. There are libraries for Java, Python, and PHP. The API Explorer ( was particularly useful.

I found some hiccups though especially how to do OAuth2. The authorization example they have for Google Tasks ( was not for websites. But having worked on the Twitter & Foursquare API using OAuth2, I eventually figured it out. With the other issues I had, the Google Tasks Developer Forum helped me solved them (


MapMyPhotos Now on Android Market

After a week of development, my new Android app, Map My Photos, is now available on the Android Market. It comes in a Lite version (Ad-supported and only 50 photos) and Paid version ($0.99; No ads and unlimited photos).

Map My Photos lets you browse your geo-tagged photos from the camera folder by cities and on a map. This is similar to the IPhone’s built-in Photo app.

Available on the Android Market:

or if you are browsing from your Android phone, click here.

2010: Year In Review


I was employed full-time 7 months out of the year which is a one-month improvement from 2009. I was supposed to work for Movity (Winter 2009 -YCombinator) and be their first employee. But right before the YC session started, I got offered a job by another startup. I consider the Movity founders good friends but I had to make an objective decision and joined instead. I felt bad backing out at the last-minute but it turned out really well for Movity since they got a more talented developer in Zain (@zainy).

I didn’t leave Movity completely. I helped them out during the YC session.  On weekends, there were seven of us cramped in a very small office. It’s one of my most enjoyable coding experiences where I was surrounded by people who are focused on one goal.

I worked for for seven months. I learned a lot more about Django since I was surrounded by smart & experienced Django developers (e.g. @david_ziegler). I left Mingle last July when I decided I need to do my own startup. To pay the bills, I did a short-term, part-time gig for

Health & Fitness:

Working a lot has taken a toll on my health earlier this year. Working full-time at Mingle and part-time for Movity stressed me out a lot. It weakened my immune system and this led me to get shingles. Fortunately, it wasn’t a painful experience and I just had to rest for a week.

Despite that, I was generally healthy in 2010 and able to play sports a lot. I had the motivation to work out a lot even just by myself. I don’t have the workout regimen I had back in 2008 though when I was doing ActiveX at my old company in San Diego.

I started playing water polo again but my stamina wasn’t there. I ended up ruining the game for other people. I quit after a month but I plan to be back sometime in 2011.

I did Mission Bay Tri again (my second sprint race) and improved by almost 10 minutes (From 1:29:29 to 1:20:10).

I joined the Palo Alto soccer league in the summer and  started running with Burt (@burtherman) & Brian (@dustball). I had to stop running though after having some foot problems. I got an Xray and found no broken bones. Therapy helped a little bit but I basically can’t run more than 5 miles now.

Bay Area:

Hacker Dojo in Mountain View is my second home. Well, actually, I spend a lot more time there than at home. The place has great energy and I became friends with a lot of good people.

I got sick of the Bay Area for a little bit. This area is inside a bubble in both good and bad ways. Bay Area sets a lot of technology trends but it is not mainstream. What happens here is very different from the rest of the US and even the world but Bay Area people think that it is the same everywhere else.

This has led me to shun a lot of networking events because of the group-think. This is also why I decided to travel to Argentina, to get away from the area for a bit.

I still love the Bay Area though. This is where I belong and I can’t imagine being anywhere else.


The only travel I did was Buenos Aires. I went with my cofounder Dan Kwon (@dankwonjr) for a month. It was more of a team-building for us. I learned a lot about my cofounder and also about myself. I have been a loner for the past few years and it’s refreshing to hang out with somebody a lot and hear what they think about me.

Lessons Learned:

Never settle: Time and time again, settling for something has brought me unhappiness. I have always wanted to have my own company but I tried to convince myself to stay at Mingle instead. This has led me to be unhappy at work. I finally came to my senses and resigned. I’ve been happier since. I work on projects I’m passionate about and started building a startup with @dankwonjr. There are some financial uncertainties though since I don’t have a lot of liquid savings so I do some part-time work from time to time.

Always Be Positive: It’s been tough for me since I moved from DC to the West Coast. I became a bit negative and it has held me back on a lot of things. Lately though, I make it a point to be more positive. I always try not to get angry and not complain. This is largely influenced by the people I surround myself with. I plan to continue this habit indefinitely.

Believing in Myself: I doubt myself a lot. It has gotten worse when I moved to the Bay Area. I’m surrounded by more intelligent and more experienced developers. The good thing is this motivated me to get better by learning new things. I picked up Python/Django in 2009 and it paid off for me in 2010. I also have been doing a lot of Android development. Learning a new programming language or framework doesn’t intimidate me anymore. I’m also not scared to take on projects that maybe over my head. I know that I can figure out a way to build it.


2010 was a good year for me but it is actually more of a build-up for the great years to come. For the next few years, my plan is to continue learning and be more open to new experiences.