From 8a11fc9c4a02aa4b5e25a4006d184a442a2e91b1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 17 Nov 2021 10:30:43 +0100 Subject: [PATCH] Minor changes to fix code inspector warnings --- .../call/fragments/StatusFragment.kt | 4 +- .../call/viewmodels/ControlsViewModel.kt | 34 ++-- .../main/chat/ChatScrollListener.kt | 2 +- .../main/chat/data/ChatMessageContentData.kt | 10 +- .../main/chat/data/ChatMessageData.kt | 2 +- .../viewmodels/ChatMessageSendingViewModel.kt | 6 +- .../main/chat/viewmodels/ChatRoomViewModel.kt | 4 +- .../chat/viewmodels/ChatRoomsListViewModel.kt | 4 +- .../viewmodels/AdvancedSettingsViewModel.kt | 4 +- .../main/viewmodels/StatusViewModel.kt | 2 +- .../compatibility/Api21Compatibility.kt | 5 + .../compatibility/Api31Compatibility.kt | 32 ++++ .../linphone/compatibility/Compatibility.kt | 7 + .../linphone/contact/AsyncContactsLoader.kt | 10 +- .../main/java/org/linphone/contact/Contact.kt | 4 +- .../org/linphone/contact/ContactsManager.kt | 12 +- .../org/linphone/contact/NativeContact.kt | 165 +++++++++--------- .../linphone/contact/NativeContactEditor.kt | 29 ++- .../java/org/linphone/core/CoreContext.kt | 2 +- .../notifications/NotificationsManager.kt | 4 +- .../main/java/org/linphone/utils/FileUtils.kt | 10 +- .../linphone/views/VoiceRecordProgressBar.kt | 22 +-- .../main/res/layout/chat_bubble_activity.xml | 1 + .../res/layout/chat_room_detail_fragment.xml | 1 + .../res/layout/settings_advanced_fragment.xml | 3 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 3 +- app/src/main/res/values/strings.xml | 1 + 28 files changed, 230 insertions(+), 155 deletions(-) create mode 100644 app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt diff --git a/app/src/main/java/org/linphone/activities/call/fragments/StatusFragment.kt b/app/src/main/java/org/linphone/activities/call/fragments/StatusFragment.kt index 0213bb9cf..5c2a4a41a 100644 --- a/app/src/main/java/org/linphone/activities/call/fragments/StatusFragment.kt +++ b/app/src/main/java/org/linphone/activities/call/fragments/StatusFragment.kt @@ -114,8 +114,8 @@ class StatusFragment : GenericFragment() { val viewModel = DialogViewModel(getString(R.string.zrtp_dialog_message), getString(R.string.zrtp_dialog_title)) viewModel.showZrtp = true - viewModel.zrtpReadSas = toRead.toUpperCase(Locale.getDefault()) - viewModel.zrtpListenSas = toListen.toUpperCase(Locale.getDefault()) + viewModel.zrtpReadSas = toRead.uppercase(Locale.getDefault()) + viewModel.zrtpListenSas = toListen.uppercase(Locale.getDefault()) viewModel.showIcon = true viewModel.iconResource = R.drawable.security_2_indicator diff --git a/app/src/main/java/org/linphone/activities/call/viewmodels/ControlsViewModel.kt b/app/src/main/java/org/linphone/activities/call/viewmodels/ControlsViewModel.kt index 33d7aac80..96d597b64 100644 --- a/app/src/main/java/org/linphone/activities/call/viewmodels/ControlsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/call/viewmodels/ControlsViewModel.kt @@ -342,23 +342,27 @@ class ControlsViewModel : ViewModel() { val currentCall = core.currentCall val conference = core.conference - if (currentCall != null) { - if (currentCall.isRecording) { - currentCall.stopRecording() - } else { - currentCall.startRecording() + when { + currentCall != null -> { + if (currentCall.isRecording) { + currentCall.stopRecording() + } else { + currentCall.startRecording() + } + isRecording.value = currentCall.isRecording } - isRecording.value = currentCall.isRecording - } else if (conference != null) { - val path = LinphoneUtils.getRecordingFilePathForConference() - if (conference.isRecording) { - conference.stopRecording() - } else { - conference.startRecording(path) + conference != null -> { + val path = LinphoneUtils.getRecordingFilePathForConference() + if (conference.isRecording) { + conference.stopRecording() + } else { + conference.startRecording(path) + } + isRecording.value = conference.isRecording + } + else -> { + isRecording.value = false } - isRecording.value = conference.isRecording - } else { - isRecording.value = false } if (closeMenu) toggleOptionsMenu() diff --git a/app/src/main/java/org/linphone/activities/main/chat/ChatScrollListener.kt b/app/src/main/java/org/linphone/activities/main/chat/ChatScrollListener.kt index 440f1d239..d2e2c7622 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/ChatScrollListener.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/ChatScrollListener.kt @@ -29,7 +29,7 @@ internal abstract class ChatScrollListener(private val mLayoutManager: LinearLay // True if we are still waiting for the last set of data to load. private var loading = true - var userHasScrolledUp: Boolean = false + private var userHasScrolledUp: Boolean = false // This happens many times a second during a scroll, so be wary of the code you place here. // We are given a few useful parameters to help us work out if we need to load some more data, diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt index 0623cf4ac..e1a34dde9 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageContentData.kt @@ -60,7 +60,6 @@ class ChatMessageContentData( val fileName = MutableLiveData() val filePath = MutableLiveData() - val fileSize = MutableLiveData() val downloadable = MutableLiveData() val downloadEnabled = MutableLiveData() @@ -72,7 +71,6 @@ class ChatMessageContentData( val formattedDuration = MutableLiveData() val voiceRecordPlayingPosition = MutableLiveData() val isVoiceRecordPlaying = MutableLiveData() - var voiceRecordAudioFocusRequest: AudioFocusRequestCompat? = null val isAlone: Boolean get() { @@ -86,7 +84,9 @@ class ChatMessageContentData( return count == 1 } - var isFileEncrypted: Boolean = false + private var isFileEncrypted: Boolean = false + + private var voiceRecordAudioFocusRequest: AudioFocusRequestCompat? = null private lateinit var voiceRecordingPlayer: Player private val playerListener = PlayerListener { @@ -193,8 +193,8 @@ class ChatMessageContentData( } // Display download size and underline text - fileSize.value = AppUtils.bytesToDisplayableSize(content.fileSize.toLong()) - val spannable = SpannableString("${AppUtils.getString(R.string.chat_message_download_file)} (${fileSize.value})") + val fileSize = AppUtils.bytesToDisplayableSize(content.fileSize.toLong()) + val spannable = SpannableString("${AppUtils.getString(R.string.chat_message_download_file)} ($fileSize)") spannable.setSpan(UnderlineSpan(), 0, spannable.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) downloadLabel.value = spannable diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt index cd8230096..43265f98e 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt @@ -165,7 +165,7 @@ class ChatMessageData(val chatMessage: ChatMessage) : GenericContactData(chatMes val list = arrayListOf() val contentsList = chatMessage.contents - for (index in 0 until contentsList.size) { + for (index in contentsList.indices) { val content = contentsList[index] if (content.isFileTransfer || content.isFile) { val data = ChatMessageContentData(chatMessage, index) diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt index f7e0de69c..dfefccc3f 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageSendingViewModel.kt @@ -86,11 +86,11 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel() val isPlayingVoiceRecording = MutableLiveData() - val recorder: Recorder - val voiceRecordPlayingPosition = MutableLiveData() - var voiceRecordAudioFocusRequest: AudioFocusRequestCompat? = null + private val recorder: Recorder + + private var voiceRecordAudioFocusRequest: AudioFocusRequestCompat? = null private lateinit var voiceRecordingPlayer: Player private val playerListener = PlayerListener { diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt index 7fd7402d3..f17074a31 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomViewModel.kt @@ -90,12 +90,12 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf var oneParticipantOneDevice: Boolean = false - var addressToCall: Address? = null - var onlyParticipantOnlyDeviceAddress: Address? = null val chatUnreadCountTranslateY = MutableLiveData() + private var addressToCall: Address? = null + private val bounceAnimator: ValueAnimator by lazy { ValueAnimator.ofFloat(AppUtils.getDimension(R.dimen.tabs_fragment_unread_count_bounce_offset), 0f).apply { addUpdateListener { diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt index 14f943db2..674cb096b 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomsListViewModel.kt @@ -170,12 +170,10 @@ class ChatRoomsListViewModel : ErrorReportingViewModel() { } private fun findChatRoomIndex(chatRoom: ChatRoom): Int { - var index = 0 - for (chatRoomViewModel in chatRooms.value.orEmpty()) { + for ((index, chatRoomViewModel) in chatRooms.value.orEmpty().withIndex()) { if (chatRoomViewModel.chatRoom == chatRoom) { return index } - index++ } return -1 } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt index ba78aaa23..c177e7386 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt @@ -32,8 +32,8 @@ import org.linphone.mediastream.Version import org.linphone.utils.Event class AdvancedSettingsViewModel : LogsUploadViewModel() { - protected val prefs = corePreferences - protected val core = coreContext.core + private val prefs = corePreferences + private val core = coreContext.core val debugModeListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { diff --git a/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt b/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt index a6d0404a7..27f0afb14 100644 --- a/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt @@ -57,7 +57,7 @@ open class StatusViewModel : ViewModel() { body: Content ) { if (body.type == "application" && body.subtype == "simple-message-summary" && body.size > 0) { - val data = body.utf8Text?.toLowerCase(Locale.getDefault()) + val data = body.utf8Text?.lowercase(Locale.getDefault()) val voiceMail = data?.split("voice-message: ") if (voiceMail?.size ?: 0 >= 2) { val toParse = voiceMail!![1].split("/", limit = 0) diff --git a/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt index cd59c2076..11aabca98 100644 --- a/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt @@ -22,6 +22,7 @@ package org.linphone.compatibility import android.annotation.SuppressLint import android.annotation.TargetApi import android.app.Activity +import android.app.PendingIntent import android.bluetooth.BluetoothAdapter import android.content.ContentValues import android.content.Context @@ -207,5 +208,9 @@ class Api21Compatibility { fun requestDismissKeyguard(activity: Activity) { activity.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD) } + + fun getUpdateCurrentPendingIntentFlag(): Int { + return PendingIntent.FLAG_UPDATE_CURRENT + } } } diff --git a/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt new file mode 100644 index 000000000..a1c454e70 --- /dev/null +++ b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010-2021 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.compatibility + +import android.annotation.TargetApi +import android.app.PendingIntent + +@TargetApi(31) +class Api31Compatibility { + companion object { + fun getUpdateCurrentPendingIntentFlag(): Int { + return PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + } + } +} diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index 5df9208e3..b1dc9d2b5 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -252,5 +252,12 @@ class Compatibility { } return Api21Compatibility.addAudioToMediaStore(context, content) } + + fun getUpdateCurrentPendingIntentFlag(): Int { + if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12)) { + return Api31Compatibility.getUpdateCurrentPendingIntentFlag() + } + return Api21Compatibility.getUpdateCurrentPendingIntentFlag() + } } } diff --git a/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt b/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt index 3433f893b..b554d0a40 100644 --- a/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt +++ b/app/src/main/java/org/linphone/contact/AsyncContactsLoader.kt @@ -129,10 +129,10 @@ class AsyncContactsLoader(private val context: Context) : try { val id: String = - cursor.getString(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID)) + cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data.CONTACT_ID)) val starred = - cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.STARRED)) == 1 - val lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)) + cursor.getInt(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.STARRED)) == 1 + val lookupKey = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.LOOKUP_KEY)) var contact: Contact? = androidContactsCache[id] if (contact == null) { Log.d( @@ -148,6 +148,10 @@ class AsyncContactsLoader(private val context: Context) : Log.e( "[Contacts Loader] Couldn't get values from cursor, exception: $ise" ) + } catch (iae: IllegalArgumentException) { + Log.e( + "[Contacts Loader] Couldn't get values from cursor, exception: $iae" + ) } } cursor.close() diff --git a/app/src/main/java/org/linphone/contact/Contact.kt b/app/src/main/java/org/linphone/contact/Contact.kt index f7ff508fa..8cba22e3a 100644 --- a/app/src/main/java/org/linphone/contact/Contact.kt +++ b/app/src/main/java/org/linphone/contact/Contact.kt @@ -51,10 +51,10 @@ open class Contact : Comparable { // Raw SIP addresses are only used for contact edition var rawSipAddresses = arrayListOf() - var thumbnailUri: Uri? = null - var friend: Friend? = null + private var thumbnailUri: Uri? = null + override fun compareTo(other: Contact): Int { val fn = fullName ?: "" val otherFn = other.fullName ?: "" diff --git a/app/src/main/java/org/linphone/contact/ContactsManager.kt b/app/src/main/java/org/linphone/contact/ContactsManager.kt index e5c28ef6e..fdc2af0d8 100644 --- a/app/src/main/java/org/linphone/contact/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contact/ContactsManager.kt @@ -79,12 +79,6 @@ class ContactsManager(private val context: Context) { @Synchronized private set - var localAccountsContacts = ArrayList() - @Synchronized - get - @Synchronized - private set - val magicSearch: MagicSearch by lazy { val magicSearch = coreContext.core.createMagicSearch() magicSearch.limitedSearch = false @@ -93,6 +87,12 @@ class ContactsManager(private val context: Context) { var latestContactFetch: String = "" + private var localAccountsContacts = ArrayList() + @Synchronized + get + @Synchronized + private set + private val friendsMap: HashMap = HashMap() private val contactsUpdatedListeners = ArrayList() diff --git a/app/src/main/java/org/linphone/contact/NativeContact.kt b/app/src/main/java/org/linphone/contact/NativeContact.kt index b4f2f4a5c..cb487bedd 100644 --- a/app/src/main/java/org/linphone/contact/NativeContact.kt +++ b/app/src/main/java/org/linphone/contact/NativeContact.kt @@ -86,97 +86,104 @@ class NativeContact(val nativeId: String, private val lookupKey: String? = null) @Synchronized override fun syncValuesFromAndroidCursor(cursor: Cursor) { - val displayName: String? = - cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME_PRIMARY)) + try { + val displayName: String? = + cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME_PRIMARY)) - val mime: String? = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE)) - val data1: String? = cursor.getString(cursor.getColumnIndex("data1")) - val data2: String? = cursor.getString(cursor.getColumnIndex("data2")) - val data3: String? = cursor.getString(cursor.getColumnIndex("data3")) - val data4: String? = cursor.getString(cursor.getColumnIndex("data4")) + val mime: String? = + cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data.MIMETYPE)) + val data1: String? = cursor.getString(cursor.getColumnIndexOrThrow("data1")) + val data2: String? = cursor.getString(cursor.getColumnIndexOrThrow("data2")) + val data3: String? = cursor.getString(cursor.getColumnIndexOrThrow("data3")) + val data4: String? = cursor.getString(cursor.getColumnIndexOrThrow("data4")) - if (fullName == null || fullName != displayName) { - Log.d("[Native Contact] Setting display name $displayName") - fullName = displayName - } + if (fullName == null || fullName != displayName) { + Log.d("[Native Contact] Setting display name $displayName") + fullName = displayName + } - val linphoneMime = AppUtils.getString(R.string.linphone_address_mime_type) - when (mime) { - ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE -> { - if (data1 == null && data4 == null) { - Log.d("[Native Contact] Phone number data is empty") - return - } + val linphoneMime = AppUtils.getString(R.string.linphone_address_mime_type) + when (mime) { + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE -> { + if (data1 == null && data4 == null) { + Log.d("[Native Contact] Phone number data is empty") + return + } - val labelColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL) - val label: String? = cursor.getString(labelColumnIndex) - val typeColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE) - val type: Int = cursor.getInt(typeColumnIndex) - val typeLabel = ContactsContract.CommonDataKinds.Phone.getTypeLabel( - coreContext.context.resources, - type, - label - ).toString() + val labelColumnIndex = + cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.LABEL) + val label: String? = cursor.getString(labelColumnIndex) + val typeColumnIndex = + cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.TYPE) + val type: Int = cursor.getInt(typeColumnIndex) + val typeLabel = ContactsContract.CommonDataKinds.Phone.getTypeLabel( + coreContext.context.resources, + type, + label + ).toString() - // data4 = ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER - // data1 = ContactsContract.CommonDataKinds.Phone.NUMBER - val number = if (corePreferences.preferNormalizedPhoneNumbersFromAddressBook) { - data4 ?: data1 - } else { - data1 ?: data4 - } - if (number != null && number.isNotEmpty()) { - Log.d("[Native Contact] Found phone number $data1 ($data4), type label is $typeLabel") - if (!rawPhoneNumbers.contains(number)) { - phoneNumbers.add(PhoneNumber(number, typeLabel)) - rawPhoneNumbers.add(number) + // data4 = ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER + // data1 = ContactsContract.CommonDataKinds.Phone.NUMBER + val number = if (corePreferences.preferNormalizedPhoneNumbersFromAddressBook) { + data4 ?: data1 + } else { + data1 ?: data4 + } + if (number != null && number.isNotEmpty()) { + Log.d("[Native Contact] Found phone number $data1 ($data4), type label is $typeLabel") + if (!rawPhoneNumbers.contains(number)) { + phoneNumbers.add(PhoneNumber(number, typeLabel)) + rawPhoneNumbers.add(number) + } } } - } - linphoneMime, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE -> { - if (data1 == null) { - Log.d("[Native Contact] SIP address is null") - return - } + linphoneMime, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE -> { + if (data1 == null) { + Log.d("[Native Contact] SIP address is null") + return + } - Log.d("[Native Contact] Found SIP address $data1") - if (rawPhoneNumbers.contains(data1)) { - Log.d("[Native Contact] SIP address value already exists in phone numbers list, skipping") - return - } + Log.d("[Native Contact] Found SIP address $data1") + if (rawPhoneNumbers.contains(data1)) { + Log.d("[Native Contact] SIP address value already exists in phone numbers list, skipping") + return + } - val address: Address? = coreContext.core.interpretUrl(data1) - if (address == null) { - Log.e("[Native Contact] Couldn't parse address $data1 !") - return - } + val address: Address? = coreContext.core.interpretUrl(data1) + if (address == null) { + Log.e("[Native Contact] Couldn't parse address $data1 !") + return + } - val stringAddress = address.asStringUriOnly() - Log.d("[Native Contact] Found SIP address $stringAddress") - if (!rawSipAddresses.contains(data1)) { - sipAddresses.add(address) - rawSipAddresses.add(data1) + val stringAddress = address.asStringUriOnly() + Log.d("[Native Contact] Found SIP address $stringAddress") + if (!rawSipAddresses.contains(data1)) { + sipAddresses.add(address) + rawSipAddresses.add(data1) + } + } + ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE -> { + if (data1 == null) { + Log.d("[Native Contact] Organization is null") + return + } + + Log.d("[Native Contact] Found organization $data1") + organization = data1 + } + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE -> { + if (data2 == null && data3 == null) { + Log.d("[Native Contact] First name and last name are both null") + return + } + + Log.d("[Native Contact] Found first name $data2 and last name $data3") + firstName = data2 + lastName = data3 } } - ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE -> { - if (data1 == null) { - Log.d("[Native Contact] Organization is null") - return - } - - Log.d("[Native Contact] Found organization $data1") - organization = data1 - } - ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE -> { - if (data2 == null && data3 == null) { - Log.d("[Native Contact] First name and last name are both null") - return - } - - Log.d("[Native Contact] Found first name $data2 and last name $data3") - firstName = data2 - lastName = data3 - } + } catch (iae: IllegalArgumentException) { + Log.e("[Native Contact] Exception: $iae") } } diff --git a/app/src/main/java/org/linphone/contact/NativeContactEditor.kt b/app/src/main/java/org/linphone/contact/NativeContactEditor.kt index 84f900e74..630cb9703 100644 --- a/app/src/main/java/org/linphone/contact/NativeContactEditor.kt +++ b/app/src/main/java/org/linphone/contact/NativeContactEditor.kt @@ -96,8 +96,12 @@ class NativeContactEditor(val contact: NativeContact) { if (cursor?.moveToFirst() == true) { do { if (rawId == null) { - rawId = cursor.getString(cursor.getColumnIndex(RawContacts._ID)) - Log.i("[Native Contact Editor] Found raw id $rawId for native contact with id ${contact.nativeId}") + try { + rawId = cursor.getString(cursor.getColumnIndexOrThrow(RawContacts._ID)) + Log.i("[Native Contact Editor] Found raw id $rawId for native contact with id ${contact.nativeId}") + } catch (iae: IllegalArgumentException) { + Log.e("[Native Contact Editor] Exception: $iae") + } } } while (cursor.moveToNext() && rawId == null) } @@ -258,11 +262,16 @@ class NativeContactEditor(val contact: NativeContact) { ) if (cursor?.moveToFirst() == true) { do { - val accountType = - cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_TYPE)) - if (accountType == AppUtils.getString(R.string.sync_account_type) && syncAccountRawId == null) { - syncAccountRawId = cursor.getString(cursor.getColumnIndex(RawContacts._ID)) - Log.d("[Native Contact Editor] Found linphone raw id $syncAccountRawId for native contact with id ${contact.nativeId}") + try { + val accountType = + cursor.getString(cursor.getColumnIndexOrThrow(RawContacts.ACCOUNT_TYPE)) + if (accountType == AppUtils.getString(R.string.sync_account_type) && syncAccountRawId == null) { + syncAccountRawId = + cursor.getString(cursor.getColumnIndexOrThrow(RawContacts._ID)) + Log.d("[Native Contact Editor] Found linphone raw id $syncAccountRawId for native contact with id ${contact.nativeId}") + } + } catch (iae: IllegalArgumentException) { + Log.e("[Native Contact Editor] Exception: $iae") } } while (cursor.moveToNext() && syncAccountRawId == null) } @@ -461,7 +470,11 @@ class NativeContactEditor(val contact: NativeContact) { val count = cursor?.count ?: 0 val data1 = if (count > 0) { if (cursor?.moveToFirst() == true) { - cursor.getString(cursor.getColumnIndex("data1")) + try { + cursor.getString(cursor.getColumnIndexOrThrow("data1")) + } catch (iae: IllegalArgumentException) { + Log.e("[Native Contact Editor] Exception: $iae") + } } else null } else null cursor?.close() diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index bb2197f9a..383a47a90 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -87,7 +87,7 @@ class CoreContext(val context: Context, coreConfig: Config) { "$sdkVersion ($sdkBranch, $sdkBuildType)" } - val collator = Collator.getInstance() + val collator: Collator = Collator.getInstance() val contactsManager: ContactsManager by lazy { ContactsManager(context) } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index c7a21f515..729cfbebe 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -633,7 +633,7 @@ class NotificationsManager(private val context: Context) { context, notifiable.notificationId, target, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + Compatibility.getUpdateCurrentPendingIntentFlag() ) val id = LinphoneUtils.getChatRoomId(room.localAddress, room.peerAddress) @@ -888,7 +888,7 @@ class NotificationsManager(private val context: Context) { context, notifiable.notificationId, replyIntent, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + Compatibility.getUpdateCurrentPendingIntentFlag() ) return NotificationCompat.Action.Builder( R.drawable.chat_send_over, diff --git a/app/src/main/java/org/linphone/utils/FileUtils.kt b/app/src/main/java/org/linphone/utils/FileUtils.kt index e9536c5b7..0955b39b7 100644 --- a/app/src/main/java/org/linphone/utils/FileUtils.kt +++ b/app/src/main/java/org/linphone/utils/FileUtils.kt @@ -70,31 +70,31 @@ class FileUtils { } fun isPlainTextFile(path: String): Boolean { - val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault()) + val extension = getExtensionFromFileName(path).lowercase(Locale.getDefault()) val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) return type?.startsWith("text/plain") ?: false } fun isExtensionPdf(path: String): Boolean { - val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault()) + val extension = getExtensionFromFileName(path).lowercase(Locale.getDefault()) val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) return type?.startsWith("application/pdf") ?: false } fun isExtensionImage(path: String): Boolean { - val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault()) + val extension = getExtensionFromFileName(path).lowercase(Locale.getDefault()) val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) return type?.startsWith("image/") ?: false } fun isExtensionVideo(path: String): Boolean { - val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault()) + val extension = getExtensionFromFileName(path).lowercase(Locale.getDefault()) val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) return type?.startsWith("video/") ?: false } fun isExtensionAudio(path: String): Boolean { - val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault()) + val extension = getExtensionFromFileName(path).lowercase(Locale.getDefault()) val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) return type?.startsWith("audio/") ?: false } diff --git a/app/src/main/java/org/linphone/views/VoiceRecordProgressBar.kt b/app/src/main/java/org/linphone/views/VoiceRecordProgressBar.kt index 3d918af4c..900e45e8f 100644 --- a/app/src/main/java/org/linphone/views/VoiceRecordProgressBar.kt +++ b/app/src/main/java/org/linphone/views/VoiceRecordProgressBar.kt @@ -205,7 +205,17 @@ class VoiceRecordProgressBar : View { } } - fun setProgressDrawable(drawable: Drawable) { + fun setSecondaryProgressTint(color: Int) { + val drawable = progressDrawable + if (drawable != null) { + if (drawable is LayerDrawable) { + val secondaryProgressDrawable = drawable.findDrawableByLayerId(android.R.id.secondaryProgress) + secondaryProgressDrawable?.setTint(color) + } + } + } + + private fun setProgressDrawable(drawable: Drawable) { val needUpdate: Boolean = if (progressDrawable != null && drawable !== progressDrawable) { progressDrawable?.callback = null true @@ -233,16 +243,6 @@ class VoiceRecordProgressBar : View { } } - fun setSecondaryProgressTint(color: Int) { - val drawable = progressDrawable - if (drawable != null) { - if (drawable is LayerDrawable) { - val secondaryProgressDrawable = drawable.findDrawableByLayerId(android.R.id.secondaryProgress) - secondaryProgressDrawable?.setTint(color) - } - } - } - private fun refreshProgress(id: Int, progress: Int) { var scale: Float = if (max > 0) (progress.toFloat() / max) else 0f diff --git a/app/src/main/res/layout/chat_bubble_activity.xml b/app/src/main/res/layout/chat_bubble_activity.xml index 7b9c755d7..4c67bbbc0 100644 --- a/app/src/main/res/layout/chat_bubble_activity.xml +++ b/app/src/main/res/layout/chat_bubble_activity.xml @@ -97,6 +97,7 @@ android:id="@+id/message" android:enabled="@{!chatSendingViewModel.isReadOnly}" android:text="@={chatSendingViewModel.textToSend}" + android:hint="@string/chat_room_sending_message_hint" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" diff --git a/app/src/main/res/layout/chat_room_detail_fragment.xml b/app/src/main/res/layout/chat_room_detail_fragment.xml index 36f37c288..d7094e429 100644 --- a/app/src/main/res/layout/chat_room_detail_fragment.xml +++ b/app/src/main/res/layout/chat_room_detail_fragment.xml @@ -328,6 +328,7 @@ android:layout_alignParentBottom="true" android:background="@drawable/round_button_background" android:padding="13dp" + android:contentDescription="@string/content_descripton_scroll_to_bottom" android:src="@drawable/scroll_to_bottom" /> + xmlns:linphone="http://schemas.android.com/apk/res-auto" + xmlns:bind="http://schemas.android.com/tools"> diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 44151a411..d99516d2f 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -192,7 +192,7 @@ Contactos Marcador telefónico Conversaciones - Eliminar el último caracter + Eliminar el último carácter Crear contacto Mostrar todas las llamadas Mostrar solo llamadas perdidad diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 75a13a517..a72ac3e00 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -481,7 +481,7 @@ Tous les appels Appel entrant Appel sortant - Créer une conversation 1-1 + Créer une conversation 1–1 Créer une conversation de groupe Non sécurisé Sécurisé @@ -626,4 +626,5 @@ Nécessite des permissions supplémentaires %1$d messages non lus %1$d message non lu + Aller au dernier message reçu ou au premier message non lu \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e1dfc7e9b..2f5d1f797 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -737,4 +737,5 @@ Cancel voice recording Pause voice recording Play voice recording + Scroll to bottom or first unread message