From 1edd4acd9c99c3773b615ebc0e710e763c3d5310 Mon Sep 17 00:00:00 2001 From: Prathamesh More Date: Mon, 30 May 2022 14:53:41 +0530 Subject: [PATCH] Fixed headphones auto-play not working --- .../fragments/base/AbsMainActivityFragment.kt | 2 +- .../retromusic/service/CrossFadePlayer.kt | 43 ++----------------- .../retromusic/service/LocalPlayback.kt | 41 +++++++++++++++++- .../monkey/retromusic/service/MultiPlayer.kt | 42 +----------------- .../monkey/retromusic/service/MusicService.kt | 17 +++++++- 5 files changed, 60 insertions(+), 85 deletions(-) diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMainActivityFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMainActivityFragment.kt index 17c1a82db..8571ffdcb 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMainActivityFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsMainActivityFragment.kt @@ -33,7 +33,7 @@ abstract class AbsMainActivityFragment(@LayoutRes layout: Int) : AbsMusicService override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val menuHost: MenuHost = requireActivity() + val menuHost: MenuHost = requireActivity() as MenuHost menuHost.addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.STARTED) } } diff --git a/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt b/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt index a449c462d..40c30ae92 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/CrossFadePlayer.kt @@ -2,13 +2,9 @@ package code.name.monkey.retromusic.service import android.animation.Animator import android.content.Context -import android.media.AudioAttributes -import android.media.AudioManager import android.media.MediaPlayer import android.media.PlaybackParams import android.os.PowerManager -import android.util.Log -import androidx.core.net.toUri import code.name.monkey.appthemehelper.util.VersionUtils.hasMarshmallow import code.name.monkey.retromusic.R import code.name.monkey.retromusic.extensions.showToast @@ -18,6 +14,7 @@ import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.service.AudioFader.Companion.createFadeAnimator import code.name.monkey.retromusic.service.playback.Playback.PlaybackCallbacks import code.name.monkey.retromusic.util.PreferenceUtil +import code.name.monkey.retromusic.util.logE import kotlinx.coroutines.* /** @author Prathamesh M */ @@ -29,8 +26,7 @@ import kotlinx.coroutines.* * play but with decreasing volume and start the player with the next song with increasing volume * and vice versa for upcoming song and so on. */ -class CrossFadePlayer(context: Context) : LocalPlayback(context), MediaPlayer.OnCompletionListener, - MediaPlayer.OnErrorListener { +class CrossFadePlayer(context: Context) : LocalPlayback(context) { private var currentPlayer: CurrentPlayer = CurrentPlayer.NOT_SET private var player1 = MediaPlayer() @@ -144,39 +140,6 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context), MediaPlayer.On override fun setNextDataSource(path: String?) {} - /** - * @param player The {@link MediaPlayer} to use - * @param path The path of the file, or the http/rtsp URL of the stream you want to play - * @return True if the player has been prepared and is ready to play, false otherwise - */ - private fun setDataSourceImpl( - player: MediaPlayer, - path: String, - completion: (success: Boolean) -> Unit, - ) { - player.reset() - try { - if (path.startsWith("content://")) { - player.setDataSource(context, path.toUri()) - } else { - player.setDataSource(path) - } - player.setAudioAttributes( - AudioAttributes.Builder().setLegacyStreamType(AudioManager.STREAM_MUSIC).build() - ) - player.setOnPreparedListener { - player.setOnPreparedListener(null) - completion(true) - } - player.prepareAsync() - } catch (e: Exception) { - completion(false) - e.printStackTrace() - } - player.setOnCompletionListener(this) - player.setOnErrorListener(this) - } - override fun setAudioSessionId(sessionId: Int): Boolean { return try { getCurrentPlayer()?.audioSessionId = sessionId @@ -287,7 +250,7 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context), MediaPlayer.On mIsInitialized = true mp?.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK) context.showToast(R.string.unplayable_file) - Log.e(TAG, what.toString() + extra) + logE(what.toString() + extra) return false } diff --git a/app/src/main/java/code/name/monkey/retromusic/service/LocalPlayback.kt b/app/src/main/java/code/name/monkey/retromusic/service/LocalPlayback.kt index 8a6bdca16..fafbae0ec 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/LocalPlayback.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/LocalPlayback.kt @@ -4,9 +4,12 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.media.AudioAttributes import android.media.AudioManager +import android.media.MediaPlayer import androidx.annotation.CallSuper import androidx.core.content.getSystemService +import androidx.core.net.toUri import androidx.media.AudioAttributesCompat import androidx.media.AudioFocusRequestCompat import androidx.media.AudioManagerCompat @@ -15,7 +18,8 @@ import code.name.monkey.retromusic.extensions.showToast import code.name.monkey.retromusic.service.playback.Playback import code.name.monkey.retromusic.util.PreferenceUtil.isAudioFocusEnabled -abstract class LocalPlayback(val context: Context) : Playback { +abstract class LocalPlayback(val context: Context) : Playback, MediaPlayer.OnErrorListener, + MediaPlayer.OnCompletionListener { private val becomingNoisyReceiverIntentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY) @@ -100,6 +104,41 @@ abstract class LocalPlayback(val context: Context) : Playback { return true } + /** + * @param player The [MediaPlayer] to use + * @param path The path of the file, or the http/rtsp URL of the stream you want to play + * @return True if the player has been prepared and is ready to play, false otherwise + */ + fun setDataSourceImpl( + player: MediaPlayer, + path: String, + completion: (success: Boolean) -> Unit, + ) { + player.reset() + try { + if (path.startsWith("content://")) { + player.setDataSource(context, path.toUri()) + } else { + player.setDataSource(path) + } + player.setAudioAttributes(AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_MEDIA) + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) + .build() + ) + player.setOnPreparedListener { + player.setOnPreparedListener(null) + completion(true) + } + player.prepareAsync() + } catch (e: Exception) { + completion(false) + e.printStackTrace() + } + player.setOnCompletionListener(this) + player.setOnErrorListener(this) + } + private fun unregisterBecomingNoisyReceiver() { if (becomingNoisyReceiverRegistered) { context.unregisterReceiver(becomingNoisyReceiver) diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt index abb4bd950..8421b60f1 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt @@ -14,10 +14,7 @@ package code.name.monkey.retromusic.service import android.content.Context -import android.media.AudioAttributes import android.media.MediaPlayer -import android.media.MediaPlayer.OnCompletionListener -import android.net.Uri import android.os.PowerManager import android.util.Log import code.name.monkey.retromusic.R @@ -30,8 +27,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil.isGapLessPlayback /** * @author Andrew Neal, Karim Abou Zeid (kabouzeid) */ -class MultiPlayer(context: Context) : LocalPlayback(context), - MediaPlayer.OnErrorListener, OnCompletionListener { +class MultiPlayer(context: Context) : LocalPlayback(context) { private var mCurrentMediaPlayer = MediaPlayer() private var mNextMediaPlayer: MediaPlayer? = null override var callbacks: PlaybackCallbacks? = null @@ -65,42 +61,6 @@ class MultiPlayer(context: Context) : LocalPlayback(context), } } - /** - * @param player The [MediaPlayer] to use - * @param path The path of the file, or the http/rtsp URL of the stream you want to play - * @return True if the `player` has been prepared and is ready to play, false otherwise - */ - private fun setDataSourceImpl( - player: MediaPlayer, - path: String, - completion: (success: Boolean) -> Unit, - ) { - try { - player.reset() - player.setOnPreparedListener(null) - if (path.startsWith("content://")) { - player.setDataSource(context, Uri.parse(path)) - } else { - player.setDataSource(path) - } - player.setAudioAttributes(AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_MEDIA) - .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) - .build() - ) - player.setOnPreparedListener { - player.setOnPreparedListener(null) - completion(true) - } - player.prepareAsync() - } catch (e: Exception) { - completion(false) - e.printStackTrace() - } - player.setOnCompletionListener(this) - player.setOnErrorListener(this) - } - /** * Set the MediaPlayer to start when this MediaPlayer finishes playback. * diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt index 54d470bdd..3221a24f0 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt +++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt @@ -235,6 +235,7 @@ class MusicService : MediaBrowserServiceCompat(), } } + private var receivedHeadsetConnected = false private val headsetReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val action = intent.action @@ -242,7 +243,12 @@ class MusicService : MediaBrowserServiceCompat(), if (Intent.ACTION_HEADSET_PLUG == action) { when (intent.getIntExtra("state", -1)) { 0 -> pause() - 1 -> play() + // Check whether the current song is empty which means the playing queue hasn't restored yet + 1 -> if (currentSong != emptySong) { + play() + } else { + receivedHeadsetConnected = true + } } } } @@ -921,6 +927,10 @@ class MusicService : MediaBrowserServiceCompat(), notHandledMetaChangedForCurrentTrack = true sendChangeInternal(META_CHANGED) } + if (receivedHeadsetConnected) { + play() + receivedHeadsetConnected = false + } } sendChangeInternal(QUEUE_CHANGED) @@ -1250,9 +1260,12 @@ class MusicService : MediaBrowserServiceCompat(), ) handleAndSendChangeInternal(SHUFFLE_MODE_CHANGED) handleAndSendChangeInternal(REPEAT_MODE_CHANGED) - serviceScope.launch { + val start= System.currentTimeMillis() + serviceScope.launch(start = CoroutineStart.DEFAULT) { restoreQueuesAndPositionIfNecessary() + println("Time completion: ${System.currentTimeMillis() - start}") } + println("Time: ${System.currentTimeMillis() - start}") } private fun savePosition() {