There are some cases when you want to check if your Android application is running in debug or release mode.
Testing BuildConfig.DEBUG
The best way is to use BuildConfig.DEBUG. This is a boolean value that will be true for a debug build, false otherwise:
if
(BuildConfig.DEBUG)
{
// we are running in DEBUG mode
}
Testing if "android:debuggable" attribute is set to "true"
Other way you can do that is to use android:debuggable attribute defined in AndroidManifest.xml file. If you are using Eclipse or Ant developing environment and have installed Android SDK 8.0.1 or higher this attribute will be set automatically to true or false by the build tools. Other way is to set value of android:debuggable attribute manually to true or false, dependig of are you building debug or release version of your application.
Here is the example code you can use to check the value of debuggable attribute.
private
boolean isDebuggable(Context ctx)
{
boolean debuggable =
false
;
PackageManager pm = ctx.getPackageManager();
try
{
ApplicationInfo appinfo = pm.getApplicationInfo(ctx.getPackageName(), 0);
debuggable = (0 != (appinfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
}
catch
(NameNotFoundException e)
{
/*debuggable variable will remain false*/
}
return
debuggable;
}
Testing if application is signed with debug key
There are some other ways to check if you are running debug or release mode of application. You cant test if application package is signed with debug key. Debug key is automatically generated by Android SDK tools while you are developing application. One way is to obtain your debug key signature, hardcode it into your code, and then test if your application is signed with this key. In my opinion this is not a good way to check debug/release mode, because it will not work if you copy your code to the another machine or if you share your code with other developers using some sort of versioning software.
Here is the example code with hardcoding debug key:
// copy your debug key here from LogCat window using Ctrl+C after first execution of code
private
static
final String DEBUG_KEY =
"copy debug key signature here"
;
private
boolean isDebuggable(Context ctx)
{
String TAG =
"isDebuggable"
;
boolean debuggable =
false
;
try
{
PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),PackageManager.GET_SIGNATURES);
Signature signatures[] = pinfo.signatures;
for
(
int
i = 0; i < signatures.length;i++)
Log.d(TAG,signatures[i].toCharsString());
if
(DEBUG_KEY.equals(signatures[0].toCharsString()))
{
debuggable =
true
;
}
}
catch
(NameNotFoundException e)
{
//debuggable variable will remain false
}
return
debuggable;
}
According to the info in Android documentation Signing Your Application, debug key contain following subject distinguished name: "CN=Android Debug,O=Android,C=US". We can use this information to test if package is signed with debug key without hardcoding debug key signature into our code.
Here is the example code for checking subject distinguihsed name of key:
private
static
final X500Principal DEBUG_DN =
new
X500Principal(
"CN=Android Debug,O=Android,C=US"
);
private
boolean isDebuggable(Context ctx)
{
boolean debuggable =
false
;
try
{
PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),PackageManager.GET_SIGNATURES);
Signature signatures[] = pinfo.signatures;
for
(
int
i = 0; i < signatures.length;i++)
{
CertificateFactory cf = CertificateFactory.getInstance(
"X.509"
);
ByteArrayInputStream stream =
new
ByteArrayInputStream(signatures[i].toByteArray());
X509Certificate cert = (X509Certificate) cf.generateCertificate(stream);
debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
if
(debuggable)
break
;
}
}
catch
(NameNotFoundException e)
{
//debuggable variable will remain false
}
catch
(CertificateException e)
{
//debuggable variable will remain false
}
return
debuggable;
}