我一直在关注创建音乐播放器的教程:http ://www.androidhive.info/2012/03/android-building-audio-player-tutorial/
我遵循本教程的每一个细节,并多次交叉检查我的代码。我使用的唯一区别是使用长按而不是单独的倒带/快进按钮,我确定这不是问题。
我不完全确定问题是什么,所以我希望有人能找到问题所在..
这是我的代码,希望有人能弄清楚我的活动无法启动的原因:
播放器.java
public class Player extends Activity implements OnCompletionListener, SeekBar.OnSeekBarChangeListener {
private ViewSwitcher vsPlayPause;
private ImageButton ibPlay, ibPause, ibPrevious, ibNext, ibShuffle, ibRepeat;
private TextView tvTitle, tvArtist, tvAlbum, tvTimeProgress, tvTimeTotal;
private SeekBar seeker;
// Media Player
private MediaPlayer mp;
// Handler to update UI timer, progress bar etc,.
private Handler mHandler = new Handler();;
private TrackManager TrackManager;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
vsPlayPause = (ViewSwitcher) findViewById(R.id.vsPlayPause);
ibPlay = (ImageButton) findViewById(R.id.ibPlay);
ibPause = (ImageButton) findViewById(R.id.ibPause);
ibPrevious = (ImageButton) findViewById(R.id.ibPrevious);
ibShuffle = (ImageButton) findViewById(R.id.ibShuffle);
ibRepeat = (ImageButton) findViewById(R.id.ibRepeat);
ibPlay = (ImageButton) findViewById(R.id.ibPlay);
tvTitle = (TextView) findViewById(R.id.tvTitle);
tvArtist = (TextView) findViewById(R.id.tvArtist);
tvAlbum = (TextView) findViewById(R.id.tvAlbum);
tvTimeProgress = (TextView) findViewById(R.id.tvTimeProgress);
tvTimeTotal = (TextView) findViewById(R.id.tvTimeTotal);
seeker = (SeekBar) findViewById(R.id.seeker);
mp = new MediaPlayer();
TrackManager = new TrackManager();
utils = new Utilities();
// Listeners
seeker.setOnSeekBarChangeListener((OnSeekBarChangeListener) this); // Important
mp.setOnCompletionListener((OnCompletionListener) this); // Important
// Getting all songs list
songsList = TrackManager.getPlayList();
ibNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// check if next song is there or not
if (currentSongIndex < (songsList.size() - 1)) {
playSong(currentSongIndex + 1);
currentSongIndex = currentSongIndex + 1;
} else {
// play first song
playSong(0);
currentSongIndex = 0;
}
}
});
ibNext.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View arg0) {
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekForward time is lesser than song duration
if (currentPosition + seekForwardTime <= mp.getDuration()) {
// forward song
mp.seekTo(currentPosition + seekForwardTime);
} else {
// forward to end position
mp.seekTo(mp.getDuration());
}
return false;
}
});
ibPrevious.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (currentSongIndex > 0) {
playSong(currentSongIndex - 1);
currentSongIndex = currentSongIndex - 1;
} else {
// play last song
playSong(songsList.size() - 1);
currentSongIndex = songsList.size() - 1;
}
}
});
ibPrevious.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View arg0) {
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekBackward time is greater than 2 sec
if (currentPosition - seekBackwardTime >= 2) {
// forward song
mp.seekTo(currentPosition - seekBackwardTime);
} else {
// backward to starting position
mp.seekTo(0);
}
return false;
}
});
ibPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
vsPlayPause.showNext();
}
});
ibPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
vsPlayPause.showPrevious();
}
});
ibRepeat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (isRepeat) {
isRepeat = false;
Toast.makeText(getApplicationContext(), "Repeat is OFF", Toast.LENGTH_SHORT).show();
ibRepeat.setImageResource(R.drawable.norepeat);
} else {
// make repeat to true
isRepeat = true;
Toast.makeText(getApplicationContext(), "Repeat is ON", Toast.LENGTH_SHORT).show();
// make shuffle to false
isShuffle = false;
ibRepeat.setImageResource(R.drawable.repeat);
ibShuffle.setImageResource(R.drawable.noshuffle);
}
}
});
ibShuffle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (isShuffle) {
isShuffle = false;
Toast.makeText(getApplicationContext(), "Shuffle is OFF", Toast.LENGTH_SHORT).show();
ibShuffle.setImageResource(R.drawable.noshuffle);
} else {
// make repeat to true
isShuffle = true;
Toast.makeText(getApplicationContext(), "Shuffle is ON", Toast.LENGTH_SHORT).show();
// make shuffle to false
isRepeat = false;
ibShuffle.setImageResource(R.drawable.shuffle);
ibRepeat.setImageResource(R.drawable.norepeat);
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 100) {
currentSongIndex = data.getExtras().getInt("songIndex");
// play selected song
playSong(currentSongIndex);
}
}
public void playSong(int songIndex) {
// Play song
try {
mp.reset();
mp.setDataSource(songsList.get(songIndex).get("songPath"));
mp.prepare();
mp.start();
// Displaying Song title
String songTitle = songsList.get(songIndex).get("songTitle");
tvTitle.setText(songTitle);
// set Progress bar values
seeker.setProgress(0);
seeker.setMax(100);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void updateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
// Background Runnable thread
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
// Displaying Total Duration time
tvTimeTotal.setText("" + utils.milliSecondsToTimer(totalDuration));
// Displaying time completed playing
tvTimeProgress.setText("" + utils.milliSecondsToTimer(currentDuration));
// Updating progress bar
int progress = (int) (utils.getProgressPercentage(currentDuration, totalDuration));
// Log.d("Progress", ""+progress);
seeker.setProgress(progress);
// Running this thread after 100 milliseconds
mHandler.postDelayed(this, 100);
}
};
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
}
// When user starts moving the progress handler
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress bar
mHandler.removeCallbacks(mUpdateTimeTask);
}
// When user stops moving the progress hanlder
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);
// forward or backward to certain seconds
mp.seekTo(currentPosition);
// update timer progress again
updateProgressBar();
}
@Override
public void onCompletion(MediaPlayer arg0) {
// check for repeat is ON or OFF
if (isRepeat) {
// repeat is on play same song again
playSong(currentSongIndex);
} else if (isShuffle) {
// shuffle is on - play a random song
Random rand = new Random();
currentSongIndex = rand.nextInt((songsList.size() - 1) - 0 + 1) + 0;
playSong(currentSongIndex);
} else {
// no repeat or shuffle ON - play next song
if (currentSongIndex < (songsList.size() - 1)) {
playSong(currentSongIndex + 1);
currentSongIndex = currentSongIndex + 1;
} else {
// play first song
playSong(0);
currentSongIndex = 0;
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
mp.release();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.player, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menulibrary:
Intent iFs = new Intent(Player.this, Library.class);
startActivity(iFs);
return true;
case R.id.menusettings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
日志猫
05-03 23:07:02.890: E/Trace(28976): error opening trace file: No such file or directory (2)
05-03 23:07:03.005: D/AndroidRuntime(28976): Shutting down VM
05-03 23:07:03.005: W/dalvikvm(28976): threadid=1: thread exiting with uncaught exception (group=0x4202a930)
05-03 23:07:03.005: E/AndroidRuntime(28976): FATAL EXCEPTION: main
05-03 23:07:03.005: E/AndroidRuntime(28976): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.timmo.music/com.timmo.music.Player}: java.lang.NullPointerException
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2310)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.ActivityThread.access$600(ActivityThread.java:154)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1248)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.os.Handler.dispatchMessage(Handler.java:99)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.os.Looper.loop(Looper.java:137)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.ActivityThread.main(ActivityThread.java:5233)
05-03 23:07:03.005: E/AndroidRuntime(28976): at java.lang.reflect.Method.invokeNative(Native Method)
05-03 23:07:03.005: E/AndroidRuntime(28976): at java.lang.reflect.Method.invoke(Method.java:511)
05-03 23:07:03.005: E/AndroidRuntime(28976): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
05-03 23:07:03.005: E/AndroidRuntime(28976): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
05-03 23:07:03.005: E/AndroidRuntime(28976): at dalvik.system.NativeStart.main(Native Method)
05-03 23:07:03.005: E/AndroidRuntime(28976): Caused by: java.lang.NullPointerException
05-03 23:07:03.005: E/AndroidRuntime(28976): at com.timmo.music.Player.onCreate(Player.java:76)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.Activity.performCreate(Activity.java:5104)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
05-03 23:07:03.005: E/AndroidRuntime(28976): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2264)
05-03 23:07:03.005: E/AndroidRuntime(28976): ... 11 more