I'm building an Android application and would like to maintain a few environment variables that I can tweak depending on whether I'm in development mode or release mode. For example, I need to invoke a web service and the URL will be slightly different in either mode. I'd like to externalize this and other settings so I can change them easily based on my target depl开发者_StackOverflowoyment.
Are there any best practices or anything in the SDK to assist with this need?
The following solution assumes that in manifest file you always set android:debuggable=true
while developing and android:debuggable=false
for application release.
Now you can check this attribute's value from your code by checking the ApplicationInfo.FLAG_DEBUGGABLE
flag in the ApplicationInfo
obtained from PackageManager
.
The following code snippet could help:
PackageInfo packageInfo = ... // get package info for your context
int flags = packageInfo.applicationInfo.flags;
if ((flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// development mode
} else {
// release mode
}
According to this stackoverflow post, in SDK Tools version 17 (we're on 19 as of this writing) adds a BuildConfig.DEBUG
constant that is true when building a dev build.
@viktor-bresan Thanks for a useful solution. It'd be more helpful if you just included a general way to retrieve the current application's context to make it a fully working example. Something along the lines of the below:
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
Android build.gradle has Handles Debug and Release Environment well.
Append the following code snippet in build.gradle
file
buildTypes {
debug {
buildConfigField "Boolean", "IS_DEBUG_MODE", 'true'
}
release {
buildConfigField "Boolean", "IS_DEBUG_MODE", 'false'
}
}
Now you can access the variable like below
if (BuildConfig.IS_DEBUG_MODE) { {
//Debug mode.
} else {
//Release mode
}
I would check out isDebuggerConnected
How about something like the code below ...
public void onCreate Bundle b ) {
super.onCreate(savedInstanceState);
if ( signedWithDebugKey(this,this.getClass()) ) {
blah blah blah
}
blah
blah
blah
}
static final String DEBUGKEY =
"get the debug key from logcat after calling the function below once from the emulator";
public static boolean signedWithDebugKey(Context context, Class<?> cls)
{
boolean result = false;
try {
ComponentName comp = new ComponentName(context, cls);
PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(),PackageManager.GET_SIGNATURES);
Signature sigs[] = pinfo.signatures;
for ( int i = 0; i < sigs.length;i++)
Log.d(TAG,sigs[i].toCharsString());
if (DEBUGKEY.equals(sigs[0].toCharsString())) {
result = true;
Log.d(TAG,"package has been signed with the debug key");
} else {
Log.d(TAG,"package signed with a key other than the debug key");
}
} catch (android.content.pm.PackageManager.NameNotFoundException e) {
return false;
}
return result;
}
I came across another approach today by accident that seems really straight forward.. Look at Build.TAGS, when the app is created for development this evaluates to the String "test-keys".
Doesn't get much easier than a string compare.
Also Build.MODEL and Build.PRODUCT evaluate to the String "google_sdk" on the emulator!
Here's the method I use:
http://whereblogger.klaki.net/2009/10/choosing-android-maps-api-key-at-run.html
I use it to toggle debug logging and the maps API key.
精彩评论