[Android] Properly update TV Channel
Geoffrey Métais
git at videolan.org
Wed Mar 6 15:10:25 CET 2019
vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Fri Mar 1 18:20:49 2019 +0100| [e6615b0dc85d4d6989a1b94b028d85e06842c3fa] | committer: Geoffrey Métais
Properly update TV Channel
> https://code.videolan.org/videolan/vlc-android/commit/e6615b0dc85d4d6989a1b94b028d85e06842c3fa
---
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