0

我正在尝试在模拟器上运行我的项目。它工作正常,直到我将一首歌推入 sdcard 然后尝试重新运行。第一次尝试时,屏幕黑屏,但播放了歌曲,但重试后完全没有任何反应。起初我认为这可能是由于空间不足,所以我将 sdcard 大小从 100Mb 增加到 200Mb。但仍然没有任何反应。任何人请帮忙。logcat 看起来也不错。一段时间后,模拟器说应用程序没有响应。

询问代码:

公共类 AndroidBuildingMusicPlayerActivity 扩展 Activity 实现 OnCompletionListener、SeekBar.OnSeekBarChangeListener {

class AskGenreDialog {
    private String songTitle = "";
    private int id;
    EditText AskGenre;
    View view;
    public void setSongTitle(String songTitle){
        this.songTitle = songTitle;
    }

    public void setId(int id){
        this.id = id;
    }
    public void onCreateDialog(){

        AlertDialog.Builder builder = new AlertDialog.Builder(AndroidBuildingMusicPlayerActivity.this);
        LayoutInflater inflator = (LayoutInflater)AndroidBuildingMusicPlayerActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflator.inflate(R.layout.ask_genre, null);
        AskGenre = (EditText) view.findViewById(R.id.genre);
        builder.setView(view);
        builder.setTitle("Genre Not Found").setMessage(songTitle);

        builder.setPositiveButton("Save", new OnClickListener(){

            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                // TODO Auto-generated method stub
                String genre = AskGenre.getText().toString();
                int i = handler.setGenreForId(genre,id);

                Log.d("Ans:", "" + id);
            }

        });
        builder.setNegativeButton("Don't Know", new OnClickListener(){

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub

            }

        });

        // create alert dialog
        AlertDialog alertDialog = builder.create();

        // show it
        alertDialog.show();
    }

}
class VolumeSeekBar{

    AudioManager manager = (AudioManager) AndroidBuildingMusicPlayerActivity.this.getSystemService(Context.AUDIO_SERVICE);;
    SeekBar seekBar;
    View view;
    public SeekBar getSeekBar(){
        return this.seekBar;
    }
    public AudioManager getAudioManager(){
        return this.manager;
    }
    public void onCreateDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(AndroidBuildingMusicPlayerActivity.this);
        LayoutInflater inflator = (LayoutInflater)AndroidBuildingMusicPlayerActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflator.inflate(R.layout.volume, null);
        seekBar = (SeekBar) view.findViewById(R.id.volSeekBar);
        builder.setView(view);
        builder.setTitle("Volume Control");

        //get the audio manager
        int maxVolume = manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        seekBar.setMax(maxVolume);
        int curVolume = manager.getStreamVolume(AudioManager.STREAM_MUSIC);
        seekBar.setProgress(curVolume);
        seekBar.setKeyProgressIncrement(1); 
        seekBar.setProgress(manager.getStreamVolume(AudioManager.STREAM_MUSIC)); 

        seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.volume_seekbar_filled));
        seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
                // TODO Auto-generated method stub
                manager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0); 
                seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.volume_seekbar_filled));
            }
        });
        // create alert dialog
        AlertDialog alertDialog = builder.create();

        // show it
        alertDialog.show();

    }   

}

