Search code examples
javaandroidandroid-mediaplayer

Is it good practice or necessary to use a Service to use a Media Player in the backgound


Hello StackOverflow's users, I'm developing a Music Player App for android. In my main activity when the user clicks on a song I start a new intent that displays PlayerActivity. In there, I initialize a MediaPlayer and all the other UI elements. When the user clicks the back button, I bring them back to the main activity and the song continues to play in the background. The same thing happens if they exit the application. Now I was wondering if it's fine to do something like this or if I should instead start a new Service for the MediaPlayer from the PlayerActivity class instead of doing it in there.

PlayerActivity:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_player);

    Bundle extras = getIntent().getExtras();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
        getWindow().setNavigationBarColor(getResources().getColor(R.color.colorPrimaryDark));
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        getWindow().setNavigationBarDividerColor(getResources().getColor(R.color.white));
    }

    playBtn = findViewById(R.id.btn_play);
    artImage = findViewById(R.id.art);
    remainingTimeLabel = findViewById(R.id.current_song_duration);
    totalTimeLabel = findViewById(R.id.total_duration);
    manager = MainActivity.getManager();

    Song song = manager.getCurrentSong();

    boolean wasCall = extras != null && extras.containsKey("call");
    if (!wasCall && manager.hasStarted()) {
        MediaPlayer mediaPlayer = manager.getMediaPlayer();
        mediaPlayer.pause();
        mediaPlayer.stop();
    }


    if (!wasCall) {
        mp = MediaPlayer.create(this, Uri.parse(song.getPath()));
        mp.setLooping(true);
        mp.seekTo(0);
        mp.setVolume(0.5f, 0.5f);
    } else {
        mp = manager.getMediaPlayer();
        mp.setLooping(true);
        mp.setVolume(0.5f, 0.5f);
    }

    totalTime = mp.getDuration();
    artImage.setImageBitmap(Bitmap.createScaledBitmap(song.getIcon(), 250, 250, true));

    totalTimeLabel.setText(createTimeLabel(totalTime));

    songName = findViewById(R.id.songName);
    songName.setText(song.getName());

    songAuthor = findViewById(R.id.songAuthor);
    songAuthor.setText(song.getArtist());

    Toolbar toolbar = findViewById(R.id.player_top_bar);
    toolbar.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
    setSupportActionBar(toolbar);

    assert getSupportActionBar() != null;
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    assert toolbar.getNavigationIcon() != null;
    toolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
    getSupportActionBar().setTitle(Html.fromHtml("<font color='#ffffff'>MySound</font>"));

    positionBar =  findViewById(R.id.seek_song_progressbar);
    positionBar.setMax(totalTime);
    positionBar.setOnSeekBarChangeListener(
            new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    if (fromUser) {
                        mp.seekTo(progress);

                        positionBar.setProgress(progress);
                    }
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            }
    );

    LinearLayout layout = findViewById(R.id.player_control);
    layout.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));

    new Thread(() -> {
        while (mp != null) {
            try {
                Message msg = new Message();
                msg.what = mp.getCurrentPosition();
                handler.sendMessage(msg);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();

    this.action = SongEndAction.REPEAT;

    mp.start();
    manager.setMediaPlayer(mp);
}

Solution

  • Here is a Music Service that I implemented in my book. https://github.com/Wickapps/Practical-Android-MusicService This implementation includes play, stop, and seek forward, but you could add other functions. Service is the best architecture for future scalability. There is a MainActivity.java which starts the service. MusicService.java is the service implementation. Hope this helps.