我在android中制作音乐播放器应用程序。该应用程序已
MainActivity.java(带有相应的XML文件:activity_main):此活动有一个列表视图,显示所有可用歌曲的列表。
PlayerScreen.java(带有相应的XML文件:activity_player_screen):当在第一个活动上点击一首歌曲时,会启动此活动并播放该特定歌曲。此活动有3个按钮(播放/暂停,NextSong,PreviousSong)和搜索栏。
现在这是我遇到问题的地方
我创建了一个单独的类(SeekBarThread.java),用于使用线程实现activity_player_screen的搜索栏。
问题是当我从PlayerScreen.java调用我的线程类的start方法时,没有任何反应。没有异常被抛出。歌曲继续播放,但activity_player_screen的小部件停止工作,即我不能暂停播放下一首歌曲的歌曲。搜索栏也不起作用。
我认为我无法正确地将activity_player_screen文件与PlayerScreen.java和SeekBarThread.java链接。
这是从PlayerScreen.java调用Thread类
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();
我真的不想摆脱异常,所以我将seekbar对象和mediaplayer对象引用以及当前上下文引用传递给SeekBarThread类。但它没有用。
这是SeekBarThread.java类代码:
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文件:
<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>
这是PlayerScreen.java类:
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;
}
}
}
这个onCreate()的大部分代码都是基于用户从上一个活动中选择要播放的歌曲。而且由于正在播放这首歌,我认为这部分代码不存在问题。
答案 0 :(得分:1)
@prakhar,仔细阅读代码,我发现了以下问题:
1)在run()方法中的SeekBarThread类中,setContentView()不应该设置,因为它已经在活动类中设置,因为你没有重新初始化点击监听器。
2)此外,不应在run()方法中设置seekbarchangeListener,并且应在主活动本身中设置,因为它不需要一直重新启动。
3)这里重要的一点是你在MediaPlayer初始化之前初始化SeekBarThread类,因此即使在寻找搜索栏之后也没有动作。
完整上述修改的详细代码。
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实现了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();
}
}
}
}