Multiple Activities with one XML File

496 Views Asked by At

I am making a music player application in android. The application has

  1. MainActivity.java (with corresponding XML File:activity_main): This Activity has a listview that displays the list of all songs available.

  2. PlayerScreen.java (with corresponding XML File:activity_player_screen): When a song is clicked on the first activity, this activity is launched and it plays that particular song. This activity has 3 Buttons (Play/Pause, NextSong, PreviousSong) and a seekbar.

Now this is where I am facing the problem

I have created a separate class (SeekBarThread.java) for implementing seekbar of the activity_player_screen using Threading.

The Problem is that when I call the start method for my thread class from PlayerScreen.java, nothing happens. No exception is thrown. The song keeps on playing but the widgets of the activity_player_screen stop working i.e. I can't pause the song aur play the next song. The seekbar also doesn't work.

I think I am not able to link the activity_player_screen file with both PlayerScreen.java and SeekBarThread.java properly.

This is the call to the Thread class from PlayerScreen.java

mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();

I don't really have an idea to get rid of the anomaly so I passed the seekbar object and mediaplayer object reference and the current context reference to the SeekBarThread class. But it didn't work.

Here is the SeekBarThread.java class code:

public class SeekBarThread implements Runnable{

private PlayerScreen myPlayerScreen;
private SeekBar seekBar;
private MediaPlayer mp;
private Context context;

public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
    this.context = context;
    this.seekBar = seekBar;
    this.mp = mp;
}

public void run() {

    ((Activity)context).setContentView(R.layout.activity_player_screen);
    seekBar.setMax(mp.getDuration());

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mp.seekTo(seekBar.getProgress());
        }
    });

    int totalduration = mp.getDuration();
    int currentposition = 0;
    while(currentposition < totalduration) {
        try {
            sleep(500);
            currentposition = mp.getCurrentPosition();
            seekBar.setProgress(currentposition);
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
}

activity_player_screen XML File:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_player_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="prakhar.simplemusicplayer20.PlayerScreen">

<Button
    android:id="@+id/play_pause"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:layout_alignParentBottom="true"
    android:layout_centerInParent="true"
    android:background="@drawable/pause" />

<Button
    android:id="@+id/next_song"
    android:layout_height="42dp"
    android:layout_width="42dp"
    android:background="@drawable/next"
    android:layout_marginEnd="25dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true" />

<Button
    android:id="@+id/prev_song"
    android:layout_height="42dp"
    android:layout_width="42dp"
    android:background="@drawable/previous"
    android:layout_marginStart="25dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true" />

<Button
    android:text="F"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:id="@+id/forward_song"
    android:layout_alignParentBottom="true"
    android:layout_toStartOf="@+id/next_song"
    android:layout_marginEnd="22dp" />

<Button
    android:text="R"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:id="@+id/rewind_song"
    android:layout_marginEnd="23dp"
    android:layout_alignParentBottom="true"
    android:layout_toStartOf="@+id/play_pause" />

<SeekBar
    android:id="@+id/seek_bar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_marginBottom="26dp"
    android:layout_above="@+id/play_pause"
    android:layout_alignParentStart="true" />

<TextView
    android:text="TextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="146dp"
    android:id="@+id/details_text_view" />


</RelativeLayout>

Here is the PlayerScreen.java class:

public class PlayerScreen extends AppCompatActivity implements     View.OnClickListener{

private Button playPause, nextSong, prevSong;
public SeekBar mySeekBar;
private int count = 0;
public MediaPlayer mediaPlayer;
private Bundle newBundle = new Bundle();
private Intent newIntent;
private int pos;
private ArrayList<String> name;
private ArrayList<String> path;
private SeekBarThread mySeekBarThread;
private Thread myThread;
private TextView detailsTextView;

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

    playPause = (Button)findViewById(R.id.play_pause);
    nextSong = (Button)findViewById(R.id.next_song);
    prevSong = (Button)findViewById(R.id.prev_song);
    mySeekBar = (SeekBar)findViewById(R.id.seek_bar);
    detailsTextView = (TextView)findViewById(R.id.details_text_view);

    playPause.setOnClickListener(this);
    nextSong.setOnClickListener(this);
    prevSong.setOnClickListener(this);

    newIntent = this.getIntent();
    newBundle = newIntent.getExtras();

    name = newBundle.getStringArrayList("title");
    path = newBundle.getStringArrayList("songpath");
    pos = newBundle.getInt("post");

    detailsTextView.setText(name.get(pos));

    mediaPlayer = new MediaPlayer();
    setMediaPlayer(pos);
}

public void setMediaPlayer(int position) {
    mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
    myThread = new Thread(mySeekBarThread);
    myThread.start();

    File mySong = new File(path.get(pos));
    mediaPlayer = new MediaPlayer();
    FileInputStream is = null;
    try {
        is = new FileInputStream(mySong);
    }
    catch(FileNotFoundException ex) {
        ex.printStackTrace();
    }

    try {
        mediaPlayer.setDataSource(is.getFD());
    }
    catch(IOException ex) {
        ex.printStackTrace();
    }

    try {
        mediaPlayer.prepare();
    }
    catch(IOException ex) {
        ex.printStackTrace();
    }
    finally {
        if(is != null) {
            try {
                is.close();
            }
            catch(IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    mediaPlayer.start();
}

@Override
protected void onPause() {
    super.onPause();
    mediaPlayer.pause();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mediaPlayer.stop();
}

@Override
public void onClick(View v) {
    switch(v.getId()) {
        case R.id.play_pause:
            count++;
            if(count%2 == 0) {
                v.setBackgroundResource(R.drawable.pause);
                mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
                mediaPlayer.start();
            }
            else {
                v.setBackgroundResource(R.drawable.play);
                mediaPlayer.pause();
            }
            break;

        case R.id.next_song:
            mediaPlayer.stop();
            pos = pos + 1;
            setMediaPlayer(pos);
            break;

        case R.id.prev_song:
            mediaPlayer.stop();
            pos = pos - 1;
            setMediaPlayer(pos);
            break;
    }
}
}

Most of the onCreate() code for this is class is dealing with which song to play based on the user's choice from the previous activity. And since the song is being played, i don't think there is a problem in that part of the code.

1

There are 1 best solutions below

12
On BEST ANSWER

@prakhar, Going through the code, I have found the following issues:

1) In SeekBarThread class in run() method setContentView() should not set,as it is already set in the activity class, as your are not reinitializing the click listeners.

2) Also the seekbarchangeListener should not be set in run() method and should be set in the main activity itself, as it doesn't need reinitalizing all the time.

3) The important point here is that your are initializing the SeekBarThread class before the initialization of MediaPlayer and hence there is no action even after seeking the seekbar.

