### Lint Warning Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/LocalContextConfigurationRead.md.html Shows examples of lint warnings for reading configuration using LocalContext.current.resources.configuration. ```text src/test/test.kt:11:Error: Reading Configuration using LocalContext.current.resources.configuration [LocalContextConfigurationRead] LocalContext.current.resources.configuration -------------------------------------------- src/test/test.kt:12:Error: Reading Configuration using LocalContext.current.resources.configuration [LocalContextConfigurationRead] LocalContext.current.getResources().getConfiguration() ------------------------------------------------------ ``` -------------------------------- ### Basic Lint Rule Implementation Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/IdleBatteryChargingConstraints.md.html Example of a simple custom lint rule that checks for a specific pattern. Requires setup in a separate module. ```java package com.example.lint; import com.android.tools.lint.client.api.IssueRegistry; import com.android.tools.lint.detector.api.Issue; import com.android.tools.lint.detector.api.Severity; public class MyIssueRegistry extends IssueRegistry { @Override public Issue[] getIssues() { return new Issue[] { MyCustomIssue.ISSUE }; } } class MyCustomIssue { static final Issue ISSUE = Issue.create( "MyCustomRule", // ID "Avoid using hardcoded strings", // Title "Hardcoding strings is discouraged. Use string resources instead.", // Message Category.I18N, // Category 6, // Priority Severity.WARNING, // Severity new Implementation(MyDetector.class, Scope.RESOURCE_FILE_SCOPE)); } import com.android.tools.lint.detector.api.Detector; import com.android.tools.lint.detector.api.JavaContext; import com.android.tools.lint.detector.api.XmlContext; import com.android.tools.lint.detector.api.TextRange; import com.android.tools.lint.detector.api.Location; import com.android.resources.ResourceFolderType; import org.jetbrains.uast.UElement; import org.jetbrains.uast.UStringLiteral; public class MyDetector extends Detector implements Detector.UastScanner { @Override public void visitLiteralExpression(JavaContext context, UStringLiteral literal) { if (literal.getValue().startsWith("Hardcoded")) { context.report(MyCustomIssue.ISSUE, literal, context.getLocation(literal), "This is a hardcoded string."); } } } ``` -------------------------------- ### Kotlin Lint Detector Test Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/LintImplUnexpectedDomain.md.html Demonstrates how to write a unit test for a custom Kotlin lint detector using LintDetectorTest. Requires setup with lint().files().run().expect(). ```kotlin package test.pkg import com.android.tools.lint.checks.infrastructure.LintDetectorTest import com.android.tools.lint.detector.api.Detector class MyKotlinLintDetectorTest : LintDetectorTest() { override fun getDetector(): Detector { return MyKotlinLintDetector() } fun testBasic() { val expected = """ src/test/pkg/AlarmTest.java:9: Warning: Value will be forced up to 5000 as of Android 5.1; don't rely on this to be exact [ShortAlarm] alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR ~~ 0 errors, 1 warnings """.trimIndent() lint().files( kotlin( """ fun test() { println("Value=${'$'}") } """.trimIndent() ), java( "src/test/pkg/AlarmTest.java", """ package test.pkg; import android.app.AlarmManager; @SuppressWarnings("ClassNameDiffersFromFileName") public class AlarmTest { public void test(AlarmManager alarmManager) { alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, 60000, null); // OK alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 6000, 70000, null); // OK alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 50, 10, null); // ERROR alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR OtherClass.MY_INTERVAL, null); // ERROR } private static class OtherClass { public static final long MY_INTERVAL = 1000L; } } """ ) ).run().expect(expected) } } ``` -------------------------------- ### Kotlin AST Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/api-guide.html A simple Kotlin program equivalent to the Java example, used to illustrate AST representation. ```kotlin // MyTest.kt package test.pkg class MyTest { val s: String = "hello" } ``` -------------------------------- ### Example of ComposeNamingLowercase lint warning Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/ComposeNamingLowercase.md.html This example shows a typical lint warning generated when a composable function that returns a value starts with an uppercase letter. ```text src/test.kt:4:Error: Composable functions that return a value should start with a lowercase letter.While useful and accepted outside of @Composable functions, this factory function convention has drawbacks that set inappropriate expectations for callers when used with @Composable functions.See https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly for more information. [ComposeNamingLowercase] fun MyComposable(): Something { } ``` ```kotlin import androidx.compose.runtime.Composable @Composable fun MyComposable(): Something { } ``` -------------------------------- ### Gradle Build File Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/GradleDynamicVersion.md.html This is a sample Gradle build file demonstrating the usage of dependencies, including a dynamic version for 'appcompat-v7'. ```groovy apply plugin: 'android' android { compileSdkVersion buildToolsVersion buildToolsVersion "19.0.0" defaultConfig { minSdkVersion 7 targetSdkVersion 17 versionCode 1 versionName "1.0" } productFlavors { free { } pro { } } } dependencies { compile 'com.android.support:appcompat-v7:+' freeCompile 'com.google.guava:guava:11.0.2' compile 'com.android.support:appcompat-v7:13.0.0' compile 'com.google.android.support:wearable:1.2.0' compile 'com.android.support:multidex:1.0.0' androidTestCompile 'com.android.support.test:runner:0.3' } ``` -------------------------------- ### Example Lint Warnings for Uppercase Naming Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/ComposeNamingUppercase.md.html These examples show the errors generated by the ComposeNamingUppercase lint rule when composable functions do not start with an uppercase letter. ```text src/test.kt:4:Error: Composable functions that return Unit should start with an uppercase letter.They are considered declarative entities that can be either present or absent in a composition and therefore follow the naming rules for classes.See https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly for more information. [ComposeNamingUppercase] fun myComposable() { } ------------ src/test.kt:7:Error: Composable functions that return Unit should start with an uppercase letter.They are considered declarative entities that can be either present or absent in a composition and therefore follow the naming rules for classes.See https://slackhq.github.io/compose-lints/rules/#naming-composable-functions-properly for more information. [ComposeNamingUppercase] fun myComposable(): Unit { } ------------ ``` -------------------------------- ### Add Startup Runtime Dependency with Version Catalogs (build.gradle.kts) Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/androidx_startup_startup-runtime.md.html Integrate the startup-runtime library using Gradle version catalogs for better dependency management. Define the version and library in your libs.versions.toml file. ```kotlin implementation(libs.startup.runtime) ``` -------------------------------- ### Base String Resource Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/StringFormatCount.md.html This is the base string resource file defining the 'hello' string with two formatting arguments. Ensure all translated strings match this argument count. ```xml Hello %1$s, %2$s? ``` -------------------------------- ### Example of Wrong Layout Name Warning Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/WrongLayoutName.md.html This example shows the output of the WrongLayoutName lint check, indicating a warning for a layout file that does not start with a required prefix. ```text res/layout/random.xml:Warning: Layout does not start with one of the following prefixes: activity_, view_, fragment_, dialog_, bottom_sheet_, adapter_item_, divider_, space_, popup_window_ [WrongLayoutName] 0 errors, 1 warnings ``` -------------------------------- ### AppCompat Method Lint Warnings Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/AppCompatMethod.md.html Examples of warnings generated by the AppCompatMethod lint check for incorrect method calls. ```text src/test/pkg/AppCompatTest.java:5:Warning: Should use getSupportActionBar instead of getActionBar name [AppCompatMethod] getActionBar(); // ERROR -------------- ``` ```text src/test/pkg/AppCompatTest.java:8:Warning: Should use startSupportActionMode instead of startActionMode name [AppCompatMethod] startActionMode(null); // ERROR ``` ```text src/test/pkg/AppCompatTest.java:11:Warning: Should use supportRequestWindowFeature instead of requestWindowFeature name [AppCompatMethod] requestWindowFeature(0); // ERROR ``` ```text src/test/pkg/AppCompatTest.java:14:Warning: Should use setSupportProgressBarVisibility instead of setProgressBarVisibility name [AppCompatMethod] setProgressBarVisibility(true); // ERROR ``` ```text src/test/pkg/AppCompatTest.java:15:Warning: Should use setSupportProgressBarIndeterminate instead of setProgressBarIndeterminate name [AppCompatMethod] setProgressBarIndeterminate(true); // ERROR ``` ```text src/test/pkg/AppCompatTest.java:16:Warning: Should use setSupportProgressBarIndeterminateVisibility instead of setProgressBarIndeterminateVisibility name [AppCompatMethod] setProgressBarIndeterminateVisibility(true); // ERROR ``` -------------------------------- ### Example Layout File Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/MissingDefaultResource.md.html An example of a land-specific layout file using the merge tag. This file is part of the lint rule tests. ```xml ``` -------------------------------- ### Source File with Instant App Call Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/InstantAppCall.md.html The source file `src/com/example/app/MyApp.kt` demonstrating the usage of `InstantApps.showInstallPrompt`, which triggers the InstantAppCall lint warning. ```kotlin package com.example.app import android.app.Activity import com.google.android.gms.instantapps.InstantApps class MyApp { fun go(activity: Activity) { InstantApps.showInstallPrompt(activity, null, 0, null) } } ``` -------------------------------- ### Example of SuperfluousMarginDeclaration Warning Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/SuperfluousMarginDeclaration.md.html This example shows how the lint warning appears in the IDE, indicating that `layout_margin` should be used instead of individual start, end, top, and bottom margins. ```text res/layout/ids.xml:1:Warning: Should be using layout_margin instead. [SuperfluousMarginDeclaration] ``` -------------------------------- ### XML Resource Violation Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/ResourceName.md.html This example shows a layout XML file where the resource name 'activity_main' does not start with the configured project resource prefix 'unit_test_prefix_'. The lint check flags this as an error. ```xml ``` -------------------------------- ### Base Resource Definitions (strings.xml) Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/DuplicateDefinition.md.html This XML file contains the initial definitions for various strings, including 'wallpaper_instructions'. Ensure resources are not duplicated within the same folder. ```xml Home Sample All Wallpaper Search Settings Ignore Me Tap picture to set portrait wallpaper ``` -------------------------------- ### Alternatives Quick Fix Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/api-guide.html Create an alternatives fix to offer users multiple distinct options for resolving an issue. This example provides choices for setting a content description attribute. ```kotlin val fix = fix().alternatives( fix().set().todo(ANDROID_URI, "text").build(), fix().set().todo(ANDROID_URI, "contentDescription") .build()) ``` -------------------------------- ### Example of Invalid Navigation XML Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/InvalidNavigation.md.html This XML snippet demonstrates a navigation graph with an invalid start destination, triggering the InvalidNavigation lint warning. Ensure the start destination is a direct child of the navigation element. ```xml ``` -------------------------------- ### Example of UnlocalizedSms Lint Warning Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/UnlocalizedSms.md.html This example shows a lint warning generated when an SMS destination number does not start with a country code. It suggests prefixing with '+' and a country code or restricting usage to a specific country. ```text src/test/pkg/NonInternationalizedSmsDetectorTest.java:18:Warning: To make sure the SMS can be sent by all users, please start the SMS number with a + and a country code or restrict the code invocation to people in the country you are targeting [UnlocalizedSms] sms.sendMultipartTextMessage("001234567890", null, null, null, null); -------------- ``` -------------------------------- ### Create Quickfix with Alternatives Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/api-guide/quickfixes.md.html Use 'alternatives' to offer the user multiple distinct quickfix options. This is useful when a problem can be solved in several ways. ```kotlin val fix = fix().alternatives( fix().set().todo(ANDROID_URI, "text").build(), fix().set().todo(ANDROID_URI, "contentDescription") \ .build()) ``` -------------------------------- ### Example build.gradle File with Deprecated Configurations Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/GradleDeprecatedConfiguration.md.html A sample build.gradle file demonstrating the use of deprecated configurations 'compile' and 'debugCompile'. ```groovy buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.0.0' } } apply plugin: 'com.android.library' dependencies { compile 'androidx.appcompat:appcompat:1.0.0' debugCompile 'androidx.appcompat:appcompat:1.0.0' } ``` -------------------------------- ### Example of CompositionLocal getters flagged as errors Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/ComposeCompositionLocalGetter.md.html This example demonstrates how the lint check identifies CompositionLocals defined with getters. It shows two cases: one using `get()` and another using a block body for the getter, both of which are flagged. ```text src/test.kt:2:Error: `CompositionLocal`s should be singletons and not use getters. Otherwise a new instance will be returned every call. [ComposeCompositionLocalGetter] val LocalBanana get() = compositionLocalOf { "Prune" } src/test.kt:3:Error: `CompositionLocal`s should be singletons and not use getters. Otherwise a new instance will be returned every call. [ComposeCompositionLocalGetter] val LocalPotato get() { ``` -------------------------------- ### Gradle Build File Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/UseTomlInstead.md.html This Gradle build file demonstrates the correct way to declare dependencies using the TOML version catalog. ```groovy dependencies { implementation(libs.androidx.appCompat) // OK implementation 'androidx.appcompat:appcompat:1.5.1' } ``` -------------------------------- ### ModifierFactoryUnreferencedReceiver Lint Error Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/ModifierFactoryUnreferencedReceiver.md.html This example shows the lint warning produced when a Modifier factory function does not use the receiver Modifier instance. Ensure the returned chain includes 'this' or starts with an implicit call to another factory function. ```kotlin src/androidx/compose/ui/foo/TestModifier.kt:8:Error: Modifier factory functions must use the receiver Modifier instance [ModifierFactoryUnreferencedReceiver] fun Modifier.fooModifier(): Modifier.Element { ----------- ``` -------------------------------- ### Groovy Build Script Example for TargetSdkVersion Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/ExpiringTargetSdkVersion.md.html An example of a `build.gradle` file demonstrating how `targetSdkVersion` is set. It includes comments indicating compliance with current and future requirements. ```groovy apply plugin: 'com.android.application' android { defaultConfig { // Already meeting last year's requirement but not this year's requirement targetSdkVersion 31 targetSdkVersion 2023 // OK targetSdkVersion 2024 // OK } } ``` -------------------------------- ### LintFix for Creating and Deleting Files Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/api-guide.html Quickfixes can now create and delete new files using `LintFix#newFile` and `LintFix#deleteFile`. ```java LintFix.newFile(filePath, content).build() LintFix.deleteFile(filePath).build() ``` -------------------------------- ### Lint Error Example: Use Require Instead of Get Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/UseRequireInsteadOfGet.md.html Illustrates common lint warnings for using 'checkNotNull(fragment.get())' instead of the preferred 'fragment.require()' methods. ```java checkNotNull(fragment.getArguments()); ``` ```java checkNotNull(fragment.getFragmentManager()); ``` ```java checkNotNull(fragment.getContext()); ``` ```java checkNotNull(fragment.getActivity()); ``` ```java checkNotNull(fragment.getHost()); ``` ```java checkNotNull(fragment.getParentFragment()); ``` ```java checkNotNull(fragment.getView()); ``` -------------------------------- ### Correct Java Bean property accessors Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/KotlinPropertyAccess.md.html Examples of correctly named Java Bean accessor methods that can be accessed as properties in Kotlin. Includes 'get' and 'is' prefixes. ```java public void setOk1(String s) { } public String getOk1() { return ""; } ``` ```java public void setOk2(String s) { } public String isOk2() { return ""; } public String getOk2() { return ""; } ``` -------------------------------- ### Full Source File Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/RetainLeaksContext.md.html This is the complete source file demonstrating the usage of `retain` with a `Context`, which triggers the `RetainLeaksContext` lint warning. ```kotlin package androidx.compose.runtime.foo import android.app.Activity import android.content.Context import android.content.ContextWrapper import android.view.View import android.view.TextView import androidx.compose.runtime.Composable import androidx.compose.runtime.retain.retain @Composable fun Test(context: Context) { val foo = retain { context } } ``` -------------------------------- ### Read Option Value from Context Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/api-guide/options.md.html Retrieve the configured value of an option within the lint analysis context. This example shows how to get the integer value for the `MAX_COUNT` option. ```kotlin val maxCount = MAX_COUNT.getValue(context) ``` -------------------------------- ### Version Catalog TOML File Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/SimilarGradleDependency.md.html An example of a Gradle version catalog file (`libs.versions.toml`) that demonstrates the declaration of multiple versions for the 'joda-time:joda-time' dependency. ```toml [versions] jodaVersion = "2.1" dagger="1.2.0" [libraries] joda_library = { module = "joda-time:joda-time", version.ref = "jodaVersion"} joda_library2 = { module = "joda-time:joda-time", version = "2.0" } dagger-lib = { group = "com.squareup.dagger", name ="dagger", version.ref = "dagger" } ``` -------------------------------- ### build.gradle.kts Configuration Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/MinSdkTooLow.md.html This snippet shows a typical build.gradle.kts file configuration where the minSdkVersion is set using version catalog references. ```kotlin android { compileSdk = libs.versions.compile.sdk.version.get().toInt() // ERROR 12 compileSdk = libs.versions.keys.csv.get().toInt() // ERROR 13 defaultConfig { minSdk = libs.versions.keys.msv.get().toInt() // ERROR 14 targetSdk = libs.versions.keys.tsv.get().toInt() // ERROR 15 } } ``` -------------------------------- ### Example of Navigation XML with Included Graph Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/InvalidNavigation.md.html This XML snippet shows an included navigation graph. The lint check analyzes these structures to ensure valid start destinations are defined. ```xml ``` -------------------------------- ### Layout with RTL Attributes Example Source: https://github.com/googlesamples/android-custom-lint-rules/blob/main/docs/checks/RtlEnabled.md.html This layout file demonstrates the use of RTL attributes like `layout_gravity="left"` and `gravity="right"` which trigger the lint warning if RTL support is not enabled in the manifest. It also shows examples of correct usage with `start` and `end` attributes, and how to suppress the warning. ```xml