diff --git a/app/src/main/java/org/linphone/ui/call/conference/fragment/ActiveConferenceCallFragment.kt b/app/src/main/java/org/linphone/ui/call/conference/fragment/ActiveConferenceCallFragment.kt index 342263f3a..3b2973924 100644 --- a/app/src/main/java/org/linphone/ui/call/conference/fragment/ActiveConferenceCallFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/conference/fragment/ActiveConferenceCallFragment.kt @@ -19,9 +19,6 @@ */ package org.linphone.ui.call.conference.fragment -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.os.Bundle import android.os.SystemClock import android.view.LayoutInflater @@ -43,6 +40,7 @@ import org.linphone.ui.call.CallActivity import org.linphone.ui.call.fragment.GenericCallFragment import org.linphone.ui.call.viewmodel.CallsViewModel import org.linphone.ui.call.viewmodel.CurrentCallViewModel +import org.linphone.utils.AppUtils import org.linphone.utils.Event import org.linphone.utils.startAnimatedDrawable @@ -272,14 +270,12 @@ class ActiveConferenceCallFragment : GenericCallFragment() { } } - binding.setShareConferenceClickListener { + binding.setCopyConferenceUriToClipboardClickListener { val sipUri = callViewModel.conferenceModel.sipUri.value.orEmpty() if (sipUri.isNotEmpty()) { - Log.i("$TAG Sharing conference SIP URI [$sipUri]") - - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + Log.i("$TAG Copying conference SIP URI [$sipUri] into clipboard") val label = "Conference SIP address" - clipboard.setPrimaryClip(ClipData.newPlainText(label, sipUri)) + AppUtils.copyToClipboard(requireContext(), label, sipUri) } } diff --git a/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceParticipantsListFragment.kt b/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceParticipantsListFragment.kt index 67aafce79..b0e816f9b 100644 --- a/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceParticipantsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/conference/fragment/ConferenceParticipantsListFragment.kt @@ -19,9 +19,6 @@ */ package org.linphone.ui.call.conference.fragment -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.os.Bundle import android.view.Gravity import android.view.LayoutInflater @@ -45,6 +42,7 @@ import org.linphone.ui.GenericActivity import org.linphone.ui.call.adapter.ConferenceParticipantsListAdapter import org.linphone.ui.call.fragment.GenericCallFragment import org.linphone.ui.call.viewmodel.CurrentCallViewModel +import org.linphone.utils.AppUtils import org.linphone.utils.ConfirmationDialogModel import org.linphone.utils.DialogUtils @@ -207,10 +205,8 @@ class ConferenceParticipantsListFragment : GenericCallFragment() { val sipUri = viewModel.conferenceModel.sipUri.value.orEmpty() if (sipUri.isNotEmpty()) { Log.i("$TAG Sharing conference SIP URI [$sipUri]") - - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val label = "Conference SIP address" - clipboard.setPrimaryClip(ClipData.newPlainText(label, sipUri)) + AppUtils.copyToClipboard(requireContext(), label, sipUri) } popupWindow.dismiss() diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt index 5f31052e3..fb65ab662 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt @@ -19,9 +19,6 @@ */ package org.linphone.ui.main.chat.fragment -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.os.Bundle import android.view.Gravity import android.view.LayoutInflater @@ -46,6 +43,7 @@ import org.linphone.ui.main.chat.viewmodel.ConversationInfoViewModel import org.linphone.ui.main.fragment.SlidingPaneChildFragment import org.linphone.utils.ConfirmationDialogModel import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel +import org.linphone.utils.AppUtils import org.linphone.utils.DialogUtils import org.linphone.utils.Event @@ -428,14 +426,13 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { popupView.setCopySipUriClickListener { val sipUri = participantModel.sipUri - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clipboard.setPrimaryClip(ClipData.newPlainText("SIP address", sipUri)) - - val message = getString(R.string.sip_address_copied_to_clipboard_toast) - (requireActivity() as GenericActivity).showGreenToast( - message, - R.drawable.check - ) + if (AppUtils.copyToClipboard(requireContext(), "SIP address", sipUri)) { + val message = getString(R.string.sip_address_copied_to_clipboard_toast) + (requireActivity() as GenericActivity).showGreenToast( + message, + R.drawable.check + ) + } } // Elevation is for showing a shadow around the popup @@ -490,12 +487,9 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { } private fun copyAddressToClipboard(value: String) { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clipboard.setPrimaryClip(ClipData.newPlainText("SIP address", value)) - val message = getString(R.string.sip_address_copied_to_clipboard_toast) - (requireActivity() as GenericActivity).showGreenToast( - message, - R.drawable.check - ) + if (AppUtils.copyToClipboard(requireContext(), "SIP address", value)) { + val message = getString(R.string.sip_address_copied_to_clipboard_toast) + (requireActivity() as GenericActivity).showGreenToast(message, R.drawable.check) + } } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ChatMessageLongPressViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ChatMessageLongPressViewModel.kt index 56af87113..944579ac5 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ChatMessageLongPressViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ChatMessageLongPressViewModel.kt @@ -19,9 +19,6 @@ */ package org.linphone.ui.main.chat.viewmodel -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.view.View import androidx.annotation.UiThread import androidx.lifecycle.MutableLiveData @@ -31,6 +28,7 @@ import org.linphone.core.tools.Log import org.linphone.databinding.ChatBubbleEmojiPickerBottomSheetBinding import org.linphone.ui.GenericViewModel import org.linphone.ui.main.chat.model.MessageModel +import org.linphone.utils.AppUtils import org.linphone.utils.Event class ChatMessageLongPressViewModel : GenericViewModel() { @@ -148,12 +146,12 @@ class ChatMessageLongPressViewModel : GenericViewModel() { @UiThread fun copyClickListener() { - Log.i("$TAG Copying message text into clipboard") - - val text = messageModel.value?.getRawTextContent() - val clipboard = coreContext.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val label = "Message" - clipboard.setPrimaryClip(ClipData.newPlainText(label, text)) + val text = messageModel.value?.getRawTextContent().orEmpty() + if (text.isNotEmpty()) { + Log.i("$TAG Copying message text into clipboard") + val label = "Message" + AppUtils.copyToClipboard(coreContext.context, label, text) + } dismiss() } diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt index 53f0d3aea..7a4db5dac 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt @@ -21,9 +21,6 @@ package org.linphone.ui.main.contacts.fragment import android.app.Dialog import android.content.ActivityNotFoundException -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.content.Intent import android.os.Bundle import android.provider.ContactsContract @@ -252,19 +249,15 @@ class ContactFragment : SlidingPaneChildFragment() { } private fun copyNumberOrAddressToClipboard(value: String, isSip: Boolean) { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val label = if (isSip) "SIP address" else "Phone number" - clipboard.setPrimaryClip(ClipData.newPlainText(label, value)) - - val message = if (isSip) { - getString(R.string.sip_address_copied_to_clipboard_toast) - } else { - getString(R.string.contact_details_phone_number_copied_to_clipboard_toast) + if (AppUtils.copyToClipboard(requireContext(), label, value)) { + val message = if (isSip) { + getString(R.string.sip_address_copied_to_clipboard_toast) + } else { + getString(R.string.contact_details_phone_number_copied_to_clipboard_toast) + } + (requireActivity() as GenericActivity).showGreenToast(message, R.drawable.check) } - (requireActivity() as GenericActivity).showGreenToast( - message, - R.drawable.check - ) } private fun shareContact(name: String, file: File) { diff --git a/app/src/main/java/org/linphone/ui/main/help/fragment/DebugFragment.kt b/app/src/main/java/org/linphone/ui/main/help/fragment/DebugFragment.kt index 6a312c1a6..f5ce1b5b9 100644 --- a/app/src/main/java/org/linphone/ui/main/help/fragment/DebugFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/help/fragment/DebugFragment.kt @@ -20,9 +20,6 @@ package org.linphone.ui.main.help.fragment import android.content.ActivityNotFoundException -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.content.Intent import android.os.Bundle import android.view.LayoutInflater @@ -39,6 +36,7 @@ import org.linphone.ui.fileviewer.FileViewerActivity import org.linphone.ui.main.MainActivity import org.linphone.ui.main.fragment.GenericMainFragment import org.linphone.ui.main.help.viewmodel.HelpViewModel +import org.linphone.utils.AppUtils class DebugFragment : GenericMainFragment() { private lateinit var binding: HelpDebugFragmentBinding @@ -69,19 +67,15 @@ class DebugFragment : GenericMainFragment() { } binding.setAppVersionClickListener { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val label = getString(R.string.help_troubleshooting_app_version_title) - clipboard.setPrimaryClip( - ClipData.newPlainText(label, viewModel.appVersion.value.orEmpty()) - ) + val value = viewModel.appVersion.value.orEmpty() + AppUtils.copyToClipboard(requireContext(), label, value) } binding.setSdkVersionClickListener { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val label = getString(R.string.help_troubleshooting_sdk_version_title) - clipboard.setPrimaryClip( - ClipData.newPlainText(label, viewModel.sdkVersion.value.orEmpty()) - ) + val value = viewModel.sdkVersion.value.orEmpty() + AppUtils.copyToClipboard(requireContext(), label, value) } viewModel.debugLogsCleanedEvent.observe(viewLifecycleOwner) { @@ -96,9 +90,7 @@ class DebugFragment : GenericMainFragment() { viewModel.uploadDebugLogsFinishedEvent.observe(viewLifecycleOwner) { it.consume { url -> if (requireActivity() is AssistantActivity) { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val label = "Logs upload URL" - clipboard.setPrimaryClip(ClipData.newPlainText(label, url)) + AppUtils.copyToClipboard(requireContext(), "Logs upload URL", url) return@consume } diff --git a/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt b/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt index a289020d6..b503cf484 100644 --- a/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt @@ -19,9 +19,6 @@ */ package org.linphone.ui.main.history.fragment -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.os.Bundle import android.view.Gravity import android.view.LayoutInflater @@ -44,6 +41,7 @@ import org.linphone.ui.main.fragment.SlidingPaneChildFragment import org.linphone.ui.main.history.adapter.ContactHistoryListAdapter import org.linphone.utils.ConfirmationDialogModel import org.linphone.ui.main.history.viewmodel.HistoryViewModel +import org.linphone.utils.AppUtils import org.linphone.utils.DialogUtils import org.linphone.utils.Event @@ -190,14 +188,12 @@ class HistoryFragment : SlidingPaneChildFragment() { } private fun copyNumberOrAddressToClipboard(value: String) { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val label = "SIP address" - clipboard.setPrimaryClip(ClipData.newPlainText(label, value)) - - (requireActivity() as GenericActivity).showGreenToast( - getString(R.string.sip_address_copied_to_clipboard_toast), - R.drawable.check - ) + if (AppUtils.copyToClipboard(requireContext(), "SIP address", value)) { + (requireActivity() as GenericActivity).showGreenToast( + getString(R.string.sip_address_copied_to_clipboard_toast), + R.drawable.check + ) + } } private fun showPopupMenu() { diff --git a/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryListFragment.kt b/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryListFragment.kt index 2cc9d6db5..9795034f1 100644 --- a/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryListFragment.kt @@ -19,9 +19,6 @@ */ package org.linphone.ui.main.history.fragment -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.os.Bundle import android.view.Gravity import android.view.LayoutInflater @@ -47,6 +44,7 @@ import org.linphone.ui.main.fragment.AbstractMainFragment import org.linphone.ui.main.history.adapter.HistoryListAdapter import org.linphone.utils.ConfirmationDialogModel import org.linphone.ui.main.history.viewmodel.HistoryListViewModel +import org.linphone.utils.AppUtils import org.linphone.utils.DialogUtils import org.linphone.utils.Event @@ -283,14 +281,12 @@ class HistoryListFragment : AbstractMainFragment() { } private fun copyNumberOrAddressToClipboard(value: String) { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val label = "SIP address" - clipboard.setPrimaryClip(ClipData.newPlainText(label, value)) - - (requireActivity() as GenericActivity).showGreenToast( - getString(R.string.sip_address_copied_to_clipboard_toast), - R.drawable.check - ) + if (AppUtils.copyToClipboard(requireContext(), "SIP address", value)) { + (requireActivity() as GenericActivity).showGreenToast( + getString(R.string.sip_address_copied_to_clipboard_toast), + R.drawable.check + ) + } } private fun showPopupMenu() { diff --git a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt index a34b631ef..9ef01f6cc 100644 --- a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt @@ -20,9 +20,6 @@ package org.linphone.ui.main.meetings.fragment import android.content.ActivityNotFoundException -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.content.Intent import android.os.Bundle import android.provider.CalendarContract @@ -47,6 +44,7 @@ import org.linphone.ui.main.fragment.SlidingPaneChildFragment import org.linphone.utils.ConfirmationDialogModel import org.linphone.ui.main.meetings.adapter.MeetingParticipantsAdapter import org.linphone.ui.main.meetings.viewmodel.MeetingViewModel +import org.linphone.utils.AppUtils import org.linphone.utils.DialogUtils import org.linphone.utils.Event @@ -136,7 +134,7 @@ class MeetingFragment : SlidingPaneChildFragment() { } } - binding.setShareClickListener { + binding.setCopyUriToClipboardClickListener { copyMeetingAddressIntoClipboard(uri) } @@ -249,15 +247,12 @@ class MeetingFragment : SlidingPaneChildFragment() { private fun copyMeetingAddressIntoClipboard(meetingSipUri: String) { Log.i("$TAG Copying conference SIP URI [$meetingSipUri] into clipboard") - - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val label = "Meeting SIP address" - clipboard.setPrimaryClip(ClipData.newPlainText(label, meetingSipUri)) - - (requireActivity() as GenericActivity).showGreenToast( - getString(R.string.meeting_address_copied_to_clipboard_toast), - R.drawable.check - ) + if (AppUtils.copyToClipboard(requireContext(), "Meeting SIP address", meetingSipUri)) { + (requireActivity() as GenericActivity).showGreenToast( + getString(R.string.meeting_address_copied_to_clipboard_toast), + R.drawable.check + ) + } } private fun shareMeetingInfoAsCalendarEvent() { diff --git a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt index 93bd679a3..692d92086 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt @@ -19,9 +19,6 @@ */ package org.linphone.ui.main.settings.fragment -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -43,6 +40,7 @@ import org.linphone.ui.GenericActivity import org.linphone.ui.main.fragment.GenericMainFragment import org.linphone.utils.ConfirmationDialogModel import org.linphone.ui.main.settings.viewmodel.AccountProfileViewModel +import org.linphone.utils.AppUtils import org.linphone.utils.DialogUtils import org.linphone.utils.Event import org.linphone.utils.FileUtils @@ -229,13 +227,10 @@ class AccountProfileFragment : GenericMainFragment() { } private fun copyAddressToClipboard(value: String) { - val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clipboard.setPrimaryClip(ClipData.newPlainText("SIP address", value)) - val message = getString(R.string.sip_address_copied_to_clipboard_toast) - (requireActivity() as GenericActivity).showGreenToast( - message, - R.drawable.check - ) + if (AppUtils.copyToClipboard(requireContext(), "SIP address", value)) { + val message = getString(R.string.sip_address_copied_to_clipboard_toast) + (requireActivity() as GenericActivity).showGreenToast(message, R.drawable.check) + } } private fun setupDialPlanPicker() { diff --git a/app/src/main/java/org/linphone/utils/AndroidUtils.kt b/app/src/main/java/org/linphone/utils/AndroidUtils.kt index e479b53a1..e2aac3522 100644 --- a/app/src/main/java/org/linphone/utils/AndroidUtils.kt +++ b/app/src/main/java/org/linphone/utils/AndroidUtils.kt @@ -20,6 +20,8 @@ package org.linphone.utils import android.app.Activity +import android.content.ClipData +import android.content.ClipboardManager import android.content.Context import android.os.Build import android.provider.Settings @@ -205,6 +207,18 @@ class AppUtils { return name } + @AnyThread + fun copyToClipboard(context: Context, label: String, value: String): Boolean { + try { + val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + clipboard.setPrimaryClip(ClipData.newPlainText(label, value)) + return true + } catch (e: Exception) { + Log.e("$TAG Failed to copy text [$value] with label [$label] to clipboard: $e") + } + return false + } + @AnyThread private fun extractFirstSymbol(text: String): String { val sequence = StringBuilder(text.length) diff --git a/app/src/main/res/layout/call_active_conference_fragment.xml b/app/src/main/res/layout/call_active_conference_fragment.xml index d9114b469..4665f71fd 100644 --- a/app/src/main/res/layout/call_active_conference_fragment.xml +++ b/app/src/main/res/layout/call_active_conference_fragment.xml @@ -10,7 +10,7 @@ name="backClickListener" type="View.OnClickListener" />