ToggleButton playPause;
Button rewind, forward;
ToggleButton moodButton;
ToggleButton volume;
private ImageButton btnPlaylist;
private ToggleButton repeat;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
// Media Player
private  MediaPlayer mp;
// Handler to update UI timer, progress bar etc,.
private Handler mHandler = new Handler();;
private SongsManager songManager;
private Utilities utils;
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<Song> songsList = new ArrayList<Song>();
private DatabaseHandler handler = new DatabaseHandler(this);
int version = 0;
boolean sortCalled = true;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // All player buttons
    btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
    moodButton = (ToggleButton) findViewById(R.id.moodButton);
    repeat = (ToggleButton) findViewById(R.id.repeat);
    volume = (ToggleButton) findViewById(R.id.volume);
    playPause = (ToggleButton) findViewById(R.id.PlayAndPauseButton);
    rewind = (Button) findViewById(R.id.rewind);
    forward = (Button) findViewById(R.id.forward);
    songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
    songTitleLabel = (TextView) findViewById(R.id.songTitle);
    songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
    songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
    // Mediaplayer
    mp = new MediaPlayer();
    songManager = new SongsManager();
    utils = new Utilities();

    // Listeners
    songProgressBar.setOnSeekBarChangeListener(this); // Important
    mp.setOnCompletionListener(this); // Important
    // Getting all songs list
    songsList = songManager.getPlayList();
    //final ArrayList<Song> backUp = new ArrayList<Song>(songsList);
    //handler.onUpgrade(handler.getReadableDatabase(), version , version + 1);
    version++;
    ArrayList<Song> songsFromDatabase = new ArrayList<Song>();
    songsFromDatabase = handler.getAllSongs();

    if(songsFromDatabase.size() == 0){
        feedDatabase(songsList);
    }
    else if(songsFromDatabase.size() != songsList.size()){
        feedDatabase(songsList, songsFromDatabase);
    }


    songsList = getPlaylist();
    checkForGenre(songsList);

    // By default play first song
    playSong(0);

    /**
     * Play button click event
     * plays a song and changes button to pause image
     * pauses a song and changes button to play image
     * */
    playPause.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // check for already playing
            if (playPause.isChecked()) {
                playPause.setBackgroundDrawable(getResources().getDrawable(R.drawable.play));
                mp.pause();
            } else {
                playPause.setBackgroundDrawable(getResources().getDrawable(R.drawable.pause));
                mp.start();
                //  startPlayProgressUpdater();
            }

        }
    });

    volume.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View v) {

            // TODO Auto-generated method stub
            if(volume.isChecked()){
                volume.setBackgroundDrawable(getResources().getDrawable(R.drawable.volume_button));
                VolumeSeekBar ob = new VolumeSeekBar();
                ob.onCreateDialog();
            }
            else{
                volume.setBackgroundDrawable(getResources().getDrawable(R.drawable.volume_button_disabled));

            }
        }



    });
    /**
     * Next button click event
     * Plays next song by taking currentSongIndex + 1
     * */
    forward.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;
            }

        }
    });

    /**
     * Back button click event
     * Plays previous song by currentSongIndex - 1
     * */
    rewind.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;
            }

        }
    });

    /**
     * Button Click event for Repeat button
     * Enables repeat flag to true
     * */
    repeat.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            if(repeat.isChecked()){
                isRepeat = true;
                repeat.setBackgroundDrawable(getResources().getDrawable(R.drawable.object_rotate_left_checked));
            }else{
                // make repeat to true
                isRepeat = false;
                repeat.setBackgroundDrawable(getResources().getDrawable(R.drawable.object_rotate_left)); 

            }
        }
    });

    /**
     * Button Click event for Shuffle button
     * Enables shuffle flag to true
     * */
    /*  btnShuffle.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            if(isShuffle){
                isShuffle = false;
                Toast.makeText(getApplicationContext(), "Shuffle is OFF", Toast.LENGTH_SHORT).show();
                btnShuffle.setImageResource(R.drawable.btn_shuffle);
            }else{
                // make repeat to true
                isShuffle= true;
                Toast.makeText(getApplicationContext(), "Shuffle is ON", Toast.LENGTH_SHORT).show();
                // make shuffle to false
                isRepeat = false;
              //  btnShuffle.setImageResource(R.drawable.btn_shuffle_focused);
                btnRepeat.setImageResource(R.drawable.btn_repeat);
            }
        }
    });*/

    /**
     * Button Click event for Play list click event
     * Launches list activity which displays list of songs
     * */
    btnPlaylist.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            Intent i = new Intent(getApplicationContext(), PlayListActivity.class);
            i.putExtra("sortCalled", sortCalled);
            startActivityForResult(i, 100);
        }
    });

}



/**
 * Receiving song index from playlist view
 * and play the song
 * */
@Override
protected void onActivityResult(int requestCode,
        int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == 100){
        currentSongIndex = data.getExtras().getInt("songIndex");
        sortCalled = data.getExtras().getBoolean("sortCalled");
        // play selected song
        playSong(currentSongIndex);
    }

}

/**
 * Function to play a song
 * @param songIndex - index of song
 * */
public void  playSong(int songIndex){

    songsList = getPlaylist();
    // Play song
    try {
        mp.reset();
        mp.setDataSource(songsList.get(songIndex).getSongPath());
        mp.prepare();
        mp.start();
        // Displaying Song title
        String songTitle = songsList.get(songIndex).getSongTitle();
        songTitleLabel.setText(songTitle);

        // Changing Button Image to pause image
        playPause.setBackgroundResource(R.drawable.pause);

        // set Progress bar values
        songProgressBar.setProgress(0);
        songProgressBar.setMax(100);

        // Updating progress bar
        updateProgressBar();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * Update timer on seekbar
 * */
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
        songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));
        // Displaying time completed playing
        songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));

        // Updating progress bar
        int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
        //Log.d("Progress", ""+progress);
        songProgressBar.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();
}

