TacB0sS
TacB0sS

Reputation: 10266

Is there a way to determine whether an Android application is signed for production or debug at runtime?

Is there a way to determine whether an Android application is signed for production or debug at runtime?

Upvotes: 4

Views: 1567

Answers (4)

Nikolay Elenkov
Nikolay Elenkov

Reputation: 52936

Yes, but no 100% reliable. The default (auto-generated) certificate has the DN 'CN=Android Debug,O=Android,C=US' as described here. If you check the DN and it matches the default, it is most probably the debug certificate. Nothing prevents people from generating their own debug certificate or using the same one for production and debugging though.

You can get the signing certificate using PackageManager. Something like:

PackageManager pm = context.getPackageManager();
Signature sig = pm.getPackageInfo(getPackageName(), 
   PackageManager.GET_SIGNATURES).signatures[0];
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(
    new ByteArrayInputStream(sig.toByteArray()));
String dn = cert.getIssuerDN().getName();

Upvotes: 6

Henrique de Sousa
Henrique de Sousa

Reputation: 5795

We use a much simpler way:

if (BuildConfig.DEBUG) {
    // we're in debug mode
} else {
    // we're in production mode
}

Upvotes: 3

Ifor
Ifor

Reputation: 2835

The post android-automatically-choose-debug-release-maps-api-key Has another packagemanger based solution. Basicaly you compare to the hashCode of the actual signatuse. Working well for me for sorting out the maps key automaticaly

Upvotes: 0

FunkTheMonk
FunkTheMonk

Reputation: 10938

private static Boolean isDebugBuild = null;
    protected boolean isDebugBuild() {
        if(isDebugBuild == null) {
            PackageManager pm = getPackageManager();
            try {
                PackageInfo pi = pm.getPackageInfo(getPackageName(), 0);
                isSignedWithDebugKey = (pi.applicationInfo.flags &
                    ApplicationInfo.FLAG_DEBUGGABLE) != 0;
            }
            catch(NameNotFoundException nnfe) {
                nnfe.printStackTrace();
                isDebugBuild = false;
            }
        }

        return isDebugBuild;
    }

Since ADT 8, if you don't specifically add debuggable="true" to your manifest, debug builds will have it set to true, and exported / signed builds will have it set to false.

It sounds like this is might be a more reliable method (as long as you don't manually set debuggable..) to determine if it is a debug vs release build, but not specifically if the certificate was a debug cert - which was your question, so my answer might not be relevant for you.

Upvotes: 7

Related Questions