Overview
Correctness | |
2 | warning DiscouragedPrivateApi: Using Discouraged Private API |
1 | warning PictureInPictureIssue: Picture In Picture best practices not followed |
2 | warning SelectedPhotoAccess: Behavior change when requesting photo library access |
8 | error RestrictedApi: Restricted API |
1 | error UnsafeOptInUsageError: Unsafe opt-in usage intended to be error-level severity |
Correctness:Messages | |
1 | warning PluralsCandidate: Potential Plurals |
1 | warning StringFormatCount: Formatting argument types incomplete or inconsistent |
Security | |
1 | warning AcceptsUserCertificates: Allowing User Certificates |
1 | warning CustomX509TrustManager: Implements custom TLS trust manager |
1 | warning ExportedService: Exported service does not require permission |
1 | warning InsecureBaseConfiguration: Insecure Base Configuration |
2 | warning WebViewClientOnReceivedSslError: Proceeds with the HTTPS connection despite SSL errors |
1 | warning DataExtractionRules: Missing data extraction rules |
Performance | |
15 | warning NotifyDataSetChanged: Invalidating All RecyclerView Data |
1 | warning ObsoleteSdkInt: Obsolete SDK_INT Version Check |
1 | warning ViewHolder: View Holder Candidates |
1 | warning Overdraw: Overdraw: Painting regions more than once |
62 | warning UnusedResources: Unused resources |
1 | warning UselessParent: Unnecessary parent layout |
1 | warning TooManyViews: Layout has too many views |
Internationalization | |
4 | warning SetTextI18n: TextView Internationalization |
Included Additional Checks (82) | |
Disabled Checks (45) |
Using Discouraged Private API
../../src/main/java/com/nextcloud/talk/account/WebViewLoginActivity.kt:293:
290 override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) { 291 try { 292 val sslCertificate = error.certificate 293 val f: Field = sslCertificate.javaClass.getDeclaredField("mX509Certificate") 294 f.isAccessible = true 295 val cert = f[sslCertificate] as X509Certificate 296 if (cert == null) {../../src/main/java/com/nextcloud/talk/account/WebViewLoginActivity.kt:293:
290 override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) { 291 try { 292 val sslCertificate = error.certificate 293 val f: Field = sslCertificate.javaClass.getDeclaredField("mX509Certificate") 294 f.isAccessible = true 295 val cert = f[sslCertificate] as X509Certificate 296 if (cert == null) {
DiscouragedPrivateApi
Correctness
Warning
Priority 6/10
Picture In Picture best practices not followed
../../src/main/AndroidManifest.xml:83:
80 android:protectionLevel="signature" /> 81 <uses-permission android:name="${applicationId}.${broadcastPermission}" /> 82 83 <application 84 android:name=".application.NextcloudTalkApplication" 85 android:allowBackup="true" 86 android:fullBackupContent="@xml/backup_config"
PictureInPictureIssue
Correctness
Warning
Priority 5/10
Behavior change when requesting photo library access
../../src/main/AndroidManifest.xml:63:
60 <uses-permission 61 android:name="android.permission.READ_EXTERNAL_STORAGE" 62 android:maxSdkVersion="32" /> 63 <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> 64 <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> 65 <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />../../src/main/AndroidManifest.xml:64:
61 android:name="android.permission.READ_EXTERNAL_STORAGE" 62 android:maxSdkVersion="32" /> 63 <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> 64 <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> 65 <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> 66 67 <uses-permission android:name="android.permission.WAKE_LOCK" />
SelectedPhotoAccess
Correctness
Warning
Priority 5/10
Restricted API
../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:69:
66 } 67 68 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemViewHolder { 69 val listItemView: View = parent.inflate(dialog.windowContext, R.layout.menu_item_sheet) 70 val viewHolder = ListItemViewHolder( 71 itemView = listItemView, 72 adapter = this../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:69:
66 } 67 68 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemViewHolder { 69 val listItemView: View = parent.inflate(dialog.windowContext, R.layout.menu_item_sheet) 70 val viewHolder = ListItemViewHolder( 71 itemView = listItemView, 72 adapter = this../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:69:
66 } 67 68 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemViewHolder { 69 val listItemView: View = parent.inflate(dialog.windowContext, R.layout.menu_item_sheet) 70 val viewHolder = ListItemViewHolder( 71 itemView = listItemView, 72 adapter = this../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:69:
66 } 67 68 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemViewHolder { 69 val listItemView: View = parent.inflate(dialog.windowContext, R.layout.menu_item_sheet) 70 val viewHolder = ListItemViewHolder( 71 itemView = listItemView, 72 adapter = this../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:74:
71 itemView = listItemView, 72 adapter = this 73 ) 74 viewHolder.titleView.maybeSetTextColor(dialog.windowContext, R.attr.md_color_content) 75 return viewHolder 76 }../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:74:
71 itemView = listItemView, 72 adapter = this 73 ) 74 viewHolder.titleView.maybeSetTextColor(dialog.windowContext, R.attr.md_color_content) 75 return viewHolder 76 }../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:74:
71 itemView = listItemView, 72 adapter = this 73 ) 74 viewHolder.titleView.maybeSetTextColor(dialog.windowContext, R.attr.md_color_content) 75 return viewHolder 76 }../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:74:
71 itemView = listItemView, 72 adapter = this 73 ) 74 viewHolder.titleView.maybeSetTextColor(dialog.windowContext, R.attr.md_color_content) 75 return viewHolder 76 }
RestrictedApi
Correctness
Error
Priority 4/10
Unsafe opt-in usage intended to be error-level severity
../../src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenMediaActivity.kt:196:
193 private fun applyWindowInsets() { 194 val playerView = binding.playerView 195 val exoControls = playerView.findViewById<FrameLayout>(R.id.exo_bottom_bar) 196 val exoProgress = playerView.findViewById<DefaultTimeBar>(R.id.exo_progress) 197 val progressBottomMargin = exoProgress.marginBottom 198 199 ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets ->
Vendor: Android Open Source Project
Identifier: androidx.annotation.experimental
Feedback: https://issuetracker.google.com/issues/new?component=459778
Identifier: androidx.annotation.experimental
Feedback: https://issuetracker.google.com/issues/new?component=459778
UnsafeOptInUsageError
Correctness
Error
Priority 4/10
Potential Plurals
../../src/main/res/values-b%2Ben%2B001/strings.xml:36:
33 <string name="close_icon">Close Icon</string> 34 <string name="connection_established">Connection established</string> 35 <string name="connection_lost">Connection lost</string> 36 <string name="connection_lost_queued">Connection lost - %1$d are queued</string> 37 <string name="connection_lost_sent_messages_are_queued">Connection lost - Sent messages are queued</string> 38 <string name="continuous_voice_message_recording">Lock recording for continuously recording of the voice message</string> 39 <string name="conversation_is_read_only">Conversation is read only</string>
PluralsCandidate
Messages
Correctness
Warning
Priority 5/10
Formatting argument types incomplete or inconsistent
../../src/main/res/values-ug/strings.xml:513:
510 <string name="nc_upload_from_cloud">%1$s دىن ئورتاقلىشىش</string> 511 <string name="nc_upload_from_device">ئۈسكۈنىدىن يۈكلەش</string> 512 <string name="nc_upload_in_progess">يۈكلەش</string> 513 <string name="nc_upload_notification_text">%1$s دىن%2$s - %3$s \ %%</string> 514 <string name="nc_upload_picture_from_cam">رەسىمگە تارتىڭ</string> 515 <string name="nc_upload_video_from_cam">سىن ئېلىڭ</string> 516 <string name="nc_user">ئىشلەتكۈچى</string>
545 <string name="nc_upload_in_progess">Uploading</string> 546 <string name="nc_upload_from_device">Upload from device</string> 547 548 <string name="nc_upload_notification_text">%1$s to %2$s - %3$s\%%</string> 549 <string name="nc_upload_failed_notification_title">Failure</string> 550 <string name="nc_upload_failed_notification_text">Failed to upload %1$s</string> 551 <string name="nc_file_storage_permission">Permission for file access is required</string>
StringFormatCount
Messages
Correctness
Warning
Priority 5/10
Allowing User Certificates
../../src/main/res/xml/network_security_config.xml:12:
9 <base-config cleartextTrafficPermitted="true"> 10 <trust-anchors> 11 <certificates src="system"/> 12 <certificates src="user"/> 13 </trust-anchors> 14 </base-config> 15 </network-security-config>
AcceptsUserCertificates
Security
Warning
Priority 5/10
Implements custom TLS trust manager
../../src/main/java/com/nextcloud/talk/utils/ssl/TrustManager.java:34:
31 import javax.net.ssl.X509TrustManager; 32 33 34 public class TrustManager implements X509TrustManager { 35 private static final String TAG = "TrustManager"; 36 37 private File keystoreFile;
CustomX509TrustManager
Security
Warning
Priority 5/10
Exported service does not require permission
../../src/main/AndroidManifest.xml:278:
275 <receiver android:name=".receivers.DismissRecordingAvailableReceiver" /> 276 <receiver android:name=".receivers.ShareRecordingToChatReceiver" /> 277 278 <service 279 android:name=".utils.SyncService" 280 android:exported="true"> 281 <intent-filter>
ExportedService
Security
Warning
Priority 5/10
Insecure Base Configuration
../../src/main/res/xml/network_security_config.xml:9:
6 ~ SPDX-License-Identifier: GPL-3.0-or-later 7 --> 8 <network-security-config> 9 <base-config cleartextTrafficPermitted="true"> 10 <trust-anchors> 11 <certificates src="system"/> 12 <certificates src="user"/>
InsecureBaseConfiguration
Security
Warning
Priority 5/10
Proceeds with the HTTPS connection despite SSL errors
../../src/main/java/com/nextcloud/talk/account/WebViewLoginActivity.kt:301:
298 } else { 299 try { 300 trustManager.checkServerTrusted(arrayOf(cert), "generic") 301 handler.proceed() 302 } catch (exception: CertificateException) { 303 eventBus.post(CertificateEvent(cert, trustManager, handler)) 304 }../../src/main/java/com/nextcloud/talk/account/WebViewLoginActivity.kt:301:
298 } else { 299 try { 300 trustManager.checkServerTrusted(arrayOf(cert), "generic") 301 handler.proceed() 302 } catch (exception: CertificateException) { 303 eventBus.post(CertificateEvent(cert, trustManager, handler)) 304 }
WebViewClientOnReceivedSslError
Security
Warning
Priority 5/10
Missing data extraction rules
../../src/main/AndroidManifest.xml:86:
83 <application 84 android:name=".application.NextcloudTalkApplication" 85 android:allowBackup="true" 86 android:fullBackupContent="@xml/backup_config" 87 android:icon="@mipmap/ic_launcher" 88 android:label="@string/nc_app_name" 89 android:largeHeap="true"
DataExtractionRules
Security
Warning
Priority 3/10
Invalidating All RecyclerView Data
../../src/main/java/com/nextcloud/talk/chat/ChatActivity.kt:2573:
2570 } 2571 } 2572 adapter!!.delete(messagesToDelete) 2573 adapter!!.notifyDataSetChanged() 2574 } 2575 }../../src/main/java/com/nextcloud/talk/chat/ChatActivity.kt:2593:
2590 updateReadStatusOfMessage(message, it) 2591 } 2592 } 2593 adapter!!.notifyDataSetChanged() 2594 } 2595 }../../src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt:775:
772 } 773 } 774 } 775 adapter?.notifyDataSetChanged() 776 checkAndHandleDoneMenuItem() 777 }../../src/main/java/com/nextcloud/talk/contacts/ContactsActivity.kt:869:
866 isPublicCall = !isPublicCall 867 enableContactForNonPublicCall() 868 checkAndHandleDoneMenuItem() 869 adapter?.notifyDataSetChanged() 870 } 871 872 private fun enableContactForNonPublicCall() {../../src/main/java/com/nextcloud/talk/bottomsheet/items/ListIconDialogAdapter.kt:108:
105 if (listener != null) { 106 this.selection = listener 107 } 108 this.notifyDataSetChanged() 109 } 110 111 override fun disableItems(indices: IntArray) {+ 10 More Occurrences...
NotifyDataSetChanged
Performance
Warning
Priority 8/10
Obsolete SDK_INT Version Check
ObsoleteSdkInt
Performance
Warning
Priority 6/10
View Holder Candidates
../../src/main/java/com/nextcloud/talk/ui/dialog/DialogBanListFragment.kt:67:
64 } 65 66 override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { 67 val binding = BanItemListBinding.inflate(LayoutInflater.from(context)) 68 binding.banActorName.text = bans[position].bannedDisplayName 69 val time = bans[position].bannedTime!!.toLong() * ONE_SEC 70 binding.banTime.text = DateUtils.formatDateTime(
ViewHolder
Performance
Warning
Priority 5/10
Overdraw: Painting regions more than once
../../src/main/res/layout/activity_account_verification.xml:12:
9 xmlns:tools="http://schemas.android.com/tools" 10 android:layout_width="match_parent" 11 android:layout_height="match_parent" 12 android:background="@color/bg_default" 13 android:keepScreenOn="true"> 14 15 <ProgressBar
Overdraw
Performance
Warning
Priority 3/10
Unused resources
../../src/main/res/drawable/baseline_calendar_month_24.xml:7:
4 ~ SPDX-FileCopyrightText: 2018-2024 Google LLC 5 ~ SPDX-License-Identifier: Apache-2.0 6 --> 7 <vector xmlns:android="http://schemas.android.com/apk/res/android" 8 android:width="24dp" 9 android:height="24dp" 10 android:tint="#000000"../../src/main/res/drawable/baseline_notifications_24.xml:7:
4 ~ SPDX-FileCopyrightText: 2021-2024 Google LLC 5 ~ SPDX-License-Identifier: Apache-2.0 6 --> 7 <vector xmlns:android="http://schemas.android.com/apk/res/android" 8 android:width="24dp" 9 android:height="24dp" 10 android:tint="?attr/colorControlNormal"../../src/main/res/drawable/baseline_report_problem_24.xml:7:
4 ~ SPDX-FileCopyrightText: 2021-2024 Google LLC 5 ~ SPDX-License-Identifier: Apache-2.0 6 --> 7 <vector xmlns:android="http://schemas.android.com/apk/res/android" 8 android:width="24dp" 9 android:height="24dp" 10 android:tint="#000000"../../src/main/res/drawable/baseline_tag_faces_24.xml:8:
5 ~ SPDX-License-Identifier: GPL-3.0-or-later 6 --> 7 8 <vector xmlns:android="http://schemas.android.com/apk/res/android" 9 android:height="24dp" 10 android:tint="#000000" 11 android:viewportHeight="24"../../src/main/res/values/bool.xml:10:
7 --> 8 <resources> 9 <bool name="value_true">true</bool> 10 <bool name="value_false">false</bool> 11 </resources>+ 57 More Occurrences...
UnusedResources
Performance
Warning
Priority 3/10
Unnecessary parent layout
../../src/main/res/layout/call_activity.xml:27:
24 android:layout_height="match_parent" 25 android:orientation="vertical"> 26 27 <RelativeLayout 28 android:id="@+id/conversationRelativeLayout" 29 android:layout_width="match_parent" 30 android:layout_height="0dp"
UselessParent
Performance
Warning
Priority 2/10
Layout has too many views
../../src/main/res/layout/activity_settings.xml:614:
611 android:layout_height="wrap_content" 612 android:text="@string/nc_settings_typing_status_desc"/> 613 614 <com.google.android.material.textview.MaterialTextView 615 android:id="@+id/settings_typing_status_only_with_hpb" 616 android:layout_width="wrap_content" 617 android:layout_height="wrap_content"
TooManyViews
Performance
Warning
Priority 1/10
TextView Internationalization
../../src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt:283:
280 holder.binding.dialogLastMessage.setTypeface(holder.binding.dialogLastMessage.typeface, Typeface.BOLD) 281 holder.binding.dialogUnreadBubble.visibility = View.VISIBLE 282 if (model.unreadMessages < UNREAD_MESSAGES_TRESHOLD) { 283 holder.binding.dialogUnreadBubble.text = model.unreadMessages.toLong().toString() 284 } else { 285 holder.binding.dialogUnreadBubble.setText(R.string.tooManyUnreadMessages) 286 }../../src/main/java/com/nextcloud/talk/adapters/messages/Reaction.kt:139:
136 ): TextView { 137 val reactionAmount = TextView(context) 138 reactionAmount.setTextColor(textColor) 139 reactionAmount.text = amount.toString() 140 reactionAmount.layoutParams = amountParams 141 return reactionAmount 142 }../../src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt:96:
93 val itemBinding = ItemReactionsTabBinding.inflate(layoutInflater) 94 itemBinding.reactionTab.tag = emoji 95 itemBinding.reactionIcon.text = emoji 96 itemBinding.reactionCount.text = amount.toString() 97 tab.customView = itemBinding.root 98 99 binding.emojiReactionsTabs.addTab(tab)../../src/main/java/com/nextcloud/talk/ui/dialog/ShowReactionsDialog.kt:107:
104 val itemBinding = ItemReactionsTabBinding.inflate(layoutInflater) 105 itemBinding.reactionTab.tag = tagAll 106 itemBinding.reactionIcon.text = context.getString(R.string.reactions_tab_all) 107 itemBinding.reactionCount.text = reactionsTotal.toString() 108 tab.customView = itemBinding.root 109 110 binding.emojiReactionsTabs.addTab(tab, 0)
SetTextI18n
Internationalization
Warning
Priority 6/10
Included Additional Checks
This card lists all the extra checks run by lint, provided from libraries,
build configuration and extra flags. This is included to help you verify
whether a particular check is included in analysis when configuring builds.
(Note that the list does not include the hundreds of built-in checks into lint,
only additional ones.)
Disabled Checks
One or more issues were not run by lint, either
because the check is not enabled by default, or because
it was disabled with a command line flag or via one or
more
lint.xml
configuration files in the project directories.
Suppressing Warnings and Errors
Lint errors can be suppressed in a variety of ways:
1. With a
2. With a
3. With a //noinspection comment in the source code
4. With ignore flags specified in the
5. With a
6. With a
7. With the --ignore flag passed to lint.
To suppress a lint warning with an annotation, add a
To suppress a lint warning with a comment, add a
To suppress a lint warning in an XML file, add a
To suppress a lint warning in a
Here we specify a comma separated list of issue id's after the disable command. You can also use
To suppress lint warnings with a configuration XML file, create a file named
The format of the
To suppress lint checks from the command line, pass the --ignore flag with a comma separated list of ids to be suppressed, such as:
For more information, see https://developer.android.com/studio/write/lint.html#config
1. With a
@SuppressLint
annotation in the Java code2. With a
tools:ignore
attribute in the XML file3. With a //noinspection comment in the source code
4. With ignore flags specified in the
build.gradle
file, as explained below5. With a
lint.xml
configuration file in the project6. With a
lint.xml
configuration file passed to lint via the --config flag7. With the --ignore flag passed to lint.
To suppress a lint warning with an annotation, add a
@SuppressLint("id")
annotation on the class, method or variable declaration closest to the warning instance you want to disable. The id can be one or more issue id's, such as "UnusedResources"
or {"UnusedResources","UnusedIds"}
, or it can be "all"
to suppress all lint warnings in the given scope.To suppress a lint warning with a comment, add a
//noinspection id
comment on the line before the statement with the error.To suppress a lint warning in an XML file, add a
tools:ignore="id"
attribute on the element containing the error, or one of its surrounding elements. You also need to define the namespace for the tools prefix on the root element in your document, next to the xmlns:android
declaration:xmlns:tools="http://schemas.android.com/tools"
To suppress a lint warning in a
build.gradle
file, add a section like this:android { lintOptions { disable 'TypographyFractions','TypographyQuotes' } }
Here we specify a comma separated list of issue id's after the disable command. You can also use
warning
or error
instead of disable
to change the severity of issues.To suppress lint warnings with a configuration XML file, create a file named
lint.xml
and place it at the root directory of the module in which it applies.The format of the
lint.xml
file is something like the following:<?xml version="1.0" encoding="UTF-8"?> <lint> <!-- Ignore everything in the test source set --> <issue id="all"> <ignore path="\*/test/\*" /> </issue> <!-- Disable this given check in this project --> <issue id="IconMissingDensityFolder" severity="ignore" /> <!-- Ignore the ObsoleteLayoutParam issue in the given files --> <issue id="ObsoleteLayoutParam"> <ignore path="res/layout/activation.xml" /> <ignore path="res/layout-xlarge/activation.xml" /> <ignore regexp="(foo|bar)\.java" /> </issue> <!-- Ignore the UselessLeaf issue in the given file --> <issue id="UselessLeaf"> <ignore path="res/layout/main.xml" /> </issue> <!-- Change the severity of hardcoded strings to "error" --> <issue id="HardcodedText" severity="error" /> </lint>
To suppress lint checks from the command line, pass the --ignore flag with a comma separated list of ids to be suppressed, such as:
$ lint --ignore UnusedResources,UselessLeaf /my/project/path
For more information, see https://developer.android.com/studio/write/lint.html#config