BuildConfig.DEBUG override to true for release build? - android

Is there any way, at least temporarily, to tell ADT to leave BuildConfig.DEBUG as TRUE even for release builds?

At that point, you should just create your own constant like
public class MyConfig {
public static final boolean DEBUG = true;
}
BuildConfig really is meant to tell if it is a debug or production release.
Note that you can modify your own constant from outside the code. For example, on Linux or OSX:
#!/bin/bash
cat MyConfig.java | sed -e 's/DEBUG = true/DEBUG = false/g' > newMyConfig.java
mv newMyConfig.java myConfig.java
ant release
This simply rewrites the config via an outside source.

I was facing the same issue as everytime I was running the project as android application it used to open in debugger mode but then the problem was solved.
-If you are working in eclipse you must be using Java EE perspective
-Instead just select Java perspective.
-Clean your app.
-uninstall the app from the device.
-Restart your device (Just like that so that no cache is stored)
-Run your app.
The debugger mode won't show up this time. Copy the apk generated in your bin folder and try it out on other devices as well

Related

Can't get malloc debug to turn on?

I'm trying to enable malloc debug for my android application, and for the life of me i can't get it working.
My wrap.sh scripts each contain this:
#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS="free-track verbose"
logwrapper "$#"
and I've set up the following directory structure:
When I grep logcat for "malloc debug enabled", I get nothing.
If i change my wrap.sh scripts contents to this
#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS=free-track logwrapper "$#"
which is exactly what the documentation for the wrap shell script says to add (although to me that seems like invalid shell script syntax), i can see the "malloc debug enabled" log message, but my application freezes at the splash screen and never actually launches.
I'm not sure what's going on and would love any type of input.
Other notes:
My project is using CMake.
My debug device is running Android P.
That is for running an executable binary on Android. I think you are running a Java app with JNI calls, and that trick does not apply to you. You will have to set those environment variables from JAVA as the app starts.
Try looking at OS.setenv() - https://developer.android.com/reference/android/system/Os.html. I hope that those environment variables can be set from Java before the JNI library is loaded, or that the library reads those environment variables on every call, and not just init.
If the accepted answer doesn't work for you then my solution might work:
#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS=free-track logwrapper
exec "$#"
Make sure line endings are LF and not CRLF.
Then my issue was that malloc debug wasn't able to write the dump:
E/malloc_debug: Unable to create file: /data/local/tmp/backtrace_heap.16934.exit.txt
I thought this might be due missing permissions. By changing the output folder to the one of your app, this is circumvented:
LIBC_DEBUG_MALLOC_OPTIONS='backtrace backtrace_dump_on_exit backtrace_dump_prefix=data/data/com.your.app/files/dump' logwrapper
And dumping now works:
E/malloc_debug: Dumping to file: data/data/com.your.app/files/dump.17599.exit.txt
Also make sure you set
buildTypes{
debug {
debuggable true
}
}
in build.gradle and
android:extractNativeLibs="true"
android:debuggable="true"
in the AndroidManifest.xml file

How we can debug a signed apk without having source code?

