[Android] Properly update TV Channel

Geoffrey Métais git at videolan.org
Wed Mar 6 15:43:08 CET 2019


vlc-android | branch: 3.1.x | Geoffrey Métais <geoffrey.metais at gmail.com> | Fri Mar  1 18:20:49 2019 +0100| [90c3f40647bdf385fbf215fcd07d73577ea136a5] | committer: Geoffrey Métais

Properly update TV Channel

(cherry picked from commit e6615b0dc85d4d6989a1b94b028d85e06842c3fa)

> https://code.videolan.org/videolan/vlc-android/commit/90c3f40647bdf385fbf215fcd07d73577ea136a5
---

 vlc-android/src/org/videolan/vlc/TvReceiver.java   |  1 +
 .../src/org/videolan/vlc/util/Kextensions.kt       | 10 +++++++
 .../org/videolan/vlc/util/ThumbnailsProvider.java  |  1 +
 .../src/org/videolan/vlc/util/TvChannels.kt        | 35 ++++++++++------------
 .../src/org/videolan/vlc/viewmodels/VideosModel.kt | 13 ++++++++
 5 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/TvReceiver.java b/vlc-android/src/org/videolan/vlc/TvReceiver.java
index fc600ecd5..f6049464d 100644
--- a/vlc-android/src/org/videolan/vlc/TvReceiver.java
+++ b/vlc-android/src/org/videolan/vlc/TvReceiver.java
@@ -69,6 +69,7 @@ public class TvReceiver extends BroadcastReceiver {
             case Intent.ACTION_BOOT_COMPLETED:
                 Log.d(TAG, "onReceive: ACTION_BOOT_COMPLETED ");
                 if (!AndroidUtil.isOOrLater) scheduleRecommendationUpdate(context);
+                else TvChannelsKt.launchChannelUpdate(context);
                 if (AndroidDevices.watchDevices) StoragesMonitorKt.enableStorageMonitoring(context);
                 break;
         }
diff --git a/vlc-android/src/org/videolan/vlc/util/Kextensions.kt b/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
index 7f5c79e39..8e5dd56ca 100644
--- a/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
+++ b/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
@@ -2,6 +2,7 @@ package org.videolan.vlc.util
 
 import android.content.Context
 import android.content.SharedPreferences
+import android.content.res.Resources
 import android.net.Uri
 import android.widget.TextView
 import androidx.appcompat.widget.AppCompatTextView
@@ -24,6 +25,9 @@ import java.net.URI
 import java.net.URISyntaxException
 import java.util.*
 import kotlin.coroutines.resume
+import android.util.DisplayMetrics
+
+
 
 object Settings : SingletonHolder<SharedPreferences, Context>({ PreferenceManager.getDefaultSharedPreferences(it) })
 
@@ -148,3 +152,9 @@ fun asyncText(view: TextView, text: CharSequence?) {
 }
 
 fun isAppStarted() = ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
