fucking service

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package biz.growapp.brew.service
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.media.MediaPlayer
import android.net.Uri
import android.os.Binder
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import androidx.media.MediaBrowserServiceCompat
import androidx.media.session.MediaButtonReceiver
import biz.growapp.brew.MainActivity
import biz.growapp.brew.R
class AudioPlayBackService : MediaBrowserServiceCompat() {
private val NOTIFICATION_ID = 404
private val NOTIFICATION_DEFAULT_CHANNEL_ID = "default_channel"
private val metadataBuilder = MediaMetadataCompat.Builder()
private val stateBuilder = PlaybackStateCompat.Builder().setActions(
PlaybackStateCompat.ACTION_PLAY
or PlaybackStateCompat.ACTION_STOP
or PlaybackStateCompat.ACTION_PAUSE
or PlaybackStateCompat.ACTION_PLAY_PAUSE
or PlaybackStateCompat.ACTION_SKIP_TO_NEXT
or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
)
private lateinit var mediaSession: MediaSessionCompat
private var audioManager: AudioManager? = null
private var audioFocusRequest: AudioFocusRequest? = null
private var audioFocusRequested = false
private val audioFocusChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> mediaSessionCallback.onPlay()
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> mediaSessionCallback.onPause()
else -> mediaSessionCallback.onPause()
}
}
private lateinit var player: MediaPlayer
private val mediaSessionCallback = object : MediaSessionCompat.Callback() {}
override fun onCreate() {
super.onCreate()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setOnAudioFocusChangeListener(audioFocusChangeListener)
.setAcceptsDelayedFocusGain(false)
.setWillPauseWhenDucked(true)
.setAudioAttributes(audioAttributes)
.build()
}
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
mediaSession = MediaSessionCompat(this, TAG).apply {
setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
)
setPlaybackState(stateBuilder.build())
// need to configure mediaSessionCallback
setCallback(mediaSessionCallback)
val appContext = applicationContext
val activityIntent = Intent(appContext, MainActivity::class.java)
setSessionActivity(PendingIntent.getActivity(appContext, 0, activityIntent, 0))
val mediaButtonIntent = Intent(Intent.ACTION_MEDIA_BUTTON, null, appContext, MediaButtonReceiver::class.java)
setMediaButtonReceiver(PendingIntent.getBroadcast(appContext, 0, mediaButtonIntent, 0))
// TODO: VK 22.03.2019 переделать
player = MediaPlayer.create(appContext, Uri.parse(""))
// Set the session's token so that client activities can communicate with it.
setSessionToken(sessionToken)
}
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
MediaButtonReceiver.handleIntent(mediaSession, intent)
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
mediaSession.release()
player.release()
}
private val becomingNoisyReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// Disconnecting headphones - stop playback
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY == intent.action) {
mediaSessionCallback.onPause()
}
}
}
override fun onBind(intent: Intent): IBinder {
return PlayerServiceBinder()
}
inner class PlayerServiceBinder : Binder() {
val mediaSessionToken: MediaSessionCompat.Token
get() = mediaSession.sessionToken
}
// TODO: VK 22.03.2019 выяснить что как с этим методом
override fun onLoadChildren(parentId: String, result: Result<MutableList<MediaBrowserCompat.MediaItem>>) {
result.sendResult(null)
}
// TODO: VK 22.03.2019 выяснить что как с этим методом
override fun onGetRoot(clientPackageName: String, clientUid: Int, rootHints: Bundle?): BrowserRoot? {
// (Optional) Control the level of access for the specified package name.
// You'll need to write your own logic to do this.
return MediaBrowserServiceCompat.BrowserRoot(
getString(R.string.app_name), // Name visible in Android Auto
null) // Bundle of optional extras
}
companion object {
private const val TAG = "AudioPlayBackService"
}
}