diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7d9e94d..cb0defa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -80,6 +80,16 @@ + + + + + + + realHumanVoiceList = category.audios - "Sounds of appliances" -> soundsOfAppliancesList = category.audios - "Sounds of nature" -> soundsOfNatureList = category.audios + "Sound of instrument" -> realHumanVoiceList = category.audios + "White noise" -> soundsOfAppliancesList = category.audios + "Voice of Nature" -> soundsOfNatureList = category.audios } } } @@ -106,6 +107,7 @@ class App : Application() { app = this initialize(this) MediaControllerManager.init(this) + LocalMediaControllerManager.init(this) appOfflineDBManager = AppOfflineDBManager.getInstance(this) currentAudioManager = CurrentAudioManager.getInstance(this) databaseManager = DatabaseManager.getInstance(this) diff --git a/app/src/main/java/com/player/musicoo/activity/BaseActivity.kt b/app/src/main/java/com/player/musicoo/activity/BaseActivity.kt index 61ed7a0..c9f89b8 100644 --- a/app/src/main/java/com/player/musicoo/activity/BaseActivity.kt +++ b/app/src/main/java/com/player/musicoo/activity/BaseActivity.kt @@ -1,9 +1,7 @@ package com.player.musicoo.activity import android.os.Bundle -import android.util.Log import androidx.appcompat.app.AppCompatActivity -import com.player.musicoo.media.MediaControllerManager open class BaseActivity : AppCompatActivity() { diff --git a/app/src/main/java/com/player/musicoo/activity/LaunchActivity.kt b/app/src/main/java/com/player/musicoo/activity/LaunchActivity.kt index 1c0200f..e7b7aad 100644 --- a/app/src/main/java/com/player/musicoo/activity/LaunchActivity.kt +++ b/app/src/main/java/com/player/musicoo/activity/LaunchActivity.kt @@ -43,7 +43,7 @@ class LaunchActivity : BaseActivity() { } private fun toMainActivity() { - startActivity(Intent(this, PrimaryActivity::class.java)) + startActivity(Intent(this, MainActivity::class.java)) finish() } } \ No newline at end of file diff --git a/app/src/main/java/com/player/musicoo/activity/MainActivity.kt b/app/src/main/java/com/player/musicoo/activity/MainActivity.kt index de6312f..b92a1db 100644 --- a/app/src/main/java/com/player/musicoo/activity/MainActivity.kt +++ b/app/src/main/java/com/player/musicoo/activity/MainActivity.kt @@ -5,7 +5,6 @@ import android.os.Bundle import android.os.Handler import android.os.Looper import android.os.Message -import android.util.Log import android.view.View import android.widget.Toast import androidx.fragment.app.Fragment @@ -19,8 +18,7 @@ import com.player.musicoo.bean.Audio import com.player.musicoo.databinding.ActivityMainBinding import com.player.musicoo.fragment.HomeFragment import com.player.musicoo.fragment.ImportFragment -import com.player.musicoo.media.MediaControllerManager -import com.player.musicoo.util.convertMillisToMinutesAndSecondsString +import com.player.musicoo.media.LocalMediaControllerManager import com.player.musicoo.util.getAudioDurationFromAssets @@ -52,7 +50,7 @@ class MainActivity : BaseActivity() { override fun onResume() { super.onResume() - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() if (App.currentPlayingAudio == null) { binding.playingStatusLayout.visibility = View.GONE @@ -121,7 +119,7 @@ class MainActivity : BaseActivity() { } binding.playBlackBtn.setOnClickListener { - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() if (currentPlayer != null) { if (currentPlayer.playbackState == Player.STATE_READY) { if (currentPlayer.isPlaying) { @@ -133,7 +131,7 @@ class MainActivity : BaseActivity() { } updateProgressState() } else { - MediaControllerManager.setupMedia(this@MainActivity, App.currentPlayingAudio!!, + LocalMediaControllerManager.setupMedia(this@MainActivity, App.currentPlayingAudio!!, object : Player.Listener { override fun onPlayWhenReadyChanged( playWhenReady: Boolean, @@ -209,7 +207,7 @@ class MainActivity : BaseActivity() { } private fun updateProgressState() { - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { progressHandler.removeCallbacksAndMessages(null) updatePlayState(currentPlayer.isPlaying) @@ -221,7 +219,7 @@ class MainActivity : BaseActivity() { private val progressHandler = object : Handler(Looper.myLooper()!!) { override fun handleMessage(msg: Message) { - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { val currentPosition = currentPlayer.currentPosition binding.progressBar.setProgress(currentPosition) diff --git a/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt b/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt index be8fab6..c41ecde 100644 --- a/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt +++ b/app/src/main/java/com/player/musicoo/activity/MoPlayDetailsActivity.kt @@ -157,8 +157,8 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener { val id = meController.currentMediaItem?.mediaId LogD(TAG, "initDownloadFlow id ->${id}") val currentScreenDownloads = downloads[id] - LogD(TAG, "currentScreenDownloads->${currentScreenDownloads}") if (currentScreenDownloads != null) { + LogD(TAG, "initDownloadFlow Download id->${currentScreenDownloads?.request?.id}") updateDownloadUI(currentScreenDownloads) } } diff --git a/app/src/main/java/com/player/musicoo/activity/PlayDetailsActivity.kt b/app/src/main/java/com/player/musicoo/activity/PlayDetailsActivity.kt index 01bc92a..1e3d636 100644 --- a/app/src/main/java/com/player/musicoo/activity/PlayDetailsActivity.kt +++ b/app/src/main/java/com/player/musicoo/activity/PlayDetailsActivity.kt @@ -13,9 +13,9 @@ import android.renderscript.Allocation import android.renderscript.Element import android.renderscript.RenderScript import android.renderscript.ScriptIntrinsicBlur -import android.util.Log import android.widget.Toast import androidx.annotation.OptIn +import androidx.media3.common.PlaybackException import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi import com.bumptech.glide.Glide @@ -24,7 +24,8 @@ import com.gyf.immersionbar.ktx.immersionBar import com.player.musicoo.R import com.player.musicoo.bean.Audio import com.player.musicoo.databinding.ActivityPlayDetailsBinding -import com.player.musicoo.media.MediaControllerManager +import com.player.musicoo.media.LocalMediaControllerManager +import com.player.musicoo.util.LogTag import com.player.musicoo.util.containsContent import com.player.musicoo.util.convertMillisToMinutesAndSecondsString import com.player.musicoo.util.getAudioDurationFromAssets @@ -53,7 +54,6 @@ class PlayDetailsActivity : BaseActivity() { Toast.makeText(this, getString(R.string.data_error), Toast.LENGTH_SHORT).show() } initView() - } private fun initImmersionBar() { @@ -97,7 +97,7 @@ class PlayDetailsActivity : BaseActivity() { binding.backBtn.setOnClickListener { onBackPressed() } - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() currentPlayer?.addListener(object : Player.Listener { override fun onPlayWhenReadyChanged( playWhenReady: Boolean, @@ -123,9 +123,12 @@ class PlayDetailsActivity : BaseActivity() { updateProgressState() } } - MediaControllerManager.setupMedia(this, + LocalMediaControllerManager.setupMedia(this, audio!!, object : Player.Listener { + override fun onPlayerError(error: PlaybackException) { + LogTag.LogD("ocean","error->${error}") + } override fun onPlayWhenReadyChanged( playWhenReady: Boolean, reason: Int @@ -154,7 +157,7 @@ class PlayDetailsActivity : BaseActivity() { override fun onResume() { super.onResume() - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY) { val isPlaying = currentPlayer.isPlaying updatePlayState(isPlaying, "onResume") @@ -236,7 +239,7 @@ class PlayDetailsActivity : BaseActivity() { } private fun updateProgressState() { - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { updatePlayState(currentPlayer.isPlaying, "playWhenReady") progressHandler.removeCallbacksAndMessages(null) @@ -248,7 +251,7 @@ class PlayDetailsActivity : BaseActivity() { private val progressHandler = object : Handler(Looper.myLooper()!!) { override fun handleMessage(msg: Message) { - val currentPlayer = MediaControllerManager.getController() + val currentPlayer = LocalMediaControllerManager.getController() if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { val currentPosition = currentPlayer.currentPosition val currentString = convertMillisToMinutesAndSecondsString(currentPosition) diff --git a/app/src/main/java/com/player/musicoo/media/LocalMediaControllerManager.kt b/app/src/main/java/com/player/musicoo/media/LocalMediaControllerManager.kt new file mode 100644 index 0000000..6c1b89f --- /dev/null +++ b/app/src/main/java/com/player/musicoo/media/LocalMediaControllerManager.kt @@ -0,0 +1,169 @@ +package com.player.musicoo.media + +import android.content.ComponentName +import android.content.Context +import android.net.Uri +import androidx.media3.common.MediaItem +import androidx.media3.common.MediaMetadata +import androidx.media3.common.Player +import androidx.media3.common.util.UnstableApi +import androidx.media3.session.MediaController +import androidx.media3.session.SessionToken +import com.google.common.util.concurrent.ListenableFuture +import com.google.common.util.concurrent.MoreExecutors +import com.player.musicoo.App +import com.player.musicoo.R +import com.player.musicoo.bean.Audio +import com.player.musicoo.bean.CurrentPlayingAudio +import com.player.musicoo.service.LocalPlaybackService +import com.player.musicoo.util.containsContent +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +@UnstableApi +object LocalMediaControllerManager { + private var mediaController: MediaController? = null + private var controllerFuture: ListenableFuture? = null + private var currentAudioFile = "" + + fun init(context: Context) { + val sessionToken = + SessionToken(context, ComponentName(context, LocalPlaybackService::class.java)) + controllerFuture = MediaController.Builder(context, sessionToken).buildAsync() + controllerFuture?.addListener({ + mediaController = controllerFuture?.get() + }, MoreExecutors.directExecutor()) + } + + fun getController(): MediaController? { + return if (mediaController != null && mediaController!!.isConnected) { + mediaController + } else { + null + } + } + + fun setupMedia(context: Context, audio: Audio, listener: Player.Listener) { + if (currentAudioFile != audio.file) { + currentAudioFile = audio.file + + val uri: Uri? = if (containsContent(audio.file)) { + Uri.parse(audio.file) + } else { + Uri.parse("file:///android_asset/$currentAudioFile") + } + + + val resourceId = R.mipmap.musicoo_logo_img + val imgUri: Uri? = if (audio.image.isNotEmpty()) { + Uri.parse("file:///android_asset/${audio.image}") + } else { + Uri.parse("android.resource://${context.packageName}/$resourceId") + } + + val mediaItem = + MediaItem.Builder() + .setUri(uri) + .setMediaMetadata( + MediaMetadata.Builder() + .setArtist(audio.name) + .setTitle(audio.name) + .setArtworkUri(imgUri) + .build() + ) + .build() + if (isConnected()) { + mediaController?.let { + it.addListener(listener) + it.setMediaItem(mediaItem) + it.repeatMode = Player.REPEAT_MODE_ALL + it.prepare() + it.play() + val currentPlayingAudio = + CurrentPlayingAudio( + audio.id, + audio.name, + audio.file, + audio.image, + audio.duration, + false + ) + CoroutineScope(Dispatchers.IO).launch { + App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio) + withContext(Dispatchers.Main) { + App.initCurrentPlayingAudio()//更新到入口变量中 + } + } + } + } + } + } + + fun setupMedia(context: Context, audio: CurrentPlayingAudio, listener: Player.Listener) { + if (currentAudioFile != audio.file) { + currentAudioFile = audio.file + + val uri: Uri? = if (containsContent(audio.file)) { + Uri.parse(audio.file) + } else { + Uri.parse("file:///android_asset/$currentAudioFile") + } + + + val resourceId = R.mipmap.musicoo_logo_img + val imgUri: Uri? = if (audio.image.isNotEmpty()) { + Uri.parse("file:///android_asset/${audio.image}") + } else { + Uri.parse("android.resource://${context.packageName}/$resourceId") + } + +// val uri = Uri.parse("file:///android_asset/$currentAudioFile") +//// val mediaItem = MediaItem.fromUri(uri) +// val imgUri = Uri.parse("file:///android_asset/${audio.image}") + val mediaItem = + MediaItem.Builder() + .setUri(uri) + .setMediaMetadata( + MediaMetadata.Builder() + .setArtist(audio.name) + .setTitle(audio.name) + .setArtworkUri(imgUri) + .build() + ) + .build() + if (isConnected()) { + mediaController?.let { + it.addListener(listener) + it.setMediaItem(mediaItem) + it.repeatMode = Player.REPEAT_MODE_ALL + it.prepare() + it.play() + val currentPlayingAudio = + CurrentPlayingAudio( + audio.id, + audio.name, + audio.file, + audio.image, + audio.duration, + false + ) + CoroutineScope(Dispatchers.IO).launch { + App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio) + withContext(Dispatchers.Main) { + App.initCurrentPlayingAudio()//更新到入口变量中 + } + } + + } + } + } + } + + fun isConnected(): Boolean { + mediaController?.let { + return it.isConnected + } + return false + } +} diff --git a/app/src/main/java/com/player/musicoo/media/MediaControllerManager.kt b/app/src/main/java/com/player/musicoo/media/MediaControllerManager.kt index 298c185..417004f 100644 --- a/app/src/main/java/com/player/musicoo/media/MediaControllerManager.kt +++ b/app/src/main/java/com/player/musicoo/media/MediaControllerManager.kt @@ -7,6 +7,7 @@ import android.os.Binder import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import androidx.media3.common.Player +import androidx.media3.common.util.UnstableApi import androidx.media3.session.MediaController import androidx.media3.session.SessionToken import com.google.common.util.concurrent.ListenableFuture @@ -22,10 +23,10 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +@UnstableApi object MediaControllerManager { private var mediaController: MediaController? = null private var controllerFuture: ListenableFuture? = null - private var currentAudioFile = "" fun init(context: Context) { val sessionToken = @@ -44,129 +45,6 @@ object MediaControllerManager { } } - fun setupMedia(context: Context, audio: Audio, listener: Player.Listener) { - if (currentAudioFile != audio.file) { - currentAudioFile = audio.file - - val uri: Uri? = if (containsContent(audio.file)) { - Uri.parse(audio.file) - } else { - Uri.parse("file:///android_asset/$currentAudioFile") - } - - - val resourceId = R.mipmap.musicoo_logo_img - val imgUri: Uri? = if (audio.image.isNotEmpty()) { - Uri.parse("file:///android_asset/${audio.image}") - } else { - Uri.parse("android.resource://${context.packageName}/$resourceId") - } - - val mediaItem = - MediaItem.Builder() - .setUri(uri) - .setMediaMetadata( - MediaMetadata.Builder() - .setArtist(audio.name) - .setTitle(audio.name) - .setArtworkUri(imgUri) - .build() - ) - .build() - if (isConnected()) { - mediaController?.let { - it.addListener(listener) - it.setMediaItem(mediaItem) - it.repeatMode = Player.REPEAT_MODE_ALL - it.prepare() - it.play() - val currentPlayingAudio = - CurrentPlayingAudio( - audio.id, - audio.name, - audio.file, - audio.image, - audio.duration, - false - ) - CoroutineScope(Dispatchers.IO).launch { - App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio) - withContext(Dispatchers.Main) { - App.initCurrentPlayingAudio()//更新到入口变量中 - } - } - } - } - } - } - - fun setupMedia(context: Context, audio: CurrentPlayingAudio, listener: Player.Listener) { - if (currentAudioFile != audio.file) { - currentAudioFile = audio.file - - val uri: Uri? = if (containsContent(audio.file)) { - Uri.parse(audio.file) - } else { - Uri.parse("file:///android_asset/$currentAudioFile") - } - - - val resourceId = R.mipmap.musicoo_logo_img - val imgUri: Uri? = if (audio.image.isNotEmpty()) { - Uri.parse("file:///android_asset/${audio.image}") - } else { - Uri.parse("android.resource://${context.packageName}/$resourceId") - } - -// val uri = Uri.parse("file:///android_asset/$currentAudioFile") -//// val mediaItem = MediaItem.fromUri(uri) -// val imgUri = Uri.parse("file:///android_asset/${audio.image}") - val mediaItem = - MediaItem.Builder() - .setUri(uri) - .setMediaMetadata( - MediaMetadata.Builder() - .setArtist(audio.name) - .setTitle(audio.name) - .setArtworkUri(imgUri) - .build() - ) - .build() - if (isConnected()) { - mediaController?.let { - it.addListener(listener) - it.setMediaItem(mediaItem) - it.repeatMode = Player.REPEAT_MODE_ALL - it.prepare() - it.play() - val currentPlayingAudio = - CurrentPlayingAudio( - audio.id, - audio.name, - audio.file, - audio.image, - audio.duration, - false - ) - CoroutineScope(Dispatchers.IO).launch { - App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio) - withContext(Dispatchers.Main) { - App.initCurrentPlayingAudio()//更新到入口变量中 - } - } - - } - } - } - } - - fun isConnected(): Boolean { - mediaController?.let { - return it.isConnected - } - return false - } - fun getDuration(): Long { mediaController?.let { if (it.duration > 0) { diff --git a/app/src/main/java/com/player/musicoo/service/LocalPlaybackService.kt b/app/src/main/java/com/player/musicoo/service/LocalPlaybackService.kt new file mode 100644 index 0000000..c359dc9 --- /dev/null +++ b/app/src/main/java/com/player/musicoo/service/LocalPlaybackService.kt @@ -0,0 +1,56 @@ +package com.player.musicoo.service + +import android.content.Intent +import androidx.media3.common.Player +import androidx.media3.common.util.UnstableApi +import androidx.media3.exoplayer.ExoPlayer +import androidx.media3.session.MediaSession +import androidx.media3.session.MediaSessionService +import com.player.musicoo.R + + +@UnstableApi +class LocalPlaybackService : MediaSessionService() { + + private var mediaSession: MediaSession? = null + + // Create your player and media session in the onCreate lifecycle event + override fun onCreate() { + super.onCreate() + + val player = ExoPlayer.Builder(this).build() + mediaSession = MediaSession.Builder(this, player) + .setId(getString(R.string.app_name) + "LocalPlay") + .build() + + +// setMediaNotificationProvider(MyMediaNotificationProvider(this)) + + } + + // The user dismissed the app from the recent tasks + override fun onTaskRemoved(rootIntent: Intent?) { + val player = mediaSession?.player!! + if (!player.playWhenReady + || player.mediaItemCount == 0 + || player.playbackState == Player.STATE_ENDED + ) { + // Stop the service if not playing, continue playing in the background + // otherwise. + stopSelf() + } + } + + override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = + mediaSession + + // Remember to release the player and media session in onDestroy + override fun onDestroy() { + mediaSession?.run { + player.release() + release() + mediaSession = null + } + super.onDestroy() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/player/musicoo/service/PlaybackService.kt b/app/src/main/java/com/player/musicoo/service/PlaybackService.kt index f23adee..b1437fb 100644 --- a/app/src/main/java/com/player/musicoo/service/PlaybackService.kt +++ b/app/src/main/java/com/player/musicoo/service/PlaybackService.kt @@ -92,6 +92,7 @@ class PlaybackService : MediaSessionService(), Player.Listener { player.addListener(this) mediaSession = MediaSession.Builder(this, player) + .setId(getString(R.string.app_name) + "OnlinePlay") .build() diff --git a/app/src/main/java/com/player/musicoo/util/OpenUrlUtil.kt b/app/src/main/java/com/player/musicoo/util/OpenUrlUtil.kt index ee8e0f0..efc9e12 100644 --- a/app/src/main/java/com/player/musicoo/util/OpenUrlUtil.kt +++ b/app/src/main/java/com/player/musicoo/util/OpenUrlUtil.kt @@ -6,8 +6,8 @@ import android.net.Uri import android.widget.Toast import com.player.musicoo.R -const val PRIVACY_POLICY_URL = "https://musicoo.app/privacy" -const val TERMS_OF_SERVICE_URL = "https://musicoo.app/terms" +const val PRIVACY_POLICY_URL = "https://sites.google.com/view/musiclax-privacy/home" +const val TERMS_OF_SERVICE_URL = "https://sites.google.com/view/musiclax-terms/home" fun openPrivacyPolicy(context: Context, privacyPolicyUrl: String) { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl)) diff --git a/app/src/main/res/layout/activity_launch.xml b/app/src/main/res/layout/activity_launch.xml index 59f5d0c..f1e728c 100644 --- a/app/src/main/res/layout/activity_launch.xml +++ b/app/src/main/res/layout/activity_launch.xml @@ -14,12 +14,26 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + + + + + @@ -41,13 +55,6 @@ android:layout_height="6dp" android:layout_marginTop="10dp" /> - diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index e086795..8bbf063 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -4,13 +4,6 @@ android:layout_height="match_parent" android:background="@color/main_bg_color"> - - - - Musicoo + Musiclax Ready to sleep We\'ve carefully prepared sounds for you Data Error