سؤال

I coded a simple mp3 player a couple of days ago. The code is at Playing music in sleep/standby mode in Android 2.3.3

Everything works fine when the mp3 player (Samsung 3.6, Android 2.2) plays music on its own. I bought a bluetooth speaker (A2DP 3.0) and connected it to the mp3 player. The music still plays fine, but when the mp3 player screen goes dark into sleep mode, the music starts skipping on the bluetooth speaker.

  • It does not happen if the mp3 plays music on its own in sleep mode
  • Other music player apps in the mp3 player seem to play fine even in sleep mode over the bluetooth speaker
  • If I disable bluetooth, and play the music using the speaker connected by a cable, then the music plays fine even in standby mode.

This leads me to believe that something may be wrong with my code.

Here's my complete code:

public class MainActivity extends Activity {

private static String audioPath;
private static ArrayList<String> devotionalList;
private static ArrayList<String> christmasList;
private static ArrayList<String> cinemaList;
private static ImageButton playPauseButton;
private static TextView appMsg;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    int maxVolume = audioManager
            .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    int curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    SeekBar volControl = (SeekBar) findViewById(R.id.volumeBar);
    volControl.setMax(maxVolume);
    volControl.setProgress(curVolume);
    volControl
            .setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onStopTrackingTouch(SeekBar arg0) {
                }

                @Override
                public void onStartTrackingTouch(SeekBar arg0) {
                }

                @Override
                public void onProgressChanged(SeekBar arg0, int arg1,
                        boolean arg2) {
                    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
                            arg1, 0);
                }
            });

    File baseDir = Environment.getExternalStorageDirectory();
    audioPath = baseDir.getAbsolutePath() + "/external_sd/music/";

    devotionalList = loadSongs(audioPath + "devotional/");
    christmasList = loadSongs(audioPath + "christmas/");
    cinemaList = loadSongs(audioPath + "cinema/");
}

private ArrayList<String> loadSongs(String songDirectory) {
    File directory = new File(songDirectory);
    ArrayList<String> al1 = new ArrayList<String>();
    for (String filename : directory.list()) {
        al1.add(songDirectory + filename);
    }
    return al1;
}

public void playPauseSong(View v) {
    if (MP3PlayerService.isPlaying) {
        playPauseButton.setImageResource(android.R.drawable.ic_media_play);
        // Intent i1 = new Intent(this, MP3PlayerService.class);
        stopService(new Intent(this, MP3PlayerService.class));
    } else {
        if (MP3PlayerService.playerStarted) {
            playPauseButton
                    .setImageResource(android.R.drawable.ic_media_pause);
            startService(new Intent(this, MP3PlayerService.class));
        }
    }
}

public void playNextSong(View v) {
    if (MP3PlayerService.playerStarted) {
        startService(new Intent(this, MP3PlayerService.class));
    }
}

public void playPreviousSong(View v) {
    if (MP3PlayerService.playerStarted) {
        MP3PlayerService.previousSong = true;
        startService(new Intent(this, MP3PlayerService.class));
    }
}

@Override
protected void onPause() {
    super.onPause();
    playPauseButton = null;
    appMsg = null;
}

@Override
protected void onResume() {
    super.onResume();
    appMsg = (TextView) this.findViewById(R.id.txtAppMsg);
    appMsg.setText("");
    playPauseButton = (ImageButton) this.findViewById(R.id.btnPlayPause);
}

public void playDevotional(View v) {
    playPlayList(devotionalList);
}

public void playChristmas(View v) {
    playPlayList(christmasList);
}

public void playCinema(View v) {
    playPlayList(cinemaList);
}

private void playPlayList(ArrayList<String> playList) {
    if (MP3PlayerService.isPlaying) {
        MP3PlayerService.mediaPlayer.stop();
        MP3PlayerService.mediaPlayer.reset();
        MP3PlayerService.mediaPlayer.release();
    }
    MP3PlayerService.songPosition = 0;
    playPauseButton.setImageResource(android.R.drawable.ic_media_pause);
    Intent i1 = new Intent(this, MP3PlayerService.class);
    i1.putExtra("playListChoice", playList);
    startService(i1);
}

}

And here's my code for the mediaplayer service:

public class MP3PlayerService extends Service implements OnCompletionListener {
private static ArrayList<String> al1;
private static FileInputStream fis;
private static FileDescriptor fd;
static boolean previousSong;
static boolean playerStarted = false;
static int songPosition;
static boolean isPlaying = false;
static String currentSong;
static ArrayList<String> songHistory;
static MediaPlayer mediaPlayer;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    songHistory = new ArrayList<String>();
}

@Override
public void onDestroy() {
    songPosition = mediaPlayer.getCurrentPosition();
    mediaPlayer.pause();
    isPlaying = false;
}

@Override
public void onStart(Intent intent, int startid) {

    if (songPosition == 0) {
        Bundle extras = intent.getExtras();
        if (extras == null) {
            if (previousSong) {
                playSong();
            } else {
                // Next Song Button clicked
                playNextSong();
            }
        } else {
            // A Playlist button is clicked
            al1 = (ArrayList<String>) extras.get("playListChoice");
            playSong();
        }
    } else {
        songPosition = 0;
        mediaPlayer.start();
    }
    isPlaying = true;
}

private void playNextSong() {
    if (isPlaying) {
        mediaPlayer.release();
        playSong();
    }
}

private void playSong() {
    if (previousSong) {
        mediaPlayer.release();
        if (songHistory.size() > 1) {
            currentSong = songHistory.get(songHistory.size() - 2);
            songHistory.remove(songHistory.size() - 1);
        } else {
            currentSong = songHistory.get(0);
        }
        previousSong = false;
    } else {
        currentSong = al1.get(new Random().nextInt(al1.size()));
        songHistory.add(currentSong);
    }
    try {
        fis = new FileInputStream(currentSong);
        fd = fis.getFD();
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource(fd);
        mediaPlayer.prepare();
        mediaPlayer.seekTo(songPosition);
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.start();
        playerStarted = true;
    } catch (FileNotFoundException e) {
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
        e.printStackTrace();
    } catch (IOException e) {
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
        e.printStackTrace();
    }
}

@Override
public void onCompletion(MediaPlayer arg0) {
    playNextSong();
}
}
هل كانت مفيدة؟

المحلول

I think I fixed it. The slider volume code was the source of the problem. Without that piece, the app was still working during standby mode using the bluetooth speakers. I wanted the slider bar, so I tried acquring a partial wake lock after instantiating the media player for each song and that kept the app going correctly duing standby mode (with the slider volume control as part of the app as well). I release the lock later after each song.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top