Reputation: 60081
As refer by Getting "debuggable" value of androidManifest from code?, there are two options of checking if the build is debuggable:
1.) BuildConfig.DEBUG flag
if (BuildConfig.DEBUG)`
2.) ApplicationInfo.FLAG_DEBUGGABLE
if (0 != (getContext().getApplicationInfo().flags &
ApplicationInfo.FLAG_DEBUGGABLE))
Are they two identical, or they are different? When to use what?
Upvotes: 14
Views: 7977
Reputation: 1413
One area that did highlight the differences in the usages of these flags was following a pen test of our app. The pen test report pointed out to us that attackers can employ a technique called "hooking" where the app is recompiled with the android:debuggable flag changed to true (how this is done I'm not totally sure).
Their recommendation to detect this happening was to add some code as follows:
if (!BuildConfig.DEBUG) {
try {
ApplicationInfo appInfo = getPackageManager().getApplicationInfo("uk.co.myapp", 0);
if ((appInfo.flags & appInfo.FLAG_DEBUGGABLE) != 0) {
// App has been compromised
finish();
return;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
What you do when you detect this circumstance is down to you. I added it to my startup activity, and if triggered, I display a message followed by the finish() statement.
Upvotes: 2
Reputation: 9803
My experience is that BuildConfig.DEBUG
is always linked to the debuggable
build attribute in the gradle file.
buildTypes {
debug {
debuggable true
}
debug {
debuggable false
}
...
}
The documentation also supports this:
- boolean DEBUG – if the build is debuggable.
getContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE
was likely the only way to determine if a build was debuggable before the gradle build system and Android Studio replaced eclipse around 2015.
Use BuildConfig.DEBUG
because it resolves to a constant which can be used during compilation to optimize code.
Upvotes: 1
Reputation: 62189
They are not identical.
There may be many buildType
s, but debug
and release
are mandatory. BuildConfig.DEBUG
will be true
if currently selected build type is debug
, otherwise it will be false
(see exclusion case below).
ApplicationInfo.FLAG_DEBUGGABLE
corresponds to following:
buildTypes {
debug {
debuggable true
}
...
}
Now, ApplicationInfo.FLAG_DEBUGGABLE
will be true
.
Thus, you may conclude, that you may perform following:
buildTypes {
debug {
debuggable false
}
...
}
Interestingly, although you are in debug
build type, BuildConfig.DEBUG
will become false
.
Upvotes: 12
Reputation: 60081
Found a good article here: http://tekeye.biz/2013/android-debug-vs-release-build.
Also tested it out. If we force android:debuggable="false"
or android:debuggable="true"
on Manifest Application, it will warn :
Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one less...
It's best to leave out the android:debuggable attribute from the manifest. If you do, then the tools will automatically insert android:debuggable=true when building an APK to debug on an emulator or device. And when you perform a release build, such as Exporting APK, it will automatically set it to false.
If on the other hand you specify a specific value in the manifest file, then the tools will always use it. This can lead to accidentally publishing your app with debug information.
I would conclude, in default situation ApplicationInfo.FLAG_DEBUGGABLE
behave the same as BuildConfig.DEBUG
, unless override by changing android:debuggable
, which is not something advisable.
Compare to BuildConfig.DEBUG
, ApplicationInfo.FLAG_DEBUGGABLE
is a more reliable way to check for debug build, as at a lower dependent module, it can't access the BuildConfig.DEBUG
of the parent module, and could have a different value.
e.g. App use MyLib module. App's BuildConfig.DEBUG
could be false, but MyLib BuildConfig.DEBUG
could be true. Hence it's better to check using ApplicationInfo.FLAG_DEBUGGABLE
Upvotes: 5