Android: Installing multiple variations of the same app on one device

This post is bit of a follow up to my last post on how to build an app for multiple environments and local development using build types and product flavors. We will focus on how to install multiple of the resulting APKs on a single device.
Given the scenario that we use some hardware devices for development, but we also use those devices to review our progress over the last weeks with our customers. We don’t want to uninstall / reinstall the app every time, as this would also mean to lose all data (if we use the debug certificate for our development and the release certificate for accessing actual systems like discribed in the previous post). So we’d like to install both, the debug APK and the APK for a test / demo environment on one device. How can we achieve that?

Modifiying the applicationId

To install the app multiple times, you have to provide a unique applicationId to every instance you want to install.
You can do that with the ‘applicationIdSuffix’ property in the buildTypes:

    buildTypes {
        debug{
            applicationIdSuffix ".debug";
            ...
        }
        local{
            applicationIdSuffix ".local";
            ...
        }
        tst{ // build types may not start with 'test'
            applicationIdSuffix ".test";
            ...
        }
        stage{
            applicationIdSuffix ".stage";
            ...
        }
        release {
            // for releases we want to keep the original applicationId
            ...
        }
    }

Apply the changes, and the different buildTypes APKs may now co-exist on a device.

Which is which?

Now that we have installed the same app multiple times… how can we know on the first look, which of the apps is for which environment?
demo1
We can use different resources for the different build types by putting the resources in folders named like the build types (same resource path as in main, of course). So we could either use a different icon for each environment, or a different app_name (e.g. prefixed with the environment).
Example for using different icons:
demo2-2
And the result:
demo2

Setting the Activity titles

To ensure we can also distinguish the different environments inside the app, we can append the environment from the BuildConfig to our Activity titles:

public class DemoActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        updateTitle();
    }
    private void updateTitle() {
        if(!"PROD".equals(BuildConfig.ENVIRONMENT)){
            setTitle(BuildConfig.ENVIRONMENT + " " + getTitle());
        }
    }
}

Maybe you’ll want to write the code for updating the title a bit cleaner, but that’s it for the example 😉
Please let me hear your opinion about this approach in the comments!