I want to ask if there is a possibility to debug a release apk without having source code and how we can prevent user to do this action ?
I thought that I can't debug an apk without a source code ( manifest has by default android:debuggable="false") until I sent it to a client and he asks me to disable debuggable mode because he got this issue . I try to reproduce the problem and I'm thinking if he did a reverse engineering.
You can debug an already signed APK with a number of different tools. Most approaches would be considered a form of reverse engineering. At a high level, a common approach (for dynamic "live" debugging) would be to:
Use APKTool to enable debugging via the property in the AndroidManifest.xml. Align and sign the newly modified APK.
Use ADB to push the new "debuggable" APK to the device/emulator.
Use a debugger such as GDB (NDK includes a gdbserver with the arm toolchain).
It's worth mentioning that static analysis can be an option too, whereby the APK could be unpacked and decompiled to SMALI/Java.
There are a number of tools available to help reverse and debug APK's. Some I use frequently are; dex2jar, JDGUI, APK Studio, JEB, IDA Pro, VisualGDB.
You can debug APKs without having source code, using Android Studio 3.0 and higher
First make sure to Enable Debugging
To start debugging an APK, click Profile or debug APK from the Android
Studio Welcome screen. Or, if you already have a project open, click
File > Profile or Debug APK from the menu bar. In the next dialog
window, select the APK you want to import into Android Studio and
click OK.
Some prevention tricks against debugging:
1. Checking the Debuggable Flag in ApplicationInfo
The android:debuggable flag in the Android Manifest determines whether the JDWP thread is started for the app. Its value can be determined programmatically, via the app's ApplicationInfo object. If the flag is set, the manifest has been tampered with and allows debugging.
public static boolean isDebuggable(Context context){
return ((context.getApplicationContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
}
2. isDebuggerConnected
The Android Debug system class offers a static method to determine whether a debugger is connected. The method returns a boolean value.
public static boolean detectDebugger() {
return Debug.isDebuggerConnected();
}
The same API can be called via native code by accessing the DvmGlobals global structure.
JNIEXPORT jboolean JNICALL Java_com_test_debugging_DebuggerConnectedJNI(JNIenv * env, jobject obj) {
if (gDvm.debuggerConnected || gDvm.debuggerActive)
return JNI_TRUE;
return JNI_FALSE;
}
3. APK Signatures check
If APK is resigned, its signature would have changed. Check that against your original APK signature.
we can not debug apk.
You can check only logs if used for release build.
open Android Monitor in android studio at the bottom
and select No Filter from drop down appears at top-left.
You will be able to see logs of released .apk

How to have Android Gradle build write a file that goes into the debug APK

GenyMotion's localhost IP address (10.0.3.2) is different from the Android emulator's localhost IP (10.0.2.2). Currently I have this in one of my source files:
//val LOCALHOST = "10.0.2.2" // Android emulator
val LOCALHOST = "10.0.3.2" // Genymotion
and whenever I switch between a Linux box and a Mac box and fetch the latest sources, I have to uncomment one and comment the other before rebuilding.
Unless someone can think of a better solution, I would like to have a Gradle task that writes out one of these values depending on the host OS, into a file that's included in the APK in such a way that I can access it from my Android app's runtime, and have that task run before assembleDebug when I build in Android Studio.
I suppose putting it in a resource would be easiest to access on the runtime side, but even a plain text file accessible to Class.getResourceAsStream() would be fine too.
I don't mind if it's included in the release apk, but I'd prefer that it just go into the debug ones.
I would also prefer that the file be generated in my build/ output directory, so that it's invisible to version control.
Any idea how to go about this?
There are much better solutions like finding the local IP address using getNetworkInterfaces(), but as you asked how to pass some information from gradle,
android {
productFlavors {
flavorGenymotion {
buildConfigField "String", "LOCALHOST", '"10.0.3.2"'
}
flavorEmulator {
buildConfigField "String", "LOCALHOST", '"10.0.2.2"'
}
}
...
which you can access as BuildConfig.LOCALHOST.

android build release apk on jenkins, without storing my password in plain text

I need to be able to build the release version of my apk, using a Jenkins job.
From reading the following SO question
How to create a release signed apk file using Gradle?
I understand I can do it in one of two ways. Either get the user to enter the password at cmd prompt, or store my password details in a plain text file that doesn't get committed to git, and lives on my local machine.
Neither of these will work when running the build job on jenkins though. 1) I can't gain user input because this may be running in the middle of the night (I don't even know how to get user input from the cmd line even if the user was at their machine) 2) Anyone who can gain access to that build box, would be able to cat the contents of that file either via the cmd line or from another build.gradle job running on that jenkins server.
Does anyone know of anyway I can keep my password hidden but so that the Jenkins job can access it?
Thanks
You can use Mask Password Plugin, which does just that. Or the same functionality is included in EnvInject plugin, and sooner or later all Jenkins projects get a need for EnvInject plugin (that does many other things), so might as well start using it now.
To securely use a password from within a build/post-build step
Install EnvInject plugin.
Under Jenkins Global Configuration, find Global Passwords section.
Add a name (this will be the environment variable name) and password (will be starred **** ).
Under Job Configuration, find Build Environment section.
Checkmark Inject passwords to the build as environment variables.
Then checkmark Global passwords.
In any build step, you can now use $name (as defined earlier) to refer to a password as you would if you were typing it in plain text.
The password variable is injected only at job execution time (typing $name on command line of the server by itself will not produce anything, and like all Jenkins variables, it is not persistent).
The job console log will show **** instead of password, if it appears.
You could configure passwords per job, rather than globally, so that other jobs can't use it.
The only security concern is that if someone has administrative permissions to configure your job, they can write echo $name > secretpassword.txt into a build step, and then review the file in the workspace. But you should be careful who you assign administrative rights to.
You should take a look for this plugin
https://wiki.jenkins-ci.org/display/JENKINS/Mask+Passwords+Plugin
If your Jenkins instance happens to be running on EC2, and you don't want to permanently store secrets in the file system, you can put the store and key passwords into Systems Manager Parameter Store, then query them at build time. In addition, you can put the keystore itself into external storage, such as S3, and only keep it locally for the duration of the build.
Here is a sample build script (assume that the secret parameters are named android-keystore-pass and android-signature-key-pass):
set -o errexit
set -o pipefail
keystore_file=keystore.properties
keystore=wise.jks
aws s3 cp s3://path-to-android/$keystore .
chmod go-rwx $keystore
touch $keystore_file
chmod go-rwx $keystore_file
cat > $keystore_file << EOF
storePassword=`aws ssm get-parameters --names android-keystore-pass --with-decryption | cut -f4`
keyPassword=`aws ssm get-parameters --names android-signature-key-pass --with-decryption | cut -f4`
keyAlias=android
storeFile=$WORKSPACE/$keystore
EOF
An example of the Gradle build scripts can be found in this answer. You can commit a dummy keystore.properties to source control so that (non-release) builds work on dev machines.
There are also open-source secret distribution tools that are platform-independent, e.g. Vault, but I haven't tried any of them.

