This is what we do at Xero for the Xero Me Android app to have different builds depending on the development stage of the App.

We have four build types that we group it into depending on what stage the app is.
1. Dev
2. QA
3. Regression
4. Release

We use Crashlytics for both crash reports and providing test builds to testers and team. We decided to categorize them into the above four builds as it provides an easy way to segregate the crash reports.

We usually ignore the crash reports from Dev build as it is almost always the developers that are causing those or people are aware that it is still going through development. QA builds are generated with each feature merge into the develop branch. Regression build is generated when we finished development of all features planned for the release and we want to test them. Release build is our actual release into the Play Store. This enables us to prioritize the crashes by looking into where they came from.

This is done by using build types and declaring an applicationIdSuffix for each build type in the app’s build.gradle.
Here is the relevant snippets from build.gradle.

android {

    defaultConfig {
        applicationId "com.xero.xerome"

        //This is overridden in each build type to change the authority according to build type.
        resValue "string", "file_authority", applicationId + applicationIdSuffix + '.files.authority'
    }

    buildTypes {
        debug {
            applicationIdSuffix ".dev"
            versionNameSuffix "_dev"
            ...
            resValue "string", "file_authority",
                    defaultConfig.applicationId + applicationIdSuffix + '.files.authority'
        }

        qa.initWith(buildTypes.debug)
        qa {
            applicationIdSuffix ".qa"
            versionNameSuffix "__qa_" + getAndUpdateBuildCount("qa_build_count")

            resValue "string", "file_authority",
                    defaultConfig.applicationId + applicationIdSuffix + '.files.authority'

            ext.betaDistributionGroupAliases = "xero-me-android-qa"
            ...
        }

        regression.initWith(buildTypes.debug)
        regression {
            applicationIdSuffix ".regression"
            versionNameSuffix "__reg_" + getAndUpdateBuildCount("reg_build_count")

            resValue "string", "file_authority",
                    defaultConfig.applicationId + applicationIdSuffix + '.files.authority'

            ext.betaDistributionGroupAliases = "xero-me-android-reg"
        }

        release {
            resValue "string", "file_authority",
                    defaultConfig.applicationId + applicationIdSuffix + '.files.authority'
// more release stuff and signing the build with release certificate
        }
    }

}

Note the resValue declarations in default build and other builds.

resValue "string", "file_authority", applicationId + applicationIdSuffix + '.files.authority'  

That is how we change the Authority of each ContentProvider to let us install all builds simultaneously on the same device without any conflicts in the Authority.

That is it. You should now be able to install different builds of the app on the same device. We also do more stuff like changing build names and versions and that is explained in various blog posts online. In the next post we will see how we let testers identify each build by changing the launcher/app name for each build.

Tags: