diff --git a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt
index b8d6401b217500d4e8b8882ef721997a2dc39184..d989c3e9b0abf7d6dcc6a47efbb875ad0b4f51c8 100644
--- a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt
+++ b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt
@@ -107,6 +107,7 @@ import org.videolan.vlc.BuildConfig
 import org.videolan.vlc.gui.dialogs.getPlaylistByName
 import org.videolan.vlc.gui.helpers.AudioUtil
 import org.videolan.vlc.gui.helpers.BitmapUtil
+import org.videolan.vlc.gui.helpers.FeedbackUtil
 import org.videolan.vlc.gui.helpers.VectorDrawableUtil
 import org.videolan.vlc.gui.helpers.getBitmapFromDrawable
 import org.videolan.vlc.gui.helpers.getColoredBitmapFromColor
@@ -266,6 +267,67 @@ fun Route.setupRouting(appContext: Context, scope: CoroutineScope) {
 
         call.respondJson(convertToJson(logs))
     }
+    // Prepare the feedback data
+    post("/feedback-form") {
+        verifyLogin(settings)
+
+        val formParameters = try {
+            call.receiveParameters()
+        } catch (e: Exception) {
+            Log.w(this::class.java.simpleName, "Failed to parse form parameters. ${e.message}", e)
+            call.respond(HttpStatusCode.BadRequest)
+            return@post
+        }
+
+        val feedbackType = formParameters.get("type")?.toInt() ?: 0
+        val includeML = formParameters.get("includeML") == "true"
+        val includeLogs = formParameters.get("includeLogs") == "true"
+        val subject = formParameters.get("subject") ?: ""
+        val message = formParameters.get("message") ?: ""
+
+        if ((includeLogs || includeML) && !settings.getBoolean(REMOTE_ACCESS_LOGS, false)) {
+            call.respond(HttpStatusCode.Forbidden)
+            return@post
+        }
+
+        var zipFile: String? = null
+
+        val externalPath = RemoteAccessServer.getInstance(appContext).downloadFolder
+        val logcatZipPath = "$externalPath/logcat.zip"
+
+        // generate logs
+        if (includeLogs) {
+            File(externalPath).mkdirs()
+            RemoteAccessServer.getInstance(appContext).gatherLogs(logcatZipPath)
+        }
+        val dbPath = "$externalPath${Medialibrary.VLC_MEDIA_DB_NAME}"
+
+        //generate ML
+        if (includeML) {
+            File(externalPath).mkdirs()
+            val db = File(appContext.getDir("db", Context.MODE_PRIVATE).toString() + Medialibrary.VLC_MEDIA_DB_NAME)
+            val dbFile = File(dbPath)
+            FileUtils.copyFile(db, dbFile)
+        }
+
+        //Zip needed files
+        if (File(logcatZipPath).exists() || File(dbPath).exists()) {
+            zipFile = "feedback_report.zip"
+            val dbZipPath = "$externalPath/$zipFile"
+            val filesToZip = mutableListOf<String>()
+            if (File(logcatZipPath).exists()) filesToZip.add(logcatZipPath)
+            if (File(dbPath).exists()) filesToZip.add(dbPath)
+            FileUtils.zip(filesToZip.toTypedArray(), dbZipPath)
+            filesToZip.forEach { FileUtils.deleteFile(it) }
+        }
+
+        val completeMessage = "$message\r\n\r\n${FeedbackUtil.generateUsefulInfo(appContext)}"
+
+        val mail = if (feedbackType == 3 && BuildConfig.BETA) FeedbackUtil.SupportType.CRASH_REPORT_EMAIL.email else FeedbackUtil.SupportType.SUPPORT_EMAIL.email
+        val result = RemoteAccessServer.FeedbackResult(mail, FeedbackUtil.generateSubject(subject, feedbackType), completeMessage, zipFile)
+
+        call.respondJson(convertToJson(result))
+    }
     // Get the translation string list
     get("/translation") {
         call.respondJson(convertToJson(TranslationMapping.generateTranslations(appContext.getContextWithLocale(AppContextProvider.locale))))
diff --git a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt
index 609087140d125ed6900d4899e966023ce0467fe6..4de80e452ff7516e46909ebfc08af36dac31cede 100644
--- a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt
+++ b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt
@@ -97,10 +97,12 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder
 import org.slf4j.LoggerFactory
 import org.videolan.libvlc.MediaPlayer
 import org.videolan.libvlc.interfaces.IMedia
+import org.videolan.libvlc.util.AndroidUtil
 import org.videolan.libvlc.util.MediaBrowser
 import org.videolan.medialibrary.MLServiceLocator
 import org.videolan.medialibrary.interfaces.media.MediaWrapper
 import org.videolan.medialibrary.media.MediaLibraryItem
+import org.videolan.resources.AppContextProvider
 import org.videolan.resources.VLCInstance
 import org.videolan.tools.AppScope
 import org.videolan.tools.KEYSTORE_PASSWORD
@@ -109,6 +111,7 @@ import org.videolan.tools.REMOTE_ACCESS_NETWORK_BROWSER_CONTENT
 import org.videolan.tools.Settings
 import org.videolan.tools.SingletonHolder
 import org.videolan.tools.putSingle
+import org.videolan.vlc.DebugLogService
 import org.videolan.vlc.PlaybackService
 import org.videolan.vlc.PlaybackService.Companion.playerSleepTime
 import org.videolan.vlc.gui.DialogActivity
@@ -117,12 +120,14 @@ import org.videolan.vlc.remoteaccessserver.ssl.SecretGenerator
 import org.videolan.vlc.remoteaccessserver.websockets.RemoteAccessWebSockets
 import org.videolan.vlc.remoteaccessserver.websockets.RemoteAccessWebSockets.setupWebSockets
 import org.videolan.vlc.util.FileUtils
+import org.videolan.vlc.util.Permissions
 import org.videolan.vlc.util.isSchemeSMB
 import org.videolan.vlc.viewmodels.CallBackDelegate
 import org.videolan.vlc.viewmodels.ICallBackHandler
 import org.videolan.vlc.viewmodels.browser.IPathOperationDelegate
 import org.videolan.vlc.viewmodels.browser.PathOperationDelegate
 import java.io.File
+import java.io.IOException
 import java.math.BigInteger
 import java.net.InetAddress
 import java.net.NetworkInterface
@@ -164,6 +169,9 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
 
     private val otgDevice = context.getString(org.videolan.vlc.R.string.otg_device_title)
 
+    var client: DebugLogService.Client? = null
+
+
     private val miniPlayerObserver = androidx.lifecycle.Observer<Boolean> { playing ->
         AppScope.launch {
             val isPlaying = service?.isPlaying == true || playing
@@ -324,6 +332,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
         withContext(Dispatchers.IO) {
             RemoteAccessWebSockets.closeAllSessions()
             if (::engine.isInitialized) engine.stop()
+            client?.release()
         }
     }
 
@@ -901,6 +910,90 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
         return list
     }
 
+    suspend fun gatherLogs(logcatZipPath: String) {
+        var waitForClient = true
+        var started = false
+        val gatheringLogsStart = System.currentTimeMillis()
+        //initiate a log to wait for
+        val logMessage = "Starting collecting logs at ${System.currentTimeMillis()}"
+
+        client = DebugLogService.Client(context, object : DebugLogService.Client.Callback {
+            override fun onStarted(logList: List<String>) {
+                started = true
+                Log.d("LogsGathering", logMessage)
+            }
+
+            override fun onStopped() {
+            }
+
+            override fun onLog(msg: String) {
+                //Wait for the log to initiate a save to avoid ANR
+                if (msg.contains(logMessage)) {
+                    if (AndroidUtil.isOOrLater && !Permissions.canWriteStorage())
+                        waitForClient = false
+                    else
+                        client?.save()
+                }
+            }
+
+            override fun onSaved(success: Boolean, path: String) {
+                if (!success) {
+                    client?.stop()
+                    waitForClient = false
+                    return
+                }
+                client?.stop()
+                val filesToAdd = mutableListOf(path)
+                //add previous crash logs
+                try {
+                    AppContextProvider.appContext.getExternalFilesDir(null)?.absolutePath?.let { folder ->
+                        File(folder).listFiles()?.forEach {
+                            if (it.isFile && (it.name.contains("crash_") || it.name.contains("logcat_"))) filesToAdd.add(it.path)
+                        }
+                    }
+                } catch (exception: IOException) {
+                    Log.w("LogsGathering", exception.message, exception)
+                    client?.stop()
+                    return
+                }
+
+                if (!FileUtils.zip(filesToAdd.toTypedArray(), logcatZipPath)) {
+                    client?.stop()
+                    return
+                }
+                try {
+                    filesToAdd.forEach { FileUtils.deleteFile(it) }
+                } catch (exception: IOException) {
+                    Log.w("LogsGathering", exception.message, exception)
+                    client?.stop()
+                    return
+                }
+
+                waitForClient = false
+
+            }
+
+        })
+        while (!started) {
+            delay(100)
+            if (System.currentTimeMillis() > gatheringLogsStart + 4000) {
+                Log.w("LogsGathering", "Failed to start log gathering")
+                started = true
+                waitForClient = false
+            }
+            client?.start() == true
+        }
+        while (waitForClient) {
+            delay(100)
+            if (System.currentTimeMillis() > gatheringLogsStart + 20000) {
+                Log.w("LogsGathering", "Cannot complete log gathering in time")
+                waitForClient = false
+            }
+        }
+        client?.release()
+        client = null
+    }
+
     abstract class WSMessage(val type: WSMessageType)
     data class NowPlaying(val title: String, val artist: String, val playing: Boolean, val isVideoPlaying: Boolean, val progress: Long,
                           val duration: Long, val id: Long, val artworkURL: String, val uri: String, val volume: Int, val speed: Float,
@@ -930,6 +1023,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
     data class ArtistResult(val albums: List<PlayQueueItem>, val tracks: List<PlayQueueItem>, val name: String)
     data class AlbumResult(val tracks: List<PlayQueueItem>, val name: String)
     data class PlaylistResult(val tracks: List<PlayQueueItem>, val name: String)
+    data class FeedbackResult(val mail: String, val subject: String, val message: String, val file: String?)
 
     fun getSecureUrl(call: ApplicationCall) = "https://${call.request.host()}:${engine.environment.connectors.first { it.type.name == "HTTPS" }.port}"
 
diff --git a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/TranslationMapping.kt b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/TranslationMapping.kt
index a1c0e81763571427238fdd52c98c7970346462f8..ad30db9a8a419928c54a06b2cb6374941b76a789 100644
--- a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/TranslationMapping.kt
+++ b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/TranslationMapping.kt
@@ -74,6 +74,7 @@ object TranslationMapping {
         DIRECTORY_EMPTY(R.string.empty_directory),
         FORBIDDEN(R.string.ra_forbidden),
         PLAYBACK_CONTROL_FORBIDDEN(R.string.ra_playback_forbidden),
+        LOGS_CONTROL_FORBIDDEN(R.string.ra_logs_forbidden),
         SEND(R.string.send),
         NEW_CODE(R.string.ra_new_code),
         CODE_REQUEST_EXPLANATION(R.string.ra_code_requested_explanation),
@@ -142,6 +143,30 @@ object TranslationMapping {
         RESUME(R.string.resume),
         CONFIRM_RESUME(R.string.confirm_resume),
         APPLY_PLAYQUEUE(R.string.apply_playqueue),
-        NO(R.string.no)
+        NO(R.string.no),
+        FEEDBACK(R.string.send_feedback),
+        GET_HELP(R.string.get_help),
+        REPORT_A_BUG(R.string.report_a_bug),
+        FEEDBACK_FORUM(R.string.feedback_forum),
+        FEEDBACK_FORUM_URL(R.string.forum_url),
+        FEEDBACK_DOC(R.string.read_doc),
+        FEEDBACK_DOC_URL(R.string.doc_url),
+        FEEDBACK_SUBTITLE(R.string.email_support),
+        FEEDBACK_TYPE(R.string.feedback_type),
+        FEEDBACK_HELP(R.string.get_help),
+        FEEDBACK_FEATURE(R.string.send_feedback_request),
+        FEEDBACK_BUG(R.string.report_a_bug),
+        FEEDBACK_CRASH(R.string.report_crash),
+        FEEDBACK_SUBJECT(R.string.subject),
+        FEEDBACK_MESSAGE(R.string.body),
+        FEEDBACK_MEDIALIBRARY(R.string.include_medialib),
+        FEEDBACK_LOGS(R.string.include_logs),
+        FEEDBACK_GENERATE(R.string.remote_access_feedback_generate),
+        FEEDBACK_PLEASE_WAIT(R.string.please_wait),
+        FEEDBACK_GENERATING_LOGS(R.string.generating_logs),
+        FEEDBACK_GENERATED_TITLE(R.string.remote_access_feedback_generated),
+        FEEDBACK_GENERATED_EXPLANATION(R.string.remote_access_feedback_generated_explanation),
+        FEEDBACK_GENERATED_FILE_EXPLANATION(R.string.remote_access_feedback_file_explanation),
+        COPIED(R.string.generic_copied_to_clipboard),
     }
 }
\ No newline at end of file
diff --git a/application/resources/src/main/java/org/videolan/resources/Constants.kt b/application/resources/src/main/java/org/videolan/resources/Constants.kt
index 35d4e393914d4c74576624bfbb2a9021296d8838..c6b4b15d8995d79e5a1b893f9872264e36e2a99b 100644
--- a/application/resources/src/main/java/org/videolan/resources/Constants.kt
+++ b/application/resources/src/main/java/org/videolan/resources/Constants.kt
@@ -242,6 +242,7 @@ const val TV_SEARCH_ACTIVITY = "org.videolan.television.ui.SearchActivity"
 const val MOBILE_SEARCH_ACTIVITY = "org.videolan.vlc.gui.SearchActivity"
 const val TV_MAIN_ACTIVITY = "org.videolan.television.ui.MainTvActivity"
 const val TV_CONFIRMATION_ACTIVITY = "org.videolan.television.ui.dialogs.ConfirmationTvActivity"
+const val TV_PREFERENCE_ACTIVITY = "org.videolan.television.ui.preferences.PreferencesActivity"
 const val MOBILE_MAIN_ACTIVITY = "org.videolan.vlc.gui.MainActivity"
 const val MOVIEPEDIA_ACTIVITY = "org.videolan.moviepedia.ui.MoviepediaActivity"
 const val TV_AUDIOPLAYER_ACTIVITY = "org.videolan.television.ui.audioplayer.AudioPlayerActivity"
diff --git a/application/resources/src/main/res/values/strings.xml b/application/resources/src/main/res/values/strings.xml
index bedd1553c0ee59d44862ded7f2345d793769391a..1bac59251e4e9f8425b030e1e4009ef1516f71ed 100644
--- a/application/resources/src/main/res/values/strings.xml
+++ b/application/resources/src/main/res/values/strings.xml
@@ -1304,6 +1304,7 @@
     <string name="ra_prepare_download">Preparing your download</string>
     <string name="ra_forbidden">Content disabled in the settings</string>
     <string name="ra_playback_forbidden">Playback control disabled in the settings</string>
+    <string name="ra_logs_forbidden">Logs sharing disabled in the settings</string>
     <string name="ra_code_requested_explanation">To protect your server, the access is protected.\nPlease enter the code displayed in your notifications</string>
     <string name="ra_ssl_explanation_title">Unsecure connection</string>
     <string name="ra_ssl_explanation">Your connection is not secure.</string>
@@ -1395,4 +1396,15 @@
     <string name="generating_logs">Generating logs. Please wait.</string>
     <string name="default_playback_action">Playback action</string>
     <string name="files">Files</string>
+    <string name="remote_access_feedback_generate">Generate report</string>
+    <string name="remote_access_feedback_generated">Your feedback report has been generated</string>
+    <string name="remote_access_feedback_generated_explanation">Tap the button below to send it using your default email client. If you encounter any issues, you can copy paste the fields below and send the email yourself.</string>
+    <string name="remote_access_feedback_file_explanation">You just downloaded the needed file. Please remember to attach it to your email.</string>
+    <string name="generic_copied_to_clipboard">Copied to clipboard</string>
+    <string name="feedback_email_warning">No email client installed</string>
+    <string name="feedback_email_warning_explanation">The easiest way to share your feedback is to use the %1$s feature.\nTo do so, enable the remote access in the settings, follow the instructions and choose the %2$s entry in the menu.</string>
+    <string name="feedback_email_warning_remote_action">Open the settings</string>
+    <string name="feedback_email_warning_try_anyway">Try anyway</string>
+    <string name="forum_url" translatable="false">https://forum.videolan.org/viewforum.php?f=35</string>
+    <string name="doc_url" translatable="false">https://docs.videolan.me/vlc-user/android/</string>
 </resources>
diff --git a/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesActivity.kt b/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesActivity.kt
index 1298ea53fde117c276e6ff1fa985162ee46575e9..f91dfe6c486eb7c5abbe6563790b85e74a47c3ce 100644
--- a/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesActivity.kt
+++ b/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesActivity.kt
@@ -38,9 +38,11 @@ import org.videolan.tools.Settings
 import org.videolan.vlc.PlaybackService
 import org.videolan.vlc.gui.PinCodeActivity
 import org.videolan.vlc.gui.PinCodeReason
+import org.videolan.vlc.gui.preferences.EXTRA_PREF_END_POINT
 
 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
 class PreferencesActivity : BaseTvActivity() {
+    var extraEndPoint: String? = null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -50,6 +52,11 @@ class PreferencesActivity : BaseTvActivity() {
             val intent = PinCodeActivity.getIntent(this, PinCodeReason.CHECK)
             startActivityForResult(intent, 0)
         }
+        if (savedInstanceState == null) {
+            if (intent.hasExtra(EXTRA_PREF_END_POINT)) {
+                extraEndPoint = intent.getStringExtra(EXTRA_PREF_END_POINT)
+            }
+        }
     }
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
diff --git a/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesFragment.kt b/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesFragment.kt
index adc4e5b42394d3e4b76e94f720eb0a4179715df4..f01f5f2cb2e9d24d677020b5a6c117df5e2b7f8e 100644
--- a/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesFragment.kt
+++ b/application/television/src/main/java/org/videolan/television/ui/preferences/PreferencesFragment.kt
@@ -35,9 +35,24 @@ import androidx.preference.CheckBoxPreference
 import androidx.preference.Preference
 import androidx.preference.PreferenceScreen
 import org.videolan.medialibrary.interfaces.Medialibrary
-import org.videolan.resources.*
-import org.videolan.tools.*
+import org.videolan.resources.AndroidDevices
+import org.videolan.resources.KEY_AUDIO_LAST_PLAYLIST
+import org.videolan.resources.KEY_CURRENT_AUDIO
+import org.videolan.resources.KEY_CURRENT_AUDIO_RESUME_ARTIST
+import org.videolan.resources.KEY_CURRENT_AUDIO_RESUME_THUMB
+import org.videolan.resources.KEY_CURRENT_AUDIO_RESUME_TITLE
+import org.videolan.resources.KEY_CURRENT_MEDIA
+import org.videolan.resources.KEY_CURRENT_MEDIA_RESUME
+import org.videolan.resources.KEY_MEDIA_LAST_PLAYLIST
+import org.videolan.resources.KEY_MEDIA_LAST_PLAYLIST_RESUME
+import org.videolan.tools.AUDIO_RESUME_PLAYBACK
+import org.videolan.tools.KEY_VIDEO_APP_SWITCH
+import org.videolan.tools.PLAYBACK_HISTORY
+import org.videolan.tools.RESULT_RESTART
+import org.videolan.tools.SCREEN_ORIENTATION
+import org.videolan.tools.Settings
 import org.videolan.tools.Settings.isPinCodeSet
+import org.videolan.tools.VIDEO_RESUME_PLAYBACK
 import org.videolan.vlc.R
 import org.videolan.vlc.gui.PinCodeActivity
 import org.videolan.vlc.gui.PinCodeReason
@@ -60,6 +75,12 @@ class PreferencesFragment : BasePreferenceFragment(), SharedPreferences.OnShared
         findPreference<Preference>(KEY_VIDEO_APP_SWITCH)?.isVisible = AndroidDevices.hasPiP
         findPreference<Preference>("remote_access_category")?.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
         findPreference<Preference>("permissions_title")?.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
+        (activity as? PreferencesActivity)?.extraEndPoint?.let {
+            if (it == "remote_access_category") findPreference<Preference>("remote_access_category")?.let {
+                onPreferenceTreeClick(it)
+                (activity as? PreferencesActivity)?.extraEndPoint = null
+            }
+        }
     }
 
     override fun onStart() {
diff --git a/application/vlc-android/AndroidManifest.xml b/application/vlc-android/AndroidManifest.xml
index 0b8afcb7c5d4801a455b28f119361e4f4da43263..d8a54c8fb1cbcd14433bcb0b6ef021877a380de8 100644
--- a/application/vlc-android/AndroidManifest.xml
+++ b/application/vlc-android/AndroidManifest.xml
@@ -57,6 +57,13 @@
         android:name="android.hardware.bluetooth"
         android:required="false"/>
 
+    <queries>
+        <intent>
+            <action android:name="android.intent.action.SENDTO" />
+            <data android:scheme="mailto" />
+        </intent>
+    </queries>
+
     <application>
 
         <!-- Enable VLC in Samsung multiwindow mode -->
diff --git a/application/vlc-android/res/layout/about_feedback_activity.xml b/application/vlc-android/res/layout/about_feedback_activity.xml
index 378bb06e8842eda5ef7aa2e6142748d85d9f7289..92821a6528ac4e67c96331fb1c77af4066692087 100644
--- a/application/vlc-android/res/layout/about_feedback_activity.xml
+++ b/application/vlc-android/res/layout/about_feedback_activity.xml
@@ -270,17 +270,98 @@
                                     app:layout_constraintStart_toStartOf="parent"
                                     app:layout_constraintTop_toBottomOf="@+id/email_support_summary" />
 
+                            <androidx.constraintlayout.widget.ConstraintLayout
+                                    android:id="@+id/email_warning"
+                                    android:layout_width="match_parent"
+                                    android:layout_height="match_parent"
+                                    android:layout_marginTop="8dp"
+                                    android:visibility="gone"
+                                    app:layout_constraintEnd_toEndOf="parent"
+                                    app:layout_constraintStart_toStartOf="parent"
+                                    app:layout_constraintTop_toTopOf="@+id/contact_separator"
+                                    tools:visibility="visible">
+
+                                <ImageView
+                                        android:id="@+id/email_warning_image"
+                                        android:layout_width="wrap_content"
+                                        android:layout_height="wrap_content"
+                                        android:layout_marginStart="8dp"
+                                        android:layout_marginTop="8dp"
+                                        android:padding="8dp"
+                                        app:layout_constraintEnd_toStartOf="@+id/email_warning_title"
+                                        app:layout_constraintHorizontal_bias="0.5"
+                                        app:layout_constraintStart_toStartOf="parent"
+                                        app:layout_constraintTop_toTopOf="parent"
+                                        app:srcCompat="@drawable/ic_warning_small"
+                                        app:tint="?attr/colorPrimary" />
+
+                                <TextView
+                                        android:id="@+id/email_warning_title"
+                                        style="@style/VLC.TextViewTitle"
+                                        android:layout_width="0dp"
+                                        android:layout_height="wrap_content"
+                                        android:layout_marginStart="8dp"
+                                        android:layout_marginEnd="16dp"
+                                        android:fontFamily="sans-serif-medium"
+                                        android:text="@string/feedback_email_warning"
+                                        android:textColor="?attr/colorPrimary"
+                                        android:textSize="14sp"
+                                        app:layout_constraintBottom_toBottomOf="@+id/email_warning_image"
+                                        app:layout_constraintEnd_toEndOf="parent"
+                                        app:layout_constraintHorizontal_bias="0.5"
+                                        app:layout_constraintStart_toEndOf="@+id/email_warning_image"
+                                        app:layout_constraintTop_toTopOf="@+id/email_warning_image" />
+
+                                <TextView
+                                        android:id="@+id/email_warning_explanation"
+                                        style="@style/VLC.TextViewTitle"
+                                        android:layout_width="0dp"
+                                        android:layout_height="wrap_content"
+                                        android:layout_marginStart="16dp"
+                                        android:layout_marginTop="24dp"
+                                        android:layout_marginEnd="16dp"
+                                        android:text="@string/feedback_email_warning_explanation"
+                                        android:textSize="14sp"
+                                        app:layout_constraintEnd_toEndOf="parent"
+                                        app:layout_constraintStart_toStartOf="parent"
+                                        app:layout_constraintTop_toBottomOf="@+id/email_warning_title" />
+
+                                <Button
+                                        android:id="@+id/try_anyway"
+                                        style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
+                                        android:layout_width="wrap_content"
+                                        android:layout_height="wrap_content"
+                                        android:layout_marginEnd="8dp"
+                                        android:text="@string/feedback_email_warning_try_anyway"
+                                        android:textColor="?attr/font_light"
+                                        app:layout_constraintEnd_toStartOf="@+id/open_settings"
+                                        app:layout_constraintTop_toTopOf="@+id/open_settings" />
+
+                                <Button
+                                        android:id="@+id/open_settings"
+                                        style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
+                                        android:layout_width="wrap_content"
+                                        android:layout_height="wrap_content"
+                                        android:layout_marginTop="16dp"
+                                        android:layout_marginEnd="16dp"
+                                        android:text="@string/feedback_email_warning_remote_action"
+                                        app:layout_constraintEnd_toEndOf="parent"
+                                        app:layout_constraintTop_toBottomOf="@+id/email_warning_explanation" />
+
+                            </androidx.constraintlayout.widget.ConstraintLayout>
+
+
                             <com.google.android.material.textfield.TextInputLayout
                                     android:id="@+id/feedback_type"
                                     style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
                                     android:layout_width="match_parent"
                                     android:layout_height="wrap_content"
                                     android:layout_marginStart="16dp"
-                                    android:layout_marginTop="8dp"
+                                    android:layout_marginTop="16dp"
                                     android:layout_marginEnd="16dp"
                                     app:layout_constraintEnd_toEndOf="parent"
                                     app:layout_constraintStart_toStartOf="parent"
-                                    app:layout_constraintTop_toBottomOf="@+id/contact_separator">
+                                    app:layout_constraintTop_toBottomOf="@+id/email_warning">
 
                                 <AutoCompleteTextView
                                         android:id="@+id/feedback_type_entry"
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/FeedbackActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/FeedbackActivity.kt
index 960c4a4a17b905ff06270400efef17380ede4435..c5614aa3ae4cf869993dbce36bbfc239850509e6 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/FeedbackActivity.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/FeedbackActivity.kt
@@ -24,9 +24,11 @@
 
 package org.videolan.vlc.gui
 
+import android.content.Intent
 import android.os.Bundle
 import android.util.Log
 import android.view.MenuItem
+import androidx.core.net.toUri
 import androidx.core.widget.addTextChangedListener
 import androidx.databinding.DataBindingUtil
 import androidx.lifecycle.lifecycleScope
@@ -43,7 +45,9 @@ import org.videolan.resources.AppContextProvider
 import org.videolan.resources.CRASH_HAPPENED
 import org.videolan.resources.CRASH_ML_CTX
 import org.videolan.resources.CRASH_ML_MSG
+import org.videolan.resources.TV_PREFERENCE_ACTIVITY
 import org.videolan.resources.util.applyOverscanMargin
+import org.videolan.tools.Settings
 import org.videolan.tools.isVisible
 import org.videolan.tools.setGone
 import org.videolan.tools.setVisible
@@ -53,6 +57,8 @@ import org.videolan.vlc.R
 import org.videolan.vlc.databinding.AboutFeedbackActivityBinding
 import org.videolan.vlc.gui.helpers.FeedbackUtil
 import org.videolan.vlc.gui.helpers.UiTools
+import org.videolan.vlc.gui.preferences.EXTRA_PREF_END_POINT
+import org.videolan.vlc.gui.preferences.PreferencesActivity
 import org.videolan.vlc.util.FileUtils
 import org.videolan.vlc.util.Permissions
 import org.videolan.vlc.util.TextUtils
@@ -170,26 +176,41 @@ class FeedbackActivity : BaseActivity(), DebugLogService.Client.Callback {
         binding.feedbackTypeEntry.addTextChangedListener {
             updateFormIncludesVisibility()
         }
+        binding.feedbackTypeEntry.setOnClickListener {
+            binding.feedbackTypeEntry.showDropDown()
+        }
         binding.feedbackTypeEntry.setText(feedbackTypeEntries[0], false)
+        binding.emailWarningExplanation.text = getString(R.string.feedback_email_warning_explanation, getString(R.string.remote_access), getString(R.string.send_feedback))
+        binding.tryAnyway.setOnClickListener {
+            binding.emailWarning.setGone()
+            switchFormVisibility()
+            updateFormIncludesVisibility()
+        }
+        binding.openSettings.setOnClickListener {
+            lifecycleScope.launch {
+                if (Settings.tvUI) {
+                    val intent = Intent(Intent.ACTION_VIEW).setClassName(this@FeedbackActivity, TV_PREFERENCE_ACTIVITY)
+                    intent.putExtra(EXTRA_PREF_END_POINT, "remote_access_category")
+                    startActivity(intent)
+                }
+                else
+                    PreferencesActivity.launchWithPref(this@FeedbackActivity, "enable_remote_access")
+            }
+        }
         binding.emailSupportCard.setOnClickListener {
-            if (binding.emailSupportForm.isVisible()) {
-                binding.emailSupportForm.setGone()
-                UiTools.setKeyboardVisibility(binding.messageTextInputLayout, false)
-                binding.emailSupportCard.nextFocusDownId = R.id.read_doc_card
-                binding.emailSupportCard.nextFocusRightId = R.id.read_doc_card
+            if (!isMailClientPresent()) {
+                switchNoEmailVisibility()
             } else {
-                binding.emailSupportForm.setVisible()
-                binding.emailSupportCard.nextFocusDownId = R.id.feedback_type_entry
-                binding.emailSupportCard.nextFocusRightId = R.id.feedback_type_entry
+                switchFormVisibility()
+                updateFormIncludesVisibility()
             }
 
-            updateFormIncludesVisibility()
         }
         binding.feedbackForumCard.setOnClickListener {
-            openLinkIfPossible("https://forum.videolan.org/viewforum.php?f=35")
+            openLinkIfPossible(getString(R.string.forum_url))
         }
         binding.readDocCard.setOnClickListener {
-            openLinkIfPossible("https://docs.videolan.me/vlc-user/android/")
+            openLinkIfPossible(getString(R.string.doc_url))
         }
         binding.emailSupportSend.setOnClickListener {
             if (binding.includeLogs.isChecked) {
@@ -226,16 +247,46 @@ class FeedbackActivity : BaseActivity(), DebugLogService.Client.Callback {
         }
     }
 
+    private fun switchFormVisibility(forceHide: Boolean = false) {
+        if (forceHide || binding.emailSupportForm.isVisible()) {
+            binding.emailSupportForm.setGone()
+            UiTools.setKeyboardVisibility(binding.messageTextInputLayout, false)
+            binding.emailSupportCard.nextFocusDownId = R.id.read_doc_card
+            binding.emailSupportCard.nextFocusRightId = R.id.read_doc_card
+        } else {
+            binding.emailSupportForm.setVisible()
+            binding.emailSupportCard.nextFocusDownId = R.id.feedback_type_entry
+            binding.emailSupportCard.nextFocusRightId = R.id.feedback_type_entry
+        }
+    }
+
+    private fun switchNoEmailVisibility() {
+        switchFormVisibility(true)
+        if (!binding.emailWarning.isVisible()) {
+            binding.emailWarning.setVisible()
+            binding.emailSupportCard.nextFocusDownId = R.id.open_settings
+            binding.emailSupportCard.nextFocusRightId = R.id.open_settings
+        } else {
+            binding.emailWarning.setGone()
+            binding.emailSupportCard.nextFocusDownId = R.id.read_doc_card
+            binding.emailSupportCard.nextFocusRightId = R.id.read_doc_card
+        }
+    }
+
+    fun isMailClientPresent(): Boolean {
+        val intent = Intent(Intent.ACTION_SENDTO, "mailto:".toUri())
+        val unsupportedActions = arrayOf("com.android.tv.frameworkpackagestubs", "com.google.android.tv.frameworkpackagestubs", "com.android.fallback")
+        val resolved = try {
+            intent.resolveActivity(packageManager)
+        } catch (e: Exception) {
+            return false
+        }
+        return resolved != null && resolved.packageName !in unsupportedActions
+    }
+
     private fun sendEmail(includeLogs: Boolean = false) {
         val feedbackTypePosition = feedbackTypeEntries.indexOf(binding.feedbackTypeEntry.text.toString())
         val isCrashFromML = !mlErrorContext.isNullOrEmpty() || !mlErrorMessage.isNullOrEmpty()
-        val subjectPrepend = when {
-            isCrashFromML -> "[ML Crash]"
-            feedbackTypePosition == 0 -> "[Help] "
-            feedbackTypePosition == 1 -> "[Feedback/Request] "
-            feedbackTypePosition == 2 -> "[Bug] "
-            else -> "[Crash] "
-        }
         val mail = if (BuildConfig.BETA && feedbackTypePosition > 2) FeedbackUtil.SupportType.CRASH_REPORT_EMAIL else FeedbackUtil.SupportType.SUPPORT_EMAIL
         lifecycleScope.launch {
             val message = if (isCrashFromML)
@@ -248,15 +299,19 @@ class FeedbackActivity : BaseActivity(), DebugLogService.Client.Callback {
                     append("ML Context: $mlErrorContext<br />ML error message: $mlErrorMessage")
                 }
             else binding.messageTextInputLayout.editText?.text.toString()
-            FeedbackUtil.sendEmail(
+            if (!FeedbackUtil.sendEmail(
                 this@FeedbackActivity,
                 mail,
                 binding.showIncludes && binding.includeMedialibrary.isChecked,
                 message,
-                subjectPrepend + binding.subjectTextInputLayout.editText?.text.toString(),
+                binding.subjectTextInputLayout.editText?.text.toString(),
+                if (isCrashFromML) 100 else feedbackTypePosition,
                 if (includeLogs) logcatZipPath else null
-            )
-            finish()
+            )) {
+                UiTools.snacker(this@FeedbackActivity, R.string.feedback_email_warning)
+                switchNoEmailVisibility()
+            } else
+                finish()
         }
     }
 
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/FeedbackUtil.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/FeedbackUtil.kt
index da56fa776d54e15e56fdc91d1897e5a228da2e2f..eb685e990a50f9d1fa05d5281912a7cfdf412048 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/FeedbackUtil.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/FeedbackUtil.kt
@@ -53,9 +53,11 @@ object FeedbackUtil {
      * @param includeMedialibrary Whether to include the medialibrary database or not
      * @param message Message to send
      * @param subject Subject of the email
+     * @param feedbackType Type of feedback
      * @param logcatZipPath Path to the logcat zip file
+     * @return true if the email was sent, false otherwise
      */
-    suspend fun sendEmail(activity: FragmentActivity, supportType: SupportType, includeMedialibrary: Boolean, message: String, subject: String, logcatZipPath: String? = null) {
+    suspend fun sendEmail(activity: FragmentActivity, supportType: SupportType, includeMedialibrary: Boolean, message: String, subject: String, feedbackType: Int, logcatZipPath: String? = null): Boolean {
         val emailIntent = withContext(Dispatchers.IO) {
 
             val emailIntent = Intent(Intent.ACTION_SEND_MULTIPLE)
@@ -87,12 +89,28 @@ object FeedbackUtil {
 
             val htmlBody = HtmlCompat.fromHtml(body, HtmlCompat.FROM_HTML_MODE_LEGACY)
             emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(supportType.email))
-            emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
+            emailIntent.putExtra(Intent.EXTRA_SUBJECT, generateSubject(subject, feedbackType))
             emailIntent.putExtra(Intent.EXTRA_TEXT, htmlBody)
             emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
             emailIntent
         }
-        emailIntent?.let { activity.startActivity(it) }
+        try {
+            emailIntent?.let { activity.startActivity(it) }
+            return true
+        } catch (_: Exception) {
+            return false
+        }
+    }
+
+    fun generateSubject(initialSubject: String, feedbackType: Int): String {
+        val subjectPrepend = when (feedbackType) {
+            0 -> "[Help] "
+            1 -> "[Feedback/Request] "
+            2 -> "[Bug] "
+            3 -> "[Crash] "
+            else -> "[ML Crash]"
+        }
+        return subjectPrepend + initialSubject
     }
 
     fun generateUsefulInfo(context: Context) = buildString {
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
index 436be9b17a5e08bf0b2d2b2eb8f3cd688df89f66..c67f97cbe670bce18ece35fbbc3130022dac303f 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
@@ -513,9 +513,6 @@ object UiTools {
         v.findViewById<View>(R.id.about_website_container).setOnClickListener {
             activity.openLinkIfPossible("https://www.videolan.org/vlc/")
         }
-//        v.findViewById<View>(R.id.about_forum_container).setOnClickListener {
-//            activity.openLinkIfPossible("https://forum.videolan.org/viewforum.php?f=35")
-//        }
         v.findViewById<View>(R.id.about_report_container).setOnClickListener {
             activity.startActivity(Intent(activity, FeedbackActivity::class.java))
         }
diff --git a/build.gradle b/build.gradle
index e84b88f9fbeaea1689c0f375134b648de8eb2cfc..7701812d45fe2b05d288464d418d5b73719829cb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -46,7 +46,7 @@ ext {
     versionCode = 3060340
     versionName = project.hasProperty('forceVlc4') && project.getProperty('forceVlc4') ? '4.0.0-preview - ' + versionCode : '3.6.4 Beta 4'
     vlcMajorVersion = project.hasProperty('forceVlc4') && project.getProperty('forceVlc4') ? 4 : 3
-    remoteAccessVersion = '0.5.0'
+    remoteAccessVersion = '0.6.0'
     libvlcVersion = vlcMajorVersion == 3 ? '3.6.2' :'4.0.0-eap20'
     medialibraryVersion = vlcMajorVersion == 3 ? '0.13.13-rc17' : '0.13.13-vlc4-rc17'
     minSdkVersion = 17
diff --git a/buildsystem/compile-remoteaccess.sh b/buildsystem/compile-remoteaccess.sh
index 81a716491451443bce163c921a53370da9534671..1e88d87dd2a9041daee99f44f746f82e745a2750 100755
--- a/buildsystem/compile-remoteaccess.sh
+++ b/buildsystem/compile-remoteaccess.sh
@@ -57,7 +57,7 @@ done
 ##############################
   diagnostic "Setting up the Remote Access project"
 
-  REMOTE_ACCESS_TESTED_HASH=a0fb5c209f506da0dd1cb1f9ff01b9f9a49eb489
+  REMOTE_ACCESS_TESTED_HASH=bc7a94b38ca21739e21ba3f76dab09909d75a695
   REMOTE_ACCESS_REPOSITORY=https://code.videolan.org/videolan/remoteaccess
 
   : ${VLC_REMOTE_ACCESS_PATH:="$(pwd -P)/application/remote-access-client/remoteaccess"}