[Android] Prevent crash on Oreo when loadlastplaylist fails
Geoffrey Métais
git at videolan.org
Thu Apr 12 17:21:31 CEST 2018
vlc-android | branch: 3.0.x | Geoffrey Métais <geoffrey.metais at gmail.com> | Thu Apr 12 17:21:09 2018 +0200| [57ebfe3fc744ffda6c378b64e4cb26dc3771b535] | committer: Geoffrey Métais
Prevent crash on Oreo when loadlastplaylist fails
> https://code.videolan.org/videolan/vlc-android/commit/57ebfe3fc744ffda6c378b64e4cb26dc3771b535
---
.../src/org/videolan/vlc/PlaybackService.java | 45 +++++++++++++++++-----
.../src/org/videolan/vlc/media/PlaylistManager.kt | 32 ++++++++-------
2 files changed, 51 insertions(+), 26 deletions(-)
diff --git a/vlc-android/src/org/videolan/vlc/PlaybackService.java b/vlc-android/src/org/videolan/vlc/PlaybackService.java
index 92931f089..87cba3c81 100644
--- a/vlc-android/src/org/videolan/vlc/PlaybackService.java
+++ b/vlc-android/src/org/videolan/vlc/PlaybackService.java
@@ -250,6 +250,7 @@ public class PlaybackService extends MediaBrowserServiceCompat{
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
+ if (AndroidUtil.isOOrLater && !VLCApplication.isForeground()) forceForeground();
if (intent == null) return START_NOT_STICKY;
final String action = intent.getAction();
if (Intent.ACTION_MEDIA_BUTTON.equals(action)) {
@@ -263,8 +264,7 @@ public class PlaybackService extends MediaBrowserServiceCompat{
if (playlistManager.hasCurrentMedia()) play();
else loadLastAudioPlaylist();
} else if (Constants.ACTION_PLAY_FROM_SEARCH.equals(action)) {
- if (mMediaSession == null)
- initMediaSession();
+ if (mMediaSession == null) initMediaSession();
final Bundle extras = intent.getBundleExtra(Constants.EXTRA_SEARCH_BUNDLE);
mMediaSession.getController().getTransportControls()
.playFromSearch(extras.getString(SearchManager.QUERY), extras);
@@ -1194,13 +1194,40 @@ public class PlaybackService extends MediaBrowserServiceCompat{
private void loadLastAudioPlaylist() {
if (AndroidDevices.isAndroidTv) return;
- if (mMedialibrary.isInitiated() && mLibraryReceiver == null) playlistManager.loadLastPlaylist(Constants.PLAYLIST_TYPE_AUDIO);
- else registerMedialibrary(new Runnable() {
- @Override
- public void run() {
- playlistManager.loadLastPlaylist(Constants.PLAYLIST_TYPE_AUDIO);
- }
- });
+ if (mMedialibrary.isInitiated() && mLibraryReceiver == null) {
+ if (!playlistManager.loadLastPlaylist(Constants.PLAYLIST_TYPE_AUDIO)) stopSelf();
+ } else registerMedialibrary(new Runnable() {
+ @Override
+ public void run() {
+ if (!playlistManager.loadLastPlaylist(Constants.PLAYLIST_TYPE_AUDIO)) stopSelf();
+ }
+ });
+ }
+
+ private void forceForeground() {
+ final Context ctx = PlaybackService.this;
+ final MediaSessionCompat.Token sessionToken = mMediaSession.getSessionToken();
+ final Notification notification = NotificationHelper.createPlaybackNotification(ctx,
+ false, ctx.getResources().getString(R.string.loading), "", "",
+ null, false, sessionToken, getSessionPendingIntent());
+ PlaybackService.this.startForeground(3, notification);
+ mIsForeground = true;
+ ExecutorHolder.executorService.execute(new Runnable() {
+ @Override
+ public void run() {
+ final Bitmap cover = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.ic_no_media);
+ VLCApplication.runOnMainThread(new Runnable() {
+ @Override
+ public void run() {
+ final Notification notification = NotificationHelper.createPlaybackNotification(ctx,
+ false, ctx.getResources().getString(R.string.loading), "", "",
+ cover, false, sessionToken, getSessionPendingIntent());
+ PlaybackService.this.startForeground(3, notification);
+ mIsForeground = true;
+ }
+ });
+ }
+ });
}
public void loadLastPlaylist(int type) {
diff --git a/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt b/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt
index 7440148a2..7e4c047da 100644
--- a/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt
+++ b/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt
@@ -26,13 +26,12 @@ import org.videolan.vlc.gui.video.VideoPlayerActivity
import org.videolan.vlc.util.*
import java.util.*
+private const val TAG = "VLC/PlaylistManager"
+private const val PREVIOUS_LIMIT_DELAY = 5000L
+private const val AUDIO_REPEAT_MODE_KEY = "audio_repeat_mode"
class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventListener, Media.EventListener {
- private val TAG = "VLC/PlaylistManager"
- private val PREVIOUS_LIMIT_DELAY = 5000L
- private val AUDIO_REPEAT_MODE_KEY = "audio_repeat_mode"
-
private val medialibrary by lazy(LazyThreadSafetyMode.NONE) { Medialibrary.getInstance() }
val player by lazy(LazyThreadSafetyMode.NONE) { PlayerController() }
private val settings by lazy(LazyThreadSafetyMode.NONE) { PreferenceManager.getDefaultSharedPreferences(service) }
@@ -83,11 +82,11 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
var mediaWrapper = medialibrary.getMedia(location)
if (mediaWrapper === null) {
if (!location.validateLocation()) {
- Log.w(TAG, "Invalid location " + location)
+ Log.w(TAG, "Invalid location $location")
service.showToast(service.resources.getString(R.string.invalid_location, location), Toast.LENGTH_SHORT)
continue
}
- Log.v(TAG, "Creating on-the-fly Media object for " + location)
+ Log.v(TAG, "Creating on-the-fly Media object for $location")
mediaWrapper = MediaWrapper(Uri.parse(location))
}
mediaList.add(mediaWrapper)
@@ -114,15 +113,15 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
@Volatile
private var loadingLastPlaylist = false
- fun loadLastPlaylist(type: Int) {
- if (loadingLastPlaylist) return
+ fun loadLastPlaylist(type: Int) : Boolean {
+ if (loadingLastPlaylist) return false
loadingLastPlaylist = true
+ val audio = type == Constants.PLAYLIST_TYPE_AUDIO
+ val currentMedia = settings.getString(if (audio) "current_song" else "current_media", "")
+ if ("" == currentMedia) return false
+ val locations = settings.getString(if (audio) "audio_list" else "media_list", "").split(" ".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
+ if (Util.isArrayEmpty(locations)) return false
launch(UI, CoroutineStart.UNDISPATCHED) {
- val audio = type == Constants.PLAYLIST_TYPE_AUDIO
- val currentMedia = settings.getString(if (audio) "current_song" else "current_media", "")
- if ("" == currentMedia) return at launch
- val locations = settings.getString(if (audio) "audio_list" else "media_list", "").split(" ".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
- if (Util.isArrayEmpty(locations)) return at launch
val playList = async {
locations.map { Uri.decode(it) }.mapTo(ArrayList(locations.size)) { MediaWrapper(Uri.parse(it)) }
}.await()
@@ -141,6 +140,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
load(playList, position)
loadingLastPlaylist = false
}
+ return true
}
private fun onPlaylistLoaded() {
@@ -274,12 +274,10 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
var id = mw.id
if (id == 0L) {
var internalMedia = medialibrary.findMedia(mw)
- if (internalMedia != null && internalMedia.id != 0L)
- id = internalMedia.id
+ if (internalMedia != null && internalMedia.id != 0L) id = internalMedia.id
else {
internalMedia = medialibrary.addMedia(Uri.decode(mw.uri.toString()))
- if (internalMedia != null)
- id = internalMedia.id
+ if (internalMedia != null) id = internalMedia.id
}
}
medialibrary.increasePlayCount(id)
More information about the Android
mailing list