29

I use a version switch to support older Android versions.

int sdk = Build.VERSION.SDK_INT;
if (sdk < Build.VERSION_CODES.HONEYCOMB) {
    ColorDrawable colorDrawable = new ColorDrawable(shapeColor);
    //noinspection deprecation
    viewHolder.shape.setBackgroundDrawable(colorDrawable);
} else {
    viewHolder.shape.setColor(shapeColor);
}

When build the project with Gradle from the command line the following warning is output by Lint:

app/src/main/java/com/example/MyApp/CustomListAdapter.java:92: warning: 
[deprecation] setBackgroundDrawable(Drawable) in View has been deprecated
            viewHolder.shape.setBackgroundDrawable(colorDrawable);
                            ^

Can I annotate the specific line or method to mute the warning (since I do it on purpose)? I do not want to disable all warnings.

JJD
  • 50,076
  • 60
  • 203
  • 339
  • Are you using Android Studio? – MrEngineer13 Jun 13 '14 at 15:03
  • @MrEngineer13 Yes. But here I am building from the command line via `./gradlew clean assembleDebug assembleRelease`. – JJD Jun 13 '14 at 15:05
  • What happens when you place your cursor on viewHolder.shape.setBackgroundDrawable(colorDrawable); and press Alt+Enter? – MrEngineer13 Jun 13 '14 at 15:06
  • @JJD Unrelated but a little tip: `./gradlew aD` – OrhanC1 Jun 13 '14 at 15:07
  • @MrEngineer13 I annotated the deprecated version in code already. This is a Lint warning. - OrhanC1: Thanks, I knew the shortcut. Wanted to be explicit here. – JJD Jun 13 '14 at 15:09
  • Have you tried adding `lintOptions { abortOnError false }` to your build.gradle? – MrEngineer13 Jun 13 '14 at 15:22
  • Did you happen to see my edited answer? I think it covers what you were asking. – bestdayever Jun 13 '14 at 16:04
  • 3
    "//noinspection" seems to be an IntelliJ way of ignoring warnings (Android Studio is based on IntelliJ). Looks like an inconsistency in the Android SDK - the IDE offering to use this //noinspection thing (when you press alt-enter) but the build system ignores it. I filed https://code.google.com/p/android/issues/detail?id=73475 – aleb Jul 11 '14 at 19:01
  • 3
    @aleb's bug report was closed as "WorksAsIntended", saying that //noinspection is supposed to be IDE-specific and isn't supposed to affect command-line operations such as gradle builds. However, the documentation doesn't make that distinction, so I filed a documentation issue: https://code.google.com/p/android/issues/detail?id=204142&thanks=204142&ts=1458158680 – LarsH Mar 16 '16 at 20:09
  • @LarsH What exactly do you suggest using? I tried adding `@SuppressLint("deprecation")` to the method - still Gradle reports a warning. – JJD Mar 17 '16 at 09:12
  • @JJD: Sorry, I don't know. I would expect that to work. Did you try user1's suggestion, `@SuppressWarnings("deprecation")`? – LarsH Mar 17 '16 at 13:37
  • @LarsH Gradle still outputs the warning with `java.lang.SuppressWarnings`. – JJD Mar 17 '16 at 23:34

8 Answers8

18

Case is important, use the following either inline or class-wide:

@Suppress("DEPRECATION")

This is in Kotlin.

Codeversed
  • 9,287
  • 3
  • 43
  • 42
13

I've noticed that the @SuppressLint("deprecated") inline annotation won't be picked up anymore - while @SuppressWarnings("deprecation") is being picked up.

one can disable the Deprecation checks for the Gradle linter with lintOptions within the module-level build.gradle file; while there is no chance to define individual files like that:

android {
    lintOptions {
        disable 'Deprecation'
    }
}

or on can assign one rather detailed lint.xml configuration file with LintOptions:lintConfig (when settings showAll true, it will still show the warnings - no matter the provided XML configuration):

android {
    lintOptions {
        lintConfig file("lint.xml")
        showAll false
    }
}

where one can add individual files, by adding their paths:

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="Deprecation" severity="Error">
        <ignore path="app/src/main/java/com/example/MyApp/CustomListAdapter.java" />
    </issue>
</lint>

