Disable LogCat Output COMPLETELY in release Android app?

42,478

Solution 1

You can use ProGuard to remove completely any lines where a return value is not used, by telling ProGuard to assume that there will be no problems.

The following proguard.cfg chunk instructs to remove Log.d, Log.v and Log.i calls.

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** w(...);
    public static *** v(...);
    public static *** i(...);
}

The end result is that these log lines are not in your release apk, and therefore any user with logcat won't see d/v/i logs.

Solution 2

if you don't use proguard, you have to manage the log yourself and in the manifest file make dubuggable false

<application
    android:name="MyApplication"
    android:icon="@drawable/gift"
    android:label="@string/app_name" android:debuggable="@bool/build_log">

Here my custom log class

public class Lol {

    public static final boolean ENABLE_LOG = true & MyApplication.sDebug;

    private static final boolean DEBUG = true & ENABLE_LOG;

    private static final boolean VERBOSE = true & ENABLE_LOG;

    private static final boolean TEMP = true & ENABLE_LOG;

    private static final boolean WARNING = true & ENABLE_LOG;

    private static final boolean INFO = true & ENABLE_LOG;

    private static final boolean ERROR = true & ENABLE_LOG;

    public static void obvious(String tag, String msg) {
        if (DEBUG) {
            msg = "*********************************\n" + msg
                    + "\n*********************************";
            Log.d(tag, msg);
        }
    }

    public static void d(String tag, String msg) {
        if (DEBUG)
            Log.d(tag, msg);
    }

    public static void d(boolean bool, String tag, String msg) {
        if (TEMP&bool)
            Log.d(tag, msg);
    }

    public static void i(String tag, String msg) {
        if (INFO)
            Log.i(tag, msg);
    }

    public static void e(String tag, String msg) {
        if (ERROR)
            Log.e(tag, msg);
    }

    public static void e(boolean bool, String tag, String msg) {
        if (TEMP&bool)
            Log.e(tag, msg);
    }

    public static void v(String tag, String msg) {
        if (VERBOSE)
            Log.v(tag, msg);
    }

    public static void w(String tag, String msg) {
        if (WARNING)
            Log.w(tag, msg);
    }

    public static String getStackTraceString(Exception e) {
        return Log.getStackTraceString(e);
    }

    public static void w(String tag, String msg, Exception e) {
        if (WARNING)
            Log.w(tag, msg,e);
    }
}

Solution 3

In app build.gradle file set:

release {
    minifyEnabled true
     ……
}

In proguard-rules.pro put:

-assumenosideeffects class android.util.Log {
  public static *** v(...);
  public static *** d(...);
  public static *** i(...);
  public static *** w(...);
  public static *** e(...);
}
-ignorewarnings

It worked for me.

Solution 4

The great answer provided by David Caunt doesn't seem to work for the rules defined in proguard-android-optimize.txt.

Instead of using the wildcard ***, current versions of ProGuard seem to expect the return parameter's type qualifier:

-assumenosideeffects class android.util.Log {
    public static int   d(...);
    public static int   w(...);
    public static int   v(...);
    public static int   i(...);
    public static int wtf(...);
}
Share:
42,478
Android Eve
Author by

Android Eve

Just starting in the world of Android development... New to Java and Eclipse as well.

Updated on July 08, 2022

Comments

  • Android Eve
    Android Eve almost 2 years

    Shutting off my own app's LogCat output before releasing an app to the market is straightforward. I also know how to selectively filter LogCat message by tag and/or id for my own debug convenience.

    But now I am interested in something that may be much more difficult (perhaps impossible?): Disable all LogCat output, including & especially those coming from 3rd-party services like TtsService, GoogleLoginService, etc.

    Is this possible?

    To further clarify: I am not interested in filtering out messages for myself. I am rather interested in disabling 3rd-party messages for whoever downloads my app from the Android Market. Is this possible?

  • Android Eve
    Android Eve about 13 years
    This tip is incredible. It already deserves a +1. I will accept the answer after making sure that it indeed yields the desired result in my app. Thank you!
  • David Snabel-Caunt
    David Snabel-Caunt about 13 years
    ProGuard is really powerful! You can also use this tip to remove other forms of development code, not just logging.
  • Rajath
    Rajath about 13 years
    in what other scenarios might we want to remove code? And what forms?
  • David Snabel-Caunt
    David Snabel-Caunt about 13 years
    Code that enables developer features, like additional menu options, perhaps. Logging is the only common thing I can think of that you SHOULD remove.
  • Android Eve
    Android Eve almost 13 years
    I finally got to testing your solution. It works beautifully. :)
  • Tony Chan
    Tony Chan about 12 years
    Will this affect line numbers when trying to match up stacktraces? I've seen some people say it only affects bytecode, so lines will still match, and others say otherwise. Can anyone confirm?
  • David Snabel-Caunt
    David Snabel-Caunt about 12 years
    Since SDK Tools 8 it has not been necessary to set the android:debuggable flag manually. This removes the risk of shipping a debuggable release.
  • androniennn
    androniennn over 11 years
    I added that lines in proguard-project.txt and proguard.config=proguard-project.txt to project.properties and with device connected into PC with Eclipse opened i can always retrieve Logs. Is that normal ?
  • pt123
    pt123 almost 11 years
    You need to be careful with this because you add a comment like Log.d(someStrVar + " sensitive info here"); the sensitive info string will still make it into the classes.dex file in the APK. Because Proguard has issues with optimisation when stringbuilder is used implicitly
  • minsk
    minsk over 10 years
    They warn in proguard.cfg about problems with allowing proguard optimization and dex. I wasn't able to run it as is. Since I only needed proguard to remove logs, restricting optimization option to removal worked for me (in case someone has similar situation: -optimizations code/removal/*
  • Andrew T.
    Andrew T. over 8 years
    Just curious (I stumbled upon this question just now), is there any reason why you use true & ENABLE_LOG instead of only ENABLE_LOG? I don't see any difference functionality wise...
  • phnmnn
    phnmnn almost 8 years
    You have to use proguard-android-optimize.txt, if you want the assumenosideeffects settings to work. In android studio: proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  • 0xAliHn
    0xAliHn over 7 years
    @DavidCaunt Is there any way to hide native layer logs?
  • David Snabel-Caunt
    David Snabel-Caunt over 7 years
    I don't know, but I don't think ProGuard is the way to silence native logs – it removes logs from your own code by literally removing the logging calls.
  • Ritesh Gune
    Ritesh Gune over 7 years
    @DavidCaunt, Could you plz verify again whether this works or not. Cause IMHO this piece of code does not work anymore. You will have to specify the exact return type ie. int instead of ***. Plz refer - stackoverflow.com/a/13327603/1554935
  • rubmz
    rubmz over 7 years
    THIS SHOULD BE ADDED TO THE ANSWER! As @phnmnn said - the following line should be set to the grade.build file: proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  • user25
    user25 about 6 years
    you're still trying to call functions and send arguments, don't think it' a good idea, just better to use if (BuildConfig.DEBUG) Log.i(TAG, msg);