A detailed code with the above modifications rectified.

public class PlayerScreen extends AppCompatActivity implements View.OnClickListener {

    private Button playPause, nextSong, prevSong;
    public SeekBar mySeekBar;
    private int count = 0;
    public MediaPlayer mediaPlayer;
    private Bundle newBundle = new Bundle();
    private Intent newIntent;
    private int pos;
    private ArrayList<String> name;
    private ArrayList<String> path;
    private SeekBarThread mySeekBarThread;
    private Thread myThread;
    private TextView detailsTextView;

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

        playPause = (Button) findViewById(R.id.play_pause);
        nextSong = (Button) findViewById(R.id.next_song);
        prevSong = (Button) findViewById(R.id.prev_song);
        mySeekBar = (SeekBar) findViewById(R.id.seek_bar);
        detailsTextView = (TextView) findViewById(R.id.details_text_view);

        playPause.setOnClickListener(this);
        nextSong.setOnClickListener(this);
        prevSong.setOnClickListener(this);

        mySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mediaPlayer.seekTo(seekBar.getProgress());
            }
        });

        newIntent = this.getIntent();
        newBundle = newIntent.getExtras();

        name = newBundle.getStringArrayList("title");
        pos = newBundle.getInt("post");

        detailsTextView.setText(name.get(pos));

        mediaPlayer = new MediaPlayer();
        setMediaPlayer(pos);
    }

    public void setMediaPlayer(int position) {

        File mySong = new File(path.get(pos));
        mediaPlayer = new MediaPlayer();
        FileInputStream is = null;
        try {
            is = new FileInputStream(mySong);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }

        try {
            mediaPlayer.setDataSource(is.getFD());
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        try {
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.prepare();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        mediaPlayer.start();

        mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
        myThread = new Thread(mySeekBarThread);
        myThread.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mediaPlayer.pause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.play_pause:
                count++;
                if (count % 2 == 0) {
                    v.setBackgroundResource(R.drawable.pause);
                    mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
                    mediaPlayer.start();
                } else {
                    v.setBackgroundResource(R.drawable.play);
                    mediaPlayer.pause();
                }
                break;

            case R.id.next_song:
                mediaPlayer.stop();
                pos = pos + 1;
                setMediaPlayer(pos);
                break;

            case R.id.prev_song:
                mediaPlayer.stop();
                pos = pos - 1;
                setMediaPlayer(pos);
                break;
        }
    }
}

public class SeekBarThread implements Runnable{

private SeekBar seekBar;
private MediaPlayer mp;
private Context context;

public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
    this.context = context;
    this.seekBar = seekBar;
    this.mp = mp;
}

public void run() {

    seekBar.setMax(mp.getDuration());



    int totalduration = mp.getDuration();
    int currentposition = 0;
    while(currentposition < totalduration) {
        try {
            sleep(500);
            currentposition = mp.getCurrentPosition();
            seekBar.setProgress(currentposition);
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

}