0

I'm trying to get context in service. I know that Service extends Context and I can get it at onCreate method. So I tried it and got error. I don't understand other example uses the context at onCreate and works, but not to me. Also I registered my service. the error is occurred at this line in service.

player = ExoPlayerFactory.newSimpleInstance(mContext, DefaultTrackSelector())

Why the context is null even though I initialized the context in onCreate? I saw the similar problem at here Android getContext on a background Service

error

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference

activity

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)


        val musicPlayer = binding.musicPlayer
  
        musicPlayer.player = audioService.getplayerInstance()
        musicPlayer.player.playWhenReady = true
        mIntent = Intent(this,AudioService::class.java)
        Util.startForegroundService(this,mIntent)
        bindService(mIntent, mConnection, Context.BIND_AUTO_CREATE);
        initializePlayer();


    }

Service


class AudioService  : Service() {
    private val mBinder: IBinder =Binder()
    private var player: SimpleExoPlayer? = null
    private var playerNotificationManager: PlayerNotificationManager? = null
    private var cacheDataSourceFactory : CacheDataSourceFactory?=null
    var mContext: Context? = null
    override fun onDestroy() {
        releasePlayer()
        super.onDestroy()
    }

    override fun onCreate() {
        super.onCreate()
        mContext = this
        if (player == null) {
            startPlayer()
        }
    }

    private fun releasePlayer() {
        if (player != null) {
            playerNotificationManager!!.setPlayer(null)
            player!!.release()
            player = null
        }
    }

    override fun onBind(intent: Intent?): IBinder {
        return mBinder
    }

    fun getplayerInstance(): SimpleExoPlayer? {
        if (player == null) {
            startPlayer()
        }
        return player
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        return START_STICKY
    }

    private fun startPlayer() {

        val uri: Uri = Uri.parse("https://storage.googleapis.com/exoplayer-test-media-0/Jazz_In_Paris.mp3")
        player = ExoPlayerFactory.newSimpleInstance(mContext, DefaultTrackSelector())

        cacheDataSourceFactory = getCacheDataSourceFactory(mContext!!)
        val mediaSource: MediaSource = ProgressiveMediaSource.Factory(cacheDataSourceFactory)
            .createMediaSource(uri)
        player!!.prepare(mediaSource)
        player!!.setPlayWhenReady(true)


        playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
            mContext,"channel_id", com.haii.exoplayerdemo.R.string.channelName,com.haii.exoplayerdemo.R.string.channelDescription,11,
            object : PlayerNotificationManager.MediaDescriptionAdapter{
                override fun createCurrentContentIntent(player: Player): PendingIntent? {
                    val intent = Intent(mContext,MainActivity::class.java)
                    return PendingIntent.getActivity(mContext,0,intent,PendingIntent.FLAG_UPDATE_CURRENT)
                }

                override fun getCurrentContentText(player: Player): String? {
                    return "description"
                }

                override fun getCurrentContentTitle(player: Player): String {
                    return "title"
                }

                override fun getCurrentLargeIcon(
                    player: Player,
                    callback: PlayerNotificationManager.BitmapCallback
                ): Bitmap? {
                    return null
                }

            } ,
            object : PlayerNotificationManager.NotificationListener {
                override fun onNotificationStarted(notificationId: Int, notification: Notification) {
                    Log.d("TAG","onNotificationStarted")
                    startForeground(notificationId,notification)
                }
                override fun onNotificationPosted(notificationId: Int, notification: Notification, ongoing: Boolean) {
                    Log.d("TAG","onNotificationPosted")
//                    startForeground(notificationId,notification)
                }

                override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) {
                    Log.e("TAG","onNotificationCancelled 2")
                    stopSelf()
                }

                override fun onNotificationCancelled(notificationId: Int) {
                    Log.e("TAG","onNotificationCancelled 1")
//                    stopSelf()
                }
            }
        )
        playerNotificationManager!!.setPlayer(player)
    }

    fun getCacheDataSourceFactory(context : Context) : com.haii.exoplayerdemo.CacheDataSourceFactory?{
        if(cacheDataSourceFactory==null){
            cacheDataSourceFactory = com.haii.exoplayerdemo.CacheDataSourceFactory(
                context,
                DefaultDataSourceFactory(context, "ua"),
                MyExoPlayer.MAX_CACHE_VALUE, MyExoPlayer.MAX_CACHE_FILE_VALUE
            )
        }
        return cacheDataSourceFactory
    }


}
Charles
  • 181
  • 1
  • 14

1 Answers1

0

I`m refering from here https://developer.android.com/guide/components/services.

The thing that you are doing wrong is calling getPlayerInstance() before onCreate is called. Your oncreate is called when you either bind or start the service. Good luck

Tensky
  • 79
  • 6