1
0
mirror of https://github.com/ultrasonic/ultrasonic synced 2025-02-19 21:20:52 +01:00

We can now remove the deprecated Remote Control API

This commit is contained in:
tzugen 2021-04-17 18:39:17 +02:00
parent 26ba022003
commit 19580cda8b
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
2 changed files with 1 additions and 147 deletions

View File

@ -300,7 +300,6 @@ public class MediaPlayerService extends Service
{ {
nowPlayingEventDistributor.getValue().raiseHideNowPlayingEvent(); nowPlayingEventDistributor.getValue().raiseHideNowPlayingEvent();
stopForeground(true); stopForeground(true);
localMediaPlayer.clearRemoteControl();
isInForeground = false; isInForeground = false;
stopIfIdle(); stopIfIdle();
} }
@ -520,7 +519,6 @@ public class MediaPlayerService extends Service
{ {
nowPlayingEventDistributor.getValue().raiseHideNowPlayingEvent(); nowPlayingEventDistributor.getValue().raiseHideNowPlayingEvent();
stopForeground(true); stopForeground(true);
localMediaPlayer.clearRemoteControl();
isInForeground = false; isInForeground = false;
stopIfIdle(); stopIfIdle();
} }

View File

@ -7,17 +7,12 @@
package org.moire.ultrasonic.service package org.moire.ultrasonic.service
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Context.AUDIO_SERVICE
import android.content.Context.POWER_SERVICE import android.content.Context.POWER_SERVICE
import android.content.Intent import android.content.Intent
import android.media.AudioManager import android.media.AudioManager
import android.media.MediaMetadataRetriever
import android.media.MediaPlayer import android.media.MediaPlayer
import android.media.MediaPlayer.OnCompletionListener import android.media.MediaPlayer.OnCompletionListener
import android.media.RemoteControlClient
import android.media.audiofx.AudioEffect import android.media.audiofx.AudioEffect
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
@ -35,10 +30,8 @@ import org.moire.ultrasonic.audiofx.VisualizerController
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.PlayerState import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.fragment.PlayerFragment import org.moire.ultrasonic.fragment.PlayerFragment
import org.moire.ultrasonic.receiver.MediaButtonIntentReceiver
import org.moire.ultrasonic.util.CancellableTask import org.moire.ultrasonic.util.CancellableTask
import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.FileUtil
import org.moire.ultrasonic.util.StreamProxy import org.moire.ultrasonic.util.StreamProxy
import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.util.Util
import timber.log.Timber import timber.log.Timber
@ -84,8 +77,6 @@ class LocalMediaPlayer(
private var mediaPlayerHandler: Handler? = null private var mediaPlayerHandler: Handler? = null
private var cachedPosition = 0 private var cachedPosition = 0
private var proxy: StreamProxy? = null private var proxy: StreamProxy? = null
private var audioManager: AudioManager = context.getSystemService(AUDIO_SERVICE) as AudioManager
private var remoteControlClient: RemoteControlClient? = null
private var bufferTask: CancellableTask? = null private var bufferTask: CancellableTask? = null
private var positionCache: PositionCache? = null private var positionCache: PositionCache? = null
private var secondaryProgress = -1 private var secondaryProgress = -1
@ -129,7 +120,6 @@ class LocalMediaPlayer(
wakeLock.setReferenceCounted(false) wakeLock.setReferenceCounted(false)
Util.registerMediaButtonEventReceiver(context, true) Util.registerMediaButtonEventReceiver(context, true)
setUpRemoteControlClient()
Timber.i("LocalMediaPlayer created") Timber.i("LocalMediaPlayer created")
} }
@ -156,8 +146,6 @@ class LocalMediaPlayer(
if (nextPlayingTask != null) { if (nextPlayingTask != null) {
nextPlayingTask!!.cancel() nextPlayingTask!!.cancel()
} }
audioManager.unregisterRemoteControlClient(remoteControlClient)
clearRemoteControl()
Util.unregisterMediaButtonEventReceiver(context, true) Util.unregisterMediaButtonEventReceiver(context, true)
wakeLock.release() wakeLock.release()
} catch (exception: Throwable) { } catch (exception: Throwable) {
@ -173,9 +161,7 @@ class LocalMediaPlayer(
if (playerState === PlayerState.STARTED) { if (playerState === PlayerState.STARTED) {
audioFocusHandler.requestAudioFocus() audioFocusHandler.requestAudioFocus()
} }
if (playerState === PlayerState.STARTED || playerState === PlayerState.PAUSED) {
updateRemoteControl()
}
if (onPlayerStateChanged != null) { if (onPlayerStateChanged != null) {
val mainHandler = Handler(context.mainLooper) val mainHandler = Handler(context.mainLooper)
val myRunnable = Runnable { val myRunnable = Runnable {
@ -200,7 +186,6 @@ class LocalMediaPlayer(
fun setCurrentPlaying(currentPlaying: DownloadFile?) { fun setCurrentPlaying(currentPlaying: DownloadFile?) {
Timber.v("setCurrentPlaying %s", currentPlaying) Timber.v("setCurrentPlaying %s", currentPlaying)
this.currentPlaying = currentPlaying this.currentPlaying = currentPlaying
updateRemoteControl()
if (onCurrentPlayingChanged != null) { if (onCurrentPlayingChanged != null) {
val mainHandler = Handler(context.mainLooper) val mainHandler = Handler(context.mainLooper)
@ -296,140 +281,11 @@ class LocalMediaPlayer(
} }
} }
/*
* The remote control API is deprecated in API 21
*/
private fun updateRemoteControl() {
if (!Util.isLockScreenEnabled(context)) {
clearRemoteControl()
return
}
if (remoteControlClient == null) {
remoteControlClient = createRemoteControlClient()
} else {
// This is probably needed only in API <=17
// "You must register your RemoteControlDisplay every time when the View which
// displays metadata is shown to the user. This is because 4.2.2 and lower
// versions support only one RemoteControlDisplay, and if system will
// decide to register it's own RCD, your RCD will be
// unregistered automatically.
// https://forum.xda-developers.com/t/guide-implement-your-own-lockscreen-like-music-controls.2401597/
audioManager.unregisterRemoteControlClient(remoteControlClient)
audioManager.registerRemoteControlClient(remoteControlClient)
}
Timber.i(
"In updateRemoteControl, playerState: %s [%d]",
playerState, playerPosition
)
if (playerState === PlayerState.STARTED) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
remoteControlClient!!.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING)
} else {
remoteControlClient!!.setPlaybackState(
RemoteControlClient.PLAYSTATE_PLAYING,
playerPosition.toLong(), 1.0f
)
}
} else {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
remoteControlClient!!.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED)
} else {
remoteControlClient!!.setPlaybackState(
RemoteControlClient.PLAYSTATE_PAUSED,
playerPosition.toLong(), 1.0f
)
}
}
if (currentPlaying != null) {
val currentSong = currentPlaying!!.song
val lockScreenBitmap = FileUtil.getAlbumArtBitmap(
context, currentSong,
Util.getMinDisplayMetric(context), true
)
val artist = currentSong.artist
val album = currentSong.album
val title = currentSong.title
val currentSongDuration = currentSong.duration
var duration = 0L
if (currentSongDuration != null) duration = (currentSongDuration * 1000).toLong()
remoteControlClient!!.editMetadata(true)
.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, artist)
.putString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, artist)
.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, album)
.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, title)
.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, duration)
.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, lockScreenBitmap)
.apply()
}
}
fun clearRemoteControl() {
if (remoteControlClient != null) {
remoteControlClient!!.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED)
audioManager.unregisterRemoteControlClient(remoteControlClient)
remoteControlClient = null
}
}
private fun setUpRemoteControlClient() {
if (!Util.isLockScreenEnabled(context)) return
if (remoteControlClient == null) {
remoteControlClient = createRemoteControlClient()
}
}
private fun createRemoteControlClient(): RemoteControlClient {
val componentName = ComponentName(
context.packageName,
MediaButtonIntentReceiver::class.java.name
)
val mediaButtonIntent = Intent(Intent.ACTION_MEDIA_BUTTON)
mediaButtonIntent.component = componentName
val broadcast = PendingIntent.getBroadcast(
context, 0,
mediaButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
val remoteControlClient = RemoteControlClient(broadcast)
audioManager.registerRemoteControlClient(remoteControlClient)
// Flags for the media transport control that this client supports.
var flags = RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS or
RemoteControlClient.FLAG_KEY_MEDIA_NEXT or
RemoteControlClient.FLAG_KEY_MEDIA_PLAY or
RemoteControlClient.FLAG_KEY_MEDIA_PAUSE or
RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE or
RemoteControlClient.FLAG_KEY_MEDIA_STOP
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
flags = flags or RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE
remoteControlClient.setOnGetPlaybackPositionListener {
mediaPlayer.currentPosition.toLong()
}
remoteControlClient.setPlaybackPositionUpdateListener {
newPositionMs ->
seekTo(newPositionMs.toInt())
}
}
remoteControlClient.setTransportControlFlags(flags)
return remoteControlClient
}
@Synchronized @Synchronized
fun seekTo(position: Int) { fun seekTo(position: Int) {
try { try {
mediaPlayer.seekTo(position) mediaPlayer.seekTo(position)
cachedPosition = position cachedPosition = position
updateRemoteControl()
} catch (x: Exception) { } catch (x: Exception) {
handleError(x) handleError(x)
} }