1

我一直在关注创建音乐播放器的教程: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
4

1 回答 1

2

你忘了初始化ibNext

从您的代码中,我猜缺少的是

ibNext = (ImageButton) findViewById(R.id.ibNext);

如果我是对的,

ibNext.setOnClickListener(new View.OnClickListener() {

在线

 at com.timmo.music.Player.onCreate(Player.java:76)
于 2013-05-03T22:33:56.543 回答