0

I have posted this question before and no one could answer it so I am trying again as this issue makes my app worthless. I need the sound to keep playing when the screen times out or the user taps the power button. I have read almost every online post about wake locks that I can find and i can not get it to work. below is one of the .Java files that plays a sound based on the user selected input. Everything works great except that when the screen goes dark the sound stops playing. Just a note, I am very new to this so if this code is sloppy or redundant please let me know.

package com.androidsleepmachine.gamble;

import android.app.Activity;
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;

public class Ship extends Activity implements View.OnClickListener {
public static final Integer[] TIME_IN_MINUTES = { 30, 45, 60, 180, 360 };
public MediaPlayer mediaPlayer;
public Handler handler = new Handler();
public Button button2;
public Spinner spinner2;
public PowerManager.WakeLock wl;


// Initialize the activity
@Override
public void onCreate(Bundle savedInstanceState) {
    PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 
"Playwhenoff");

    super.onCreate(savedInstanceState);
     wl.acquire();
    setContentView(R.layout.ship);
    button2 = (Button) findViewById(R.id.btn2);
    button2.setOnClickListener(this);
    spinner2 = (Spinner) findViewById(R.id.spinner2);
    ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this,
            android.R.layout.simple_spinner_item, TIME_IN_MINUTES);

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner2.setAdapter(adapter);

}

// Play the sound and start the timer
private void playSound(int resourceId) {
    // Cleanup any previous sound files
    cleanup();
    // Create a new media player instance and start it

    mediaPlayer = MediaPlayer.create(this, resourceId);
    mediaPlayer.start();
    // Create the timer to stop the sound after x number of milliseconds
    int selectedTime = TIME_IN_MINUTES[spinner2.getSelectedItemPosition()];
    handler.postDelayed(runnable, selectedTime * 60 * 1000);
}

// Handle button callback
@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn2:
        playSound(R.raw.ocean_ship);
        break;
    }
}

protected void onStop() {

    cleanup();
    super.onStop();
}

// Stop the sound and cleanup the media player
public void cleanup() {
    if (mediaPlayer != null) {
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
        wl.release();
    }
    // Cancel any previously running tasks
    handler.removeCallbacks(runnable);
}

// Runnable task used by the handler to stop the sound
public Runnable runnable = new Runnable() {
    public void run() {
        cleanup();
    }
};


@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    wl.release();
}

}
user2727048
  • 115
  • 2
  • 12

2 Answers2

1

This probably has nothing to do with the WakeLock. Your activity is probably being called with onStop() when the screen turns off.

Audio players usually use a service for the audio playback, so the playback can run independently of UI concerns like this.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • ok so I think i understand a little of what your saying. when I deleted the cleanup(); from the onStop(); the audio still played when i turned off the screen, the problem then is that it wont stop at all. how do I fix that – user2727048 Oct 03 '13 at 05:08
  • @user2727048: As I wrote, audio players usually use a service for the audio playback, so the playback can run independently of UI concerns like this. Your UI sends commands to the service to start and stop playback. – CommonsWare Oct 03 '13 at 10:13
  • i get what your saying but I am really new to this and I am not sure how to implement the change from having my activity play the sound to a service playing the sound – user2727048 Oct 03 '13 at 16:09
  • @user2727048: That is well beyond the scope of a StackOverflow answer, let alone a StackOverflow comment. The Android developer documentation has [docs on services](http://developer.android.com/guide/components/services.html) and [using a service to play back media](http://developer.android.com/guide/topics/media/mediaplayer.html#mpandservices). – CommonsWare Oct 03 '13 at 16:18
0

You are releasing your wakeLock onPause ->

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    wl.release(); // -> This is the line where you release the wakelock
}

When your device "goes to sleep", it goes like onPause -> onStop.

If you release your wakelock onPause, you will not be able to play your music with your screen off, because the system will not keep your CPU awaked.

Release it somewhere else (perhaps onDestroy?) and it should work.

reis_eliel
  • 338
  • 2
  • 7
  • Do I need to delete the onPause method and create the onDestroy method and place it there? – user2727048 Oct 02 '13 at 21:42
  • Yes, please try it and let me know. – reis_eliel Oct 02 '13 at 21:45
  • @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); wl.release(); } I got a message that said wakelocks should be released in onPause not onDestroy. It also stops playing the sound as soon as I press the power button to cut the screen off – user2727048 Oct 02 '13 at 21:55