How to pass a parameter to the Java code in run/debug configuration from Android Studio

My android app does some http requests to my server. However sometimes I am debugging the new api code that runs on my development machine. I would like to be able to pass something (like an environment variable) so in my code, if it's present I would be able to use that as the hostname for the api requests from the android emulator.
So I'm looking for a way to pass something like:
API_SERVER=http://10.0.2.2/myapp/
and in my code I would use it somehow, for example:
final static String API_SERVER_REAL = "http://example.com/";
final String apiServerOverride = System.getenv("API_SERVER");
final String API_SERVER = (null != apiServerOverride && !apiServerOverride.isEmpty() ? apiServerOverride : API_SERVER_REAL);
I know this thread is quite old, but in my opinion none of provided answers actually solves the problem. Flavors are ill-suited for parametrizing your build with things like API URLs, and even worse for things like API keys etc.
Firstly, build.gradle which defines flavors is part of project source, therefore it must not contain such information in order to be safely committed into source control systems.
Secondly, a need may arise to test different flavors against different API endpoints/keys. What if you just want to hit some debug http server you just created to solve a bug? Would you create a flavor for that? Probably not... Flavors are good for things like "free flavor" and "premium flavor".
This problem is easily solved using gradles -P flag. You can access gradle properties that are passed this way as regular variables inside your gradle.build, and you can vary it's behavior accordingly.
If you want to push this flags further into your application you can use Scott's solution that was posted here, combined with the provided flag.
The build command would then probably look like:
$ gradle build -Papiroot=http://www.example.com
And in your build.gradle you would define the writeValue task like this:
task writeValue(type:Exec) {
commandLine '/usr/local/bin/adb', 'shell', "echo 'API_SERVER=${apiroot}' > /data/data/values.properties"
}
FYI the -P flag can be easily configured in Android Studio by navigating from the menu:
Run -> Run/Debug Configurations -> Defaults -> Gradle -> Script Parameters
Probably the simplest thing is to write the data you want to pass to a file on the device in /data/data; your Android app can read the device trivially (perhaps make it a .properties file and use java.util.Properties to read it in). To write it out, use this kind of task in your build.gradle file (and use the correct path to the adb command for your setup):
task writeValue(type:Exec) {
commandLine '/usr/local/bin/adb', 'shell', 'echo \'API_SERVER=http://10.0.2.2/myapp/\' > /data/data/values.properties'
}
There's documentation on Gradle exec tasks at http://www.gradle.org/docs/current/dsl/org.gradle.api.tasks.Exec.html
You can execute this task manually from Android Studio by using the Gradle tasks view:
Due to a bug in Android Studio, you cannot pass vm or script parameters from a gradle configuration. The issue is here.
As a workaround in Linux envs (probably Mac too), you can create a bash configuration where you will be able to add all desired parameters.
I suggest using productFlavors. Each flavor can contain environment specific settings. I simply have a class called 'Environment' which contains all the public static final Strings that I need and each product flavor includes an different version of this class with the values set for the environment.

Categories

Resources