0

エミュレーターでプロジェクトを実行しようとしています。SDカードに曲をプッシュしてから再実行するまでは正常に機能していました。最初の試行では、画面が空白になり、曲は再生されましたが、再試行した後、まったく応答がありませんでした。最初はスペース不足が原因だと思ったので、SDカードのサイズを100Mbから200Mbに増やしました。しかし、まだ応答はありません。誰でも助けてください。また、logcatは問題ないようでした。そしてしばらくすると、エミュレーターはアプリが応答していないと言います。

尋ねられたコード:

public class AndroidBuildingMusicPlayerActivity extends Activity implements 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

それを証明するために、非常に短いオーディオファイルを再生できます(1秒未満、同じ問題が発生するかどうかを確認してください)

編集:

http://developer.android.com/guide/topics/media/mediaplayer.html(サービスを使用)ですでに利用可能なコードがいくつかあります

そのページの内容にも注意してください。

非同期準備

MediaPlayerの使用は、原則として簡単です。ただし、一般的なAndroidアプリケーションと正しく統合するには、さらにいくつかのことが必要であることを覚えておくことが重要です。たとえば、prepare()の呼び出しは、メディアデータのフェッチとデコードを伴う可能性があるため、実行に時間がかかる場合があります。したがって、実行に時間がかかる可能性のあるメソッドの場合と同様に、アプリケーションのUIスレッドからメソッドを呼び出さないでください。これを行うと、メソッドが戻るまでUIがハングします。これは、ユーザーエクスペリエンスが非常に悪く、ANR(Application Not Responding)エラーが発生する可能性があります。リソースがすぐに読み込まれることを期待している場合でも、

UIスレッドがハングしないようにするには、別のスレッドを生成してMediaPlayerを準備し、完了したらメインスレッドに通知します。ただし、スレッドロジックを自分で作成することもできますが、MediaPlayerを使用する場合、このパターンは非常に一般的であるため、フレームワークは、prepareAsync()メソッドを使用してこのタスクを実行する便利な方法を提供します。このメソッドは、バックグラウンドでメディアの準備を開始し、すぐに戻ります。メディアの準備が完了すると、setOnPreparedListener()を介して構成されたMediaPlayer.OnPreparedListenerのonPrepared()メソッドが呼び出されます。

于 2012-10-31T15:12:11.440 に答える