/**
 * On Song Playing completed
 * if repeat is ON play same song again
 * if shuffle is ON play random song
 * */
@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();
}

public void checkForGenre(ArrayList<Song> songsList){
    ArrayList<Song> temp = new ArrayList<Song>();
    temp = handler.getAllSongAfterSorting();
    for(int i = 0; i < temp.size(); i++){
        if("unknown".compareToIgnoreCase(temp.get(i).getGenre()) == 0){
            AskGenreDialog ask = new AskGenreDialog();
            ask.setSongTitle("The Genre for the song " + songsList.get(i).getSongTitle()+ 
            " is unknown. Do You wish to change it?");
            int id = handler.getIdForSong(songsList.get(i));
            if(id != -1)
                ask.setId(id);
            ask.onCreateDialog();


        }
    }

}

public void feedDatabase(ArrayList<Song> songsList){

    for(int i =0; i < songsList.size(); i++){
        //for(int j = 0; j < songsListFromDatabase.size(); j++){
        //  if(songs)
            Log.d("Insert:", "inserting...");
            handler.addSong(songsList.get(i));
            String song = "ID" + songsList.get(i).getId() + "SongName:" + songsList.get(i).getSongTitle();
            Log.d("Name:" , song);
        //}
    }
}

private void feedDatabase(ArrayList<Song> songsList,
        ArrayList<Song> songsFromDatabase) {
    // TODO Auto-generated method stub
    for(int i = 0; i < songsList.size(); i++){
        for(int j = 0; j < songsFromDatabase.size(); j++){

            boolean flag = true;
            if(songsList.get(i).getSongTitle().compareToIgnoreCase(songsFromDatabase.get(j).getSongTitle()) == 0){
                flag = false;

            }

            if(flag == true){
                handler.addSong(songsList.get(i));
            }

        }
    }
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    //if one of the volume keys were pressed
    if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)
    {
        VolumeSeekBar ob = new VolumeSeekBar();

        //change the seek bar progress indicator position
        ob.getSeekBar().setProgress(ob.getAudioManager().getStreamVolume(AudioManager.STREAM_MUSIC));

    }
    //propagate the key event
    return super.onKeyDown(keyCode, event);
} 

ArrayList<Song> getPlaylist(){

    ArrayList<Song> allSongs = new ArrayList<Song>();

    allSongs = handler.getAllSongAfterSorting();
    return allSongs;
}

DatabaseHandler getHandler(){
    return this.handler;
}

}

4

1 回答 1

0

您必须在 UI 线程中播放音频...

你应该阅读这个: http: //developer.android.com/guide/components/processes-and-threads.html和这个:http ://android-developers.blogspot.com/2009/05/painless-threading.html

为了证明,可以播放很短的音频文件(1s以内,看看会不会出现同样的问题)

编辑:

http://developer.android.com/guide/topics/media/mediaplayer.html已经有一些代码可用(使用服务)

另请注意该页面上的内容:

异步准备

使用 MediaPlayer 原则上可以很简单。但是,重要的是要记住,要正确地将其与典型的 Android 应用程序集成,还需要做一些事情。例如,对 prepare() 的调用可能需要很长时间才能执行,因为它可能涉及获取和解码媒体数据。因此,与任何可能需要很长时间才能执行的方法一样,您永远不应该从应用程序的 UI 线程中调用它。这样做会导致 UI 挂起,直到方法返回,这是非常糟糕的用户体验,并可能导致 ANR(应用程序无响应)错误。即使您希望您的资源能够快速加载,

为避免挂起您的 UI 线程,请生成另一个线程来准备 MediaPlayer 并在完成后通知主线程。但是,虽然您可以自己编写线程逻辑,但这种模式在使用 MediaPlayer 时非常常见,以至于框架提供了一种通过使用 prepareAsync() 方法来完成此任务的便捷方法。此方法开始在后台准备媒体并立即返回。媒体准备完成后,调用通过 setOnPreparedListener() 配置的 MediaPlayer.OnPreparedListener 的 onPrepared() 方法。

于 2012-10-31T15:12:11.440 回答