SimpleMobileTools / Simple-Music-Player

A clean music player with a customizable widget, stylish interface and no ads.
https://www.simplemobiletools.com
GNU General Public License v3.0
1.27k stars 411 forks source link

Track does not play from the Songs page for first time install #504

Closed parneet-guraya closed 11 months ago

parneet-guraya commented 1 year ago
  1. For a fresh install track doesn't play as shown in the video attached.

https://user-images.githubusercontent.com/111801812/215437896-2fe24116-3013-4b72-a8ba-a12dba974999.mp4

  1. But after clearing it from the Main Memory(recents). For rest of the time if i launch the app the track plays fine from the Songs page.
  2. Clearing the app data makes it come again (obviously) for the first time and rest of the time it works fine.

As of 30/01/23 Version- 5.16.3 Screenshot_2023-01-30-15-00-53-85_fc704e6b13c4fb26bf5e411f75da84f2

parneet-guraya commented 1 year ago

I think these line could be the reason


2023-02-01 23:26:40.755 30841-30841 OplusScrollToTopManager com...mobiletools.musicplayer.debug  D  unregisterGuidePopupDismissReceiverInSystemUI
2023-02-01 23:26:40.755 30841-30841 OplusScrollToTopManager com...mobiletools.musicplayer.debug  D  Receiver not registered: android.view.OplusScrollToTopManager$1@c8cb134
2023-02-01 23:26:40.755 30841-30841 OplusScrollToTopManager com...mobiletools.musicplayer.debug  D  unregisterSystemUIBroadcastReceiver 
2023-02-01 23:26:40.755 30841-30841 OplusScrollToTopManager com...mobiletools.musicplayer.debug  D  java.lang.IllegalArgumentException: Receiver not registered: android.view.OplusScrollToTopManager$2@81d7b5d
tibbi commented 1 year ago

doesnt look like anything related

tanaytandon12 commented 1 year ago

cause of issue found, file is TrackActivity @Subscribe(threadMode = ThreadMode.MAIN) fun trackChangedEvent(event: Events.TrackChanged) { val track = event.track if (track == null) { finish() } else { setupTrackInfo(event.track) } } The function trackChangedEvent is called and the value of event.track is null which causes finish to get called.

tanaytandon12 commented 1 year ago

@tibbi any idea why event.track is null?

tanaytandon12 commented 1 year ago

@tibbi the function getQueuedTracks in the file MusicService.kt returns an empty arraylist the first time it is called, which is why this bug is seen.

tanaytandon12 commented 1 year ago

Hi @tibbi I have a fix in place for this, but can't push the code. Is it an access issue, or should I be able to push it?

tibbi commented 1 year ago

you can create a PR, you dont need access for it

tanaytandon12 commented 1 year ago

@tibbi you can check the PR.

parneet-guraya commented 1 year ago

@tibbi

Hello, I was going through the code to find the possible cause. I found something that is related. As I am a beginner and my limited knowledge is speaking but these are things I noticed ->

Code is at the end!

The problem (I think) is, for some reason (for the first time) the albums fetched are empty so does the tracks and they are passed to the TracksAdapter in the UI thread block.

But, the call to the dao for albums invokes again (for some reason) maybe the background thread is concurrently executing that. This time the albums are initialised with actual data and so does the tracks. But, then the UI thread block does not run. So, It is having the data from the first run which is empty.

Screenshot from 2023-05-22 23-10-11

Also when application is launched again it works fine. The problem persist for the fresh install and for the first time usage. Screenshot from 2023-05-22 23-09-02

TracksFragment.kt-> https://github.com/SimpleMobileTools/Simple-Music-Player/blob/e0a136a589a838210c610013569b5b2257a21f9c/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/TracksFragment.kt

override fun setupFragment(activity: BaseSimpleActivity) {
        ensureBackgroundThread {
            val albums = ArrayList<Album>()
            val artists = context.artistDAO.getAll()
            artists.forEach { artist ->
                albums.addAll(context.albumsDAO.getArtistAlbums(artist.id))
            }
            Log.d(LOG_TAG,"Albums init inside TracksFragment -> ${albums.size}")
            var tracks = ArrayList<Track>()
            albums.forEach { album ->
                tracks.addAll(context.tracksDAO.getTracksFromAlbum(album.id))
            }

            tracks = tracks.distinctBy { "${it.path}/${it.mediaStoreId}" }.toMutableList() as ArrayList<Track>

            val excludedFolders = context.config.excludedFolders
            tracks = tracks.filter {
                !excludedFolders.contains(it.path.getParentPath())
            }.toMutableList() as ArrayList<Track>

            Track.sorting = context.config.trackSorting
            tracks.sort()
            tracksIgnoringSearch = tracks
            Log.d(LOG_TAG,"Tracks init inside TracksFragment -> ${tracks.size}")

            activity.runOnUiThread {
                tracks_placeholder.text = context.getString(R.string.no_items_found)
                tracks_placeholder.beVisibleIf(tracks.isEmpty())
                val adapter = tracks_list.adapter
                if (adapter == null) {
                    Log.d(LOG_TAG,"TracksAdapter(tracks) in TracksFragment -> $tracks")
                    TracksAdapter(activity, tracks, false, tracks_list) {
                        activity.hideKeyboard()
                        activity.handleNotificationPermission { granted ->
                            if (granted) {
                                activity.resetQueueItems(tracks) {
                                    Intent(activity, TrackActivity::class.java).apply {
                                        putExtra(TRACK, Gson().toJson(it))
                                        putExtra(RESTART_PLAYER, true)
                                        activity.startActivity(this)
                                    }
                                }
                            } else {
                                if (context is Activity) {
                                    PermissionRequiredDialog(activity, R.string.allow_notifications_music_player)
                                }
                            }
                        }
                    }.apply {
                        tracks_list.adapter = this
                    }

                    if (context.areSystemAnimationsEnabled) {
                        tracks_list.scheduleLayoutAnimation()
                    }
                } else {
                    (adapter as TracksAdapter).updateItems(tracks)
                }
            }
        }
    }

Any idea what's causing this?

Thanks Parneet

naveensingh commented 1 year ago

Hello! @parneet-guraya @tanaytandon12

I have uploaded a test APK with a possible fix for this issue, please check if you are interested: https://github.com/Naveen3Singh/Simple-Music-Player/releases/download/improved_media_scan/music-player-prepaid-debug.apk

Let me know if it works, thanks.

parneet-guraya commented 1 year ago

Yup, It works fine! What changes did you make? What was causing it? Was I any way near with that my comment?

naveensingh commented 1 year ago

Simply converted the local variable to a global one. Like in @tanaytandon12's PR.

naveensingh commented 1 year ago

@parneet-guraya @naveen3singh is my telegram username.