[Android] Streams fragment: re-type the url if an error occurred

Nicolas Pomepuy git at videolan.org
Wed Feb 11 13:25:17 UTC 2026


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Fri Feb  6 12:06:11 2026 +0100| [111312f8c9f8b9906063b839ba81fe4f1c552d0e] | committer: Nicolas Pomepuy

Streams fragment: re-type the url if an error occurred

Fixes #3293

> https://code.videolan.org/videolan/vlc-android/commit/111312f8c9f8b9906063b839ba81fe4f1c552d0e
---

 .../src/org/videolan/vlc/PlaybackService.kt        |  1 +
 .../videolan/vlc/gui/network/MRLPanelFragment.kt   | 29 ++++++++++++++++++++++
 .../src/org/videolan/vlc/media/PlaylistManager.kt  |  1 +
 3 files changed, 31 insertions(+)

diff --git a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
index ed21c1abc0..3cf8d017d2 100644
--- a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
@@ -2024,6 +2024,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner, CoroutineSc
         val headSetDetection = LiveEvent<Boolean>()
         val equalizer = LiveEvent<MediaPlayer.Equalizer?>()
         val waitConfirmation = LiveEvent<String?>()
+        val lastError = LiveEvent<String?>()
 
         private const val SHOW_TOAST = "show_toast"
         private const val END_MEDIASESSION = "end_mediasession"
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/network/MRLPanelFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/network/MRLPanelFragment.kt
index 1c836ad6be..eab857ea31 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/network/MRLPanelFragment.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/network/MRLPanelFragment.kt
@@ -24,6 +24,8 @@ import android.content.ClipboardManager
 import android.content.Context
 import android.graphics.Rect
 import android.os.Bundle
+import android.text.Editable
+import android.text.TextWatcher
 import android.view.KeyEvent
 import android.view.LayoutInflater
 import android.view.Menu
@@ -37,16 +39,22 @@ import androidx.appcompat.view.ActionMode
 import androidx.core.net.toUri
 import androidx.core.view.doOnLayout
 import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 import org.videolan.medialibrary.MLServiceLocator
 import org.videolan.medialibrary.interfaces.media.MediaWrapper
 import org.videolan.resources.util.parcelable
 import org.videolan.tools.Settings
 import org.videolan.tools.isValidUrl
 import org.videolan.tools.setVisible
+import org.videolan.vlc.PlaybackService
 import org.videolan.vlc.R
 import org.videolan.vlc.databinding.MrlPanelBinding
 import org.videolan.vlc.gui.BaseFragment
@@ -68,6 +76,7 @@ class MRLPanelFragment : BaseFragment(), View.OnKeyListener, TextView.OnEditorAc
     private lateinit var binding: MrlPanelBinding
     private lateinit var adapter: MRLAdapter
     private lateinit var viewModel: StreamsModel
+    private  var goToEnd = false
     override fun getTitle() = ""
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -81,6 +90,18 @@ class MRLPanelFragment : BaseFragment(), View.OnKeyListener, TextView.OnEditorAc
         binding.viewmodel = viewModel
         binding.mrlEdit.editText?.setOnKeyListener(this)
         binding.mrlEdit.editText?.setOnEditorActionListener(this)
+        binding.mrlEdit.editText?.addTextChangedListener(object : TextWatcher {
+            override fun afterTextChanged(s: Editable?) {
+                if (goToEnd) binding.mrlEdit.editText?.setSelection(binding.mrlEdit.editText!!.length())
+                goToEnd = false
+
+            }
+
+            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
+
+            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
+
+        })
         binding.mrlEdit.editText?.requestFocus()
 
         binding.play.setOnClickListener(this)
@@ -124,6 +145,14 @@ class MRLPanelFragment : BaseFragment(), View.OnKeyListener, TextView.OnEditorAc
             val name = bundle.getString(RENAME_DIALOG_NEW_NAME) ?: return at setFragmentResultListener
             renameStream(media, name)
         }
+
+        PlaybackService.lastError.observe(requireActivity()) {
+            if (it != null) {
+                goToEnd = true
+                viewModel.observableSearchText.set(it)
+                PlaybackService.lastError.value = null
+            }
+        }
     }
 
     override fun onResume() {
diff --git a/application/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt b/application/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt
index 4a9fda5099..640067e52c 100644
--- a/application/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt
+++ b/application/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt
@@ -1236,6 +1236,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
 
                     service.showToast(if (location != null && location.toUri().scheme == "missing") service.getString(R.string.missing_location) else service.getString(R.string.invalid_location, location
                             ?: ""), Toast.LENGTH_SHORT, true)
+                    if (location != null) PlaybackService.lastError.postValue(location)
                     if (currentIndex != nextIndex) next() else stop()
                 }
                 MediaPlayer.Event.TimeChanged -> {



More information about the Android mailing list