+
+fun Int.toPixel(): Int {
+    val metrics = Resources.getSystem().displayMetrics
+    val px = toFloat() * (metrics.densityDpi / 160f)
+    return Math.round(px)
+}
diff --git a/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java b/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java
index 351c76392..6b81f9703 100644
--- a/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java
+++ b/vlc-android/src/org/videolan/vlc/util/ThumbnailsProvider.java
@@ -81,6 +81,7 @@ public class ThumbnailsProvider {
             if (hasCache) {
                 media.setThumbnail(thumbPath);
                 saveOnDisk(bitmap, thumbPath);
+                media.setArtworkURL(thumbPath);
             }
         } else if (media.getId() != 0L) {
             Medialibrary.getInstance().requestThumbnail(media.getId());
diff --git a/vlc-android/src/org/videolan/vlc/util/TvChannels.kt b/vlc-android/src/org/videolan/vlc/util/TvChannels.kt
index 0e1530d0e..6219cb13b 100644
--- a/vlc-android/src/org/videolan/vlc/util/TvChannels.kt
+++ b/vlc-android/src/org/videolan/vlc/util/TvChannels.kt
@@ -31,11 +31,11 @@ import androidx.annotation.RequiresApi
 import androidx.tvprovider.media.tv.TvContractCompat
 import androidx.tvprovider.media.tv.WatchNextProgram
 import kotlinx.coroutines.*
-import org.videolan.medialibrary.Medialibrary
 import org.videolan.medialibrary.media.MediaWrapper
-import org.videolan.vlc.*
 import org.videolan.vlc.BuildConfig
+import org.videolan.vlc.PreviewVideoInputService
 import org.videolan.vlc.R
+import org.videolan.vlc.getFileUri
 import videolan.org.commontools.*
 
 
@@ -53,26 +53,10 @@ fun setChannel(context: Context) = GlobalScope.launch(start = CoroutineStart.UND
     if (Permissions.canReadStorage(context)) updatePrograms(context, channelId)
 }
 
-suspend fun updatePrograms(context: Context, channelId: Long) {
+private suspend fun updatePrograms(context: Context, channelId: Long) {
     if (channelId == -1L) return
-    val ml = Medialibrary.getInstance()
-    if (!ml.isStarted) {
-        ml.addOnMedialibraryReadyListener(object : Medialibrary.OnMedialibraryReadyListener {
-            override fun onMedialibraryIdle() {}
-            override fun onMedialibraryReady() {
-                val listener = this
-                GlobalScope.launch {
-                    ml.removeOnMedialibraryReadyListener(listener)
-                    updatePrograms(context, channelId)
-                }
-            }
-
-        })
-        context.startMedialibrary(false, false, false)
-        return
-    }
+    val videoList = context.getFromMl { recentVideos }
     val programs = withContext(Dispatchers.IO) { existingPrograms(context, channelId) }
-    val videoList = withContext(Dispatchers.IO) { VLCApplication.getMLInstance().recentVideos }
     if (Util.isArrayEmpty(videoList)) return
     val cn = ComponentName(context, PreviewVideoInputService::class.java)
     for ((count, mw) in videoList.withIndex()) {
@@ -82,6 +66,12 @@ suspend fun updatePrograms(context: Context, channelId: Long) {
             programs.removeAt(index)
             continue
         }
+        if (mw.isThumbnailGenerated) {
+            if (mw.artworkMrl === null) continue
+        } else if (withContext(Dispatchers.IO) { ThumbnailsProvider.getMediaThumbnail(mw, 272.toPixel()) } === null
+                || mw.artworkMrl === null) {
+            continue
+        }
         val desc = ProgramDesc(channelId, mw.id, mw.title, mw.description,
                 mw.artUri(), mw.length.toInt(), mw.time.toInt(),
                 mw.width, mw.height, BuildConfig.APPLICATION_ID)
@@ -96,6 +86,11 @@ suspend fun updatePrograms(context: Context, channelId: Long) {
     }
 }
 
+fun Context.launchChannelUpdate() = AppScope.launch {
+    val id = withContext(Dispatchers.IO) { Settings.getInstance(this at launchChannelUpdate).getLong(KEY_TV_CHANNEL_ID, -1L) }
+    updatePrograms(this at launchChannelUpdate, id)
+}
+
 fun setResumeProgram(context: Context, mw: MediaWrapper) {
     var cursor: Cursor? = null
     var isProgramPresent = false
diff --git a/vlc-android/src/org/videolan/vlc/viewmodels/VideosModel.kt b/vlc-android/src/org/videolan/vlc/viewmodels/VideosModel.kt
index a8147a65c..459837b0f 100644
--- a/vlc-android/src/org/videolan/vlc/viewmodels/VideosModel.kt
+++ b/vlc-android/src/org/videolan/vlc/viewmodels/VideosModel.kt
@@ -20,7 +20,10 @@
 
 package org.videolan.vlc.viewmodels
 
+import android.annotation.TargetApi
 import android.content.Context
+import android.content.Intent
+import android.os.Build
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.Observer
 import androidx.lifecycle.ViewModel
@@ -30,13 +33,17 @@ import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.withContext
+import org.videolan.libvlc.util.AndroidUtil
 import org.videolan.medialibrary.Medialibrary
 import org.videolan.medialibrary.media.Folder
 import org.videolan.medialibrary.media.MediaWrapper
 import org.videolan.vlc.R
+import org.videolan.vlc.RecommendationsService
 import org.videolan.vlc.media.MediaGroup
 import org.videolan.vlc.media.getAll
+import org.videolan.vlc.util.AndroidDevices
 import org.videolan.vlc.util.Settings
+import org.videolan.vlc.util.launchChannelUpdate
 
 @ExperimentalCoroutinesApi
 open class VideosModel(context: Context, private val group: String?, val folder : Folder?, private val minGroupLen: Int, customSort : Int, customDesc: Boolean?) : MedialibraryModel<MediaWrapper>(context), Medialibrary.MediaCb {
@@ -67,6 +74,12 @@ open class VideosModel(context: Context, private val group: String?, val folder
         refresh()
     }
 
+    @TargetApi(Build.VERSION_CODES.O)
+    override fun onMedialibraryIdle() {
+        super.onMedialibraryIdle()
+        if (AndroidDevices.isAndroidTv && AndroidUtil.isOOrLater) context.launchChannelUpdate()
+    }
+
     override fun onMediaDeleted() {
         refresh()
     }



More information about the Android mailing list