外部玩家运行良好,但无效玩家正在服务中



我在服务中使用外部层进行后台流传输。我发现了一些奇怪的东西。当我在活动中得到玩家时,该玩家为空。但音乐在流媒体播放,我能听到那首歌。为什么服务中的播放器即使正在流媒体播放也为空?我不明白。例如,如果我点击musicOnOff按钮,我会得到播放器的零点错误,但音乐正在流式播放。请让我明白。。。

错误

kotlin.KotlinNullPointerException

活动

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var mBound = false
var mIntent = Intent()
var audioService :AudioService ?= null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
audioService = AudioService()
mIntent = Intent(this,AudioService::class.java)
Util.startForegroundService(this,mIntent)
binding.musicOnOffButton.setOnClickListener {
initializePlayer()
}
}
private fun initializePlayer() {
if (mBound) {
val player: SimpleExoPlayer = audioService!!.getplayerInstance()!!
binding.musicPlayer.player = player
binding.musicPlayer.useController = true
}
}
override fun onResume() {
super.onResume()
bindService(mIntent, mConnection, Context.BIND_AUTO_CREATE)
}
override fun onPause() {
super.onPause()
unbindService(mConnection)
}
private val mConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
mBound = true
//initializePlayer()
}
override fun onServiceDisconnected(componentName: ComponentName) {
}
}
}

服务


class AudioService  : Service() {
private val mBinder: IBinder =Binder()
var player: SimpleExoPlayer? = null
private var cacheDataSourceFactory : CacheDataSourceFactory?=null
var mContext: Context? = null
lateinit var notification : Notification
override fun onDestroy() {
releasePlayer()
super.onDestroy()
}
override fun onCreate() {
super.onCreate()
Log.d("TAG","TAG : onCreate")
}
private fun releasePlayer() {
if (player != null) {
player!!.release()
player = null
}
}
override fun onBind(intent: Intent?): IBinder {
return mBinder
}
fun getplayerInstance(): SimpleExoPlayer? {
if (player == null) {
startPlayer(mContext!!)
}
return player
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
Log.d("TAG","TAG : onStartCommand")
mContext = this
startPlayer(mContext!!)
val myNotificationListener = object :MyNotificationListener{
override fun onPlay() {
player!!.playWhenReady= !player!!.playWhenReady
}
override fun onRemove() {
stopSelf()
//stopForeground(true)
}
}
val receiver = NotificationBroadCast(myNotificationListener)
registerReceiver(receiver, IntentFilter("TRACKS_TRACKS"))
createNotification(
this,
MusicTrack("title 1","artist 1",R.drawable.reaction_happy),
1,
3
)
startForeground(NOTIFICATION_ID,notification)
return START_STICKY
}
private fun startPlayer(context: Context) {
val uri: Uri = Uri.parse("https://storage.googleapis.com/exoplayer-test-media-0/Jazz_In_Paris.mp3")
player = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector())
cacheDataSourceFactory = getCacheDataSourceFactory(context)
val mediaSource: MediaSource = ProgressiveMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(uri)
player!!.prepare(mediaSource)
player!!.setPlayWhenReady(true)
}
fun getCacheDataSourceFactory(context : Context) : CacheDataSourceFactory?{
if(cacheDataSourceFactory==null){
cacheDataSourceFactory = CacheDataSourceFactory(
context,
DefaultDataSourceFactory(context, "ua"),
MyExoPlayer.MAX_CACHE_VALUE, MyExoPlayer.MAX_CACHE_FILE_VALUE
)
}
return cacheDataSourceFactory
}
fun createNotification(context: Context, musicTrack: MusicTrack,  pos:Int, size:Int){
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val resultIntent = Intent(context, MobileActivity::class.java)
resultIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
val resultPendingIntent: PendingIntent? = PendingIntent.getActivity(context,0,resultIntent, PendingIntent.FLAG_CANCEL_CURRENT)
var previousIntent :PendingIntent ?=null
var nextIntent :PendingIntent ?=null
var playIntent :PendingIntent ?=null
var image_prev = 0
var image_next = 0
if(pos==0){
previousIntent = null
image_prev =0
}else{
val intentPrevious = Intent(context,
NotificationReceiver::class.java).setAction(
MusicNotification.ACTION_PREVIOUS
)
previousIntent = PendingIntent.getBroadcast(context,0,intentPrevious,PendingIntent.FLAG_UPDATE_CURRENT)
image_prev = R.drawable.play_previous
}
if(pos==size){
nextIntent = null
image_next =0
}else{
val intentNext = Intent(context,
NotificationReceiver::class.java).setAction(
MusicNotification.ACTION_NEXT
)
nextIntent = PendingIntent.getBroadcast(context,0,intentNext,PendingIntent.FLAG_UPDATE_CURRENT)
image_next = R.drawable.play_next
}
val intentPlay = Intent(context,
NotificationReceiver::class.java).setAction(
MusicNotification.ACTION_PLAY
)
playIntent = PendingIntent.getBroadcast(context,0,intentPlay,PendingIntent.FLAG_UPDATE_CURRENT)
val intentCancel = Intent(context,
NotificationReceiver::class.java).setAction(
MusicNotification.ACTION_PLAY
)
val cancelIntent = PendingIntent.getBroadcast(context,0,intentCancel,PendingIntent.FLAG_UPDATE_CURRENT)
var binding = CustomNotificationBinding.inflate(LayoutInflater.from(context))
var contentView = RemoteViews(context.packageName, R.layout.custom_notification)
contentView.setTextViewText(binding.notiMusicName.id,musicTrack.title)
contentView.setOnClickPendingIntent(binding.prevButton.id,previousIntent)
contentView.setOnClickPendingIntent(binding.startButton.id,playIntent)
contentView.setOnClickPendingIntent(binding.nextButton.id,nextIntent)

notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.music_note)
.setOnlyAlertOnce(true)
.setShowWhen(false)
.setOngoing(true)
.setAutoCancel(true)
.setContent(contentView)
.setCustomContentView(contentView)
.setCustomBigContentView(contentView)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(resultPendingIntent)
.setColorized(true)
.setColor(context.getColor(R.color.colorPrimary))
.build()

if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
val channelName ="Music Channel"
val channel = NotificationChannel(CHANNEL_ID,channelName, NotificationManager.IMPORTANCE_DEFAULT)
channel.enableLights(true)
channel.lightColor= 0x00FFFF
channel.setShowBadge(false)
notificationManager.createNotificationChannel(channel)
}
}

}

我解决了这个问题。由于我对服务和活页夹的了解不够,我无法得到我想要的结果。

我添加了指向当前服务的本地绑定器

添加到AudioService

val mBinder: IBinder = LocalBinder()
inner class LocalBinder : Binder() {
val service: AudioService
get() = this@AudioService
}

添加到MainActivity

private val mConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
mBound = true
val binder = iBinder as AudioService.LocalBinder
audioService = binder.service
initializePlayer()
}
override fun onServiceDisconnected(componentName: ComponentName) {
}
}

最新更新