The source code of com.android.builder.model.LintOptions might explain, what actually happens there (and confirms about 50% of what I've wrote).

in order to get rid of the inline warnings in Android Studio... that linter appears to be another linter - and these annotations do not affect the linter of the Gradle build (it may be required to use this combined with one of the methods stated above, in order to ignore known deprecated classes and methods):

//noinspection deprecation

update The Android Studio 2.3 release notes mention a new feature:

Lint Baseline: With Android Studio 2.3, you can set unresolved lint warnings as a baseline in your project. From that point forward, Lint will report only new issues. This is helpful if you have many legacy lint issues in your app, but just want to focus on fixing new issues. Learn more about Lint baseline and the new Lint checks & annotations added in this release.

here it's explained, how to create a Lint warnings baseline - which records the detected warnings into an XML file and then mutes them (which is way better than to have the code annotations inline, distributed all over the place); I'd assume, that options lintConfig and baseline should be combine-able (depending on the requirements).

android {
    lintOptions {
        baseline file("lint-baseline.xml")
    }
}
Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • 1
    I do **not** want to disable **all** warnings. – JJD Mar 06 '17 at 18:53
  • @JJD explained it better now; basically one has to configure two linters (the one of Android Studio, which lints live - and the one of Gradle, which lints at build time) - in order to mute all warnings which are not of interest. – Martin Zeitler Mar 10 '17 at 10:15
  • When I place your `lint.xml` (with my class path) in the root folder of the project then **Gradle still notifies** me that the class "uses or overrides a deprecated API" when execute a build on the command line. Further, excluding the whole class is a bit too much since I only want to **silent the deprecation for a single line or function**. – JJD Mar 10 '17 at 14:31
  • could only imagine, that the `lint.xml` is not being referred in the `lintOptions` of the `build.gradle` ...and therefore might not be obeyed by the linter. – Martin Zeitler Mar 11 '17 at 12:46
  • @JDD have a look at the updated answer; also https://www.jetbrains.com/help/idea/2016.1/specify-inspection-scope-dialog.html appears relevant, for the live code-inspection. – Martin Zeitler Mar 13 '17 at 22:14
  • Thanks for the update, I saw the announcement, too. Looks really interesting. I forgot to mention that you can compile the project yourself. It is [open source](https://github.com/johnjohndoe/Umweltzone). All you want to do is to **disable** these [compiler arguments](https://github.com/johnjohndoe/Umweltzone/blob/master/Umweltzone/build.gradle#L40) **temporarily** to see the notice in the shell when you compile with Gradle. – JJD Mar 15 '17 at 22:34
7

Just something new: Not sure about Android Studio, but, to remove this warning from this line, you can use:

//noinspection deprecation

This removes the warning from the next line. E.g:

//noinspection deprecation
e.setBackgroundDrawable(editTextDrawable);

It won't show an error. However, as @JJD said, this still outputs the warning to the console. But at least you can have a nice error-less code which can be useful like for Git for example. And, this prevents the problem with @SupressWarnings, which is it ignores all warnings in the method. So if you have something deprecated that you are not aware of, @SupressWarnings will hide it and you will not be warned. That is the advantage of the //noinspection

Ali Bdeir
  • 4,151
  • 10
  • 57
  • 117
6

I ran into a similar problem. First I got a compiler warning:

:compileDebugJava
Note: /path/file.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

Which you can suppress with @SuppressWarnings("deprecation") or just ignore since it is a warning and does cause your build to fail. Additionally I got the lint error (details in build/lint-results.html):

Call requires API level 13 (current min is 9)

This could be suppressed by adding @SuppressLint("NewApi"). Alternatively you could use @TargetApi(13) to hint that the method/class may use methods that depend on API version 13, rather than what you have set as minSdkVersion (e.g. 9).

The annotations can only be done at a class or function level, not for a single line. Also note that "deprecation" should not be capitalized, while that didn't seem to matter for "NewApi".

user1
  • 536
  • 5
  • 8
3

To avoid lint warnings, always split functions so one function deals with the old system and other one deals with the new system. The old can supress the warning safely. The new one should be annotated to be used only on newest api levels.

This is an example on how it should look:

    @SuppressWarnings("deprecation")
    private static int getVersionCode_old(@NonNull Context appContext) {
        PackageInfo pInfo;
        try {
            pInfo = appContext.getPackageManager().getPackageInfo(appContext.getPackageName(), 0);
            return pInfo.versionCode;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.P)
    private static int getVersionCode_new(@NonNull Context appContext) {
        PackageInfo pInfo ;
        try {
            pInfo = appContext.getPackageManager().getPackageInfo(appContext.getPackageName(), 0);
            return (int) pInfo.getLongVersionCode();
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    public static int getVersionCodeUniversal(@NonNull Context appContext)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            return getVersionCode_new(appContext);
        }
        else
        {
            return getVersionCode_old(appContext);
        }
    }

Another important hint to avoid lint warnings: if you are using a whole deprecated class then you should remove all explicit imports for that class. Then just access to that class directly using its full path, and only do it in the old versions of your functions.

And finally, you should consider start using androidX, the new Google libraries where you will find a lot of universal functions ready to use. Then you can save a lot of time with this kind of small problems. For example, you can remove all the code of the above example and simply use this new and universal androidX function:

    PackageInfo.getLongVersionCode()
Blackd
  • 833
  • 6
  • 10
2

You need to create a lint.xml file to tell lint what to ignore.

http://tools.android.com/tips/lint/suppressing-lint-warnings see this for more details

yours might look a little like this

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <!-- Disable the given check in this project -->
    <issue id="Deprecation">
        <ignore path="app/src/main/java/com/example/MyApp/CustomListAdapter.java" />
    </issue>
</lint>

To handle this in the source you should use something like

 @SuppressLint("Deprecation")
bestdayever
  • 154
  • 6
  • 2
    I do not want to disable all deprecation warnings. I would prefer to add a Lint annotation to the specific line in the code. – JJD Jun 13 '14 at 15:28
  • The link covers that. @SuppressLint("Deprecation") inline. – bestdayever Jun 13 '14 at 15:36
  • 2
    I tried `//noinspection AndroidLintDeprecation` as suggested in the documentation but the warning still appears. I am not sure what is meant by **id**. The `lintId` is extracted as can be seen [here](https://android.googlesource.com/platform/tools/adt/idea/+/jb-mr2-dev/android/src/org/jetbrains/android/inspections/lint/SuppressLintIntentionAction.java), line 169. - `@SuppressLint("Deprecation")` can only be set on method level if I understand correctly. – JJD Jun 13 '14 at 16:13
  • 2
    Wouldn't the easiest solution be to break out that if statement into a separate method that is marked with the suppress lint annotation? – bestdayever Jun 13 '14 at 16:21
  • Thought about it - line annotation would be nice anyways :-} – JJD Jun 13 '14 at 16:26
  • 1
    You mean `//noinspection deprecation`? But apart from this the Gradle still outputs the warning to the console. – JJD Jun 13 '14 at 16:50
  • //noinspection AndroidLintDeprecation I tried this on a test project and it worked fine. I would imagine you are having problems with out of date tools or something. – bestdayever Jun 13 '14 at 16:53
  • It does not work for [this project](https://bitbucket.org/tbsprs/umweltzone). Tools are almost up-to-date (work in progress) – JJD Jun 13 '14 at 18:44
  • JJD is right - as of today with the latest tools and IDE updates, `//noinspection` fails to disable lint warnings for the build system. The issue tracker at https://code.google.com/p/android/issues/detail?id=73475 says this is by design, but the documentation at http://tools.android.com/tips/lint/suppressing-lint-warnings fails to mention that important difference between `//noinspection` and `@SuppressLint()`. – LarsH Mar 16 '16 at 19:43
  • FYI, I filed a bug report about the documentation: https://code.google.com/p/android/issues/detail?id=204142&thanks=204142&ts=1458158680 – LarsH Mar 16 '16 at 20:07
0

Just use @SuppressWarnings("deprecation") above the function to suppress that specific warning for that function only.

Works like a charm!

@Blackd has the better answer. You should accept that!

0

Try to find a method from ViewCompat to replace the deprecated method.

In your case, use ViewCompat.setBackground(View, Drawable).

There are many classes named XXXCompat for cases like that, such as ContextCompat, ActivityCompat and so on.

hqzxzwb
  • 4,661
  • 2
  • 14
  • 15