I have a sleep machine app that I want to still play the sound if the phone goes into stand by. I just edited to have the wake lock added and it is added in the manifest as well. It isnt working correctly but I am not sure why.
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;
private PowerManager.WakeLock wl;
// Initialize the activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
setContentView(R.layout.ship);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNjfdhotDimScreen");
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();
}
};
}
You can make it happen with wake locks. Its part of the Powermanager api.
A detailed explanation can be found here.
Related
I am new to Android development and am working on an app that I use for my work. It required multiple buttons to each pay a sound. It is however more complicated than that.
I have managed to make a mediaplayer that will play sounds, pause, fade etc from buttons giving the button tag a string that is passed to the player as file to play. I can press other buttons and start a new sound without problems after stopping and releasing the MP. My problem is As this is for my theatre show. I want to be able to cross mix (i.e as one sound fades the next is starting). The first thought is I need a different MP for each button (which would use a lot of copy code) and also I want to be able to set up nearly 100 buttons.
Has anyone done this before, I have searched for hours online to find very little help. Any help would be useful thank you in advance.
My code is below
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnLongClickListener;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends Activity {
MediaPlayer mp, mp2 ;
Button Sound1 ,Sound2, Stop, Pause , Fade;
TextView displaystatus;
String bName = "button pressed";
//set variables for volume control
private int iVolume;
private final static int INT_VOLUME_MAX = 100;
private final static int INT_VOLUME_MIN = 0;
private final static float FLOAT_VOLUME_MAX = 1;
private final static float FLOAT_VOLUME_MIN = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//connect interface to local variables
Fade=(Button)findViewById(R.id.bfade);
Sound1 = (Button)findViewById(R.id.bSound1);
Sound2 = (Button)findViewById(R.id.bSound2);
Stop =(Button)findViewById(R.id.bStop); Pause=(Button)findViewById(R.id.bPause);
displaystatus=(TextView)findViewById(R.id.tStatus);
mp2=new MediaPlayer();
//Button clicks to make play/pause/stop
Sound1.setOnClickListener(buttonPlayOnClickListener);
Sound2.setOnClickListener(buttonPlayOnClickListener);
Pause.setOnClickListener(buttonPauseOnClickListener);
Stop.setOnClickListener( buttonQuitOnClickListener);
Fade.setOnClickListener( buttonFadeOnClickListener);
//set onlongclicklistener to open SoundDetailActivity
Sound1.setOnLongClickListener(new View.OnLongClickListener(){
public boolean onLongClick(View v) {
//get the tag for the button pressed
bName= v.getTag().toString();
whenLongClick();
return true;
};
});
//set long click listener to open SoundDetailActivity
Sound2.setOnLongClickListener(new View.OnLongClickListener(){
public boolean onLongClick(View v) {
//get the tag for the button pressed
bName= v.getTag().toString();
whenLongClick();
return true;
};
});
}
private void initMediaPlayer ()
{
if(mp!=null){mp.stop();
mp.release();}
mp = new MediaPlayer();
File path=android.os.Environment.getExternalStorageDirectory();
try {
Log.v("paddy",path+bName);
mp.setDataSource(path+bName );
mp.prepare();
}catch (IOException e){
e.printStackTrace();
}
}
Button.OnClickListener buttonPlayOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View v) {
bName= v.getTag().toString();
initMediaPlayer();
Log.v("paddy",bName);
// if(mp.isPlaying()) {mp.reset();}
mp.start();
displaystatus.setText("- PLAYING -");
Pause.setText("Pause");
Log.v("paddy","no sound was playing");
}
};
Button.OnClickListener buttonPauseOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(mp.isPlaying()) {
mp.pause();
displaystatus.setText("- resume -");
Pause.setText("Resume");
}else{
mp.start();
displaystatus.setText("- playing -");
Pause.setText("Pause");
}
//finish();
}
};
Button.OnClickListener buttonQuitOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mp.stop();
mp.reset();
displaystatus.setText("- Ready -");
}
};
public Button.OnClickListener buttonFadeOnClickListener
=new Button.OnClickListener(){
#Override
public void onClick(View v) {
fade(5000); ///time in milliseconds
// TODO Auto-generated method stub
// mp.stop();
displaystatus.setText("- Fade out -");
//finish();
}
};
public void fade(int fadeDuration)
{
//Set current volume, depending on fade or not
if (fadeDuration > 0)
iVolume = INT_VOLUME_MAX;
else
iVolume = INT_VOLUME_MIN;
updateVolume(0);
//Start increasing volume in increments
if(fadeDuration > 0)
{
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask()
{
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
updateVolume(-1);
if (iVolume <= INT_VOLUME_MIN) {
timer.cancel();
timer.purge();
//Pause music
if (mp.isPlaying()) mp.stop();
mp.release();
mp = new MediaPlayer();
mp = MediaPlayer.create(MainActivity.this, R.raw.franksinatra);
displaystatus.setText("- Ready -");
Log.v("paddy","getting to end of fade");
}
}
});
}
};
// calculate delay, cannot be zero, set to 1 if zero
int delay = fadeDuration/INT_VOLUME_MAX;
if (delay == 0) delay = 1;
timer.schedule(timerTask, delay, delay);
}
}
// when a button is longclicked the activity sound details is opened and the sound button tag is sent as an extra.
public void whenLongClick () {
Toast.makeText(getApplicationContext(), bName , Toast.LENGTH_LONG).show();
Intent i = new Intent(this,SoundDetailActivity.class);
i.putExtra("ButtonId",bName);
startActivity(i);
}
private void updateVolume(int change)
{
//increment or decrement depending on type of fade
iVolume = iVolume + change;
//ensure iVolume within boundaries
if (iVolume < INT_VOLUME_MIN)
iVolume = INT_VOLUME_MIN;
else if (iVolume > INT_VOLUME_MAX)
iVolume = INT_VOLUME_MAX;
//convert to float value
float fVolume = 1 - ((float) Math.log(INT_VOLUME_MAX - iVolume) / (float) Math.log(INT_VOLUME_MAX));
//ensure fVolume within boundaries
if (fVolume < FLOAT_VOLUME_MIN)
fVolume = FLOAT_VOLUME_MIN;
else if (fVolume > FLOAT_VOLUME_MAX)
fVolume = FLOAT_VOLUME_MAX;
mp.setVolume(fVolume, fVolume);
}
}
I am rather new to android and I am attempting an alarm clock app. I am starting an activity through an AlarmManager which works fine as long as the phone is awake. When the phone is asleep it appears to run the code properly and then it runs the onStop function closing the activity. I have tried various combinations of WakeLock and Window flags with no avail.
This does however work on an older phone (2.3) if that helps. Any insight is appreciated.
Here is code for the Alarm activity:
package com.myAlarm.android;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.DigitalClock;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextClock;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ImageView;
import com.snoozulooze.android.UtilityFunctions;
#SuppressLint("NewApi")
public class Alarm extends Activity{
private int timerDelay = 4000;
private int id;
private double snoozeInt = 1;
private TextView clockText;
private TextView dateText;
private LinearLayout clockLayout;
private DatabaseHandler db;
public static AlarmRow ALARM_DATA;
private Animation animScroll;
private SensorManager mSensorManager;
private ShakeEventListener mSensorListener;
private Runnable alertLoop;
private Handler handler;
private ImageView snooze;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
turnOnScreen();
Log.i("ALARM", "on create ran");
AlarmWakeLock.acquireCpuWakeLock(Alarm.this);
setContentView(R.layout.activity_alarm);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorListener = new ShakeEventListener();
handler = new Handler();
alertLoop = new Runnable() {
#Override
public void run() {
playAlarm();
handler.postDelayed(this, timerDelay);
}
};
//Create the clock for text clock of digital clock
LayoutParams clockParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
clockLayout = (LinearLayout)findViewById(R.id.alarmClockLayout);
dateText = (TextView) findViewById(R.id.alarmClockDateTxt);
try{
TextClock tc = new TextClock(Alarm.this);
tc.setLayoutParams(clockParams);
tc.setTextColor(getResources().getColor(R.color.white));
tc.setGravity(Gravity.CENTER);
clockText = (TextClock) tc;
}
catch(Throwable t){
Log.e("Alarm", t.getMessage());
DigitalClock dc = new DigitalClock(Alarm.this);
dc.setLayoutParams(clockParams);
dc.setTextColor(getResources().getColor(R.color.white));
dc.setGravity(Gravity.CENTER);
clockText = (TextView) dc;
}
clockLayout.addView(clockText,0);
UtilityFunctions.assignText(Alarm.this, clockText, "fonts/Roboto-Thin.ttf");
SimpleDateFormat sdf = new SimpleDateFormat("EEE. LLLL dd");
String currentDateandTime = sdf.format(new Date());
dateText.setText(currentDateandTime.toLowerCase());
clockLayout.post(new Runnable(){
public void run(){
float clockHeight = (float) (clockLayout.getHeight()*.35);
float dateHeight = (float) (clockLayout.getHeight()*.15);
if (clockHeight > 45){
clockHeight = 45;
dateHeight = 24;
}
clockText.setTextSize(((float) clockHeight));
dateText.setTextSize(((float) dateHeight));
}
});
//SetupAlarm aSetUp = new SetupAlarm();
//aSetUp.execute();
init();
}
private void init(){
db = new DatabaseHandler(this);
Intent fromIntent = getIntent();
Bundle bundle = fromIntent.getExtras();
id = bundle.getInt("id");
Alarm.ALARM_DATA = db.getAlarmData(id);
snooze = (ImageView) findViewById(R.id.snoozeAlarmBtn);
setupUI();
}
private void setupUI(){
String message = Alarm.ALARM_DATA.getMessage();
if(message != "" && message != null){
TextView tv = new TextView(Alarm.this);
tv.setText(message);
tv.setTextSize(16);
FrameLayout sf = (FrameLayout) findViewById(R.id.snoozFrame);
tv.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
sf.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
sf.addView(tv, tv.getMeasuredWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
animScroll = new TranslateAnimation(sf.getMeasuredWidth(), tv.getMeasuredWidth()*-1, 0, 0);
long durationMulti = ((sf.getMeasuredWidth()+tv.getMeasuredWidth())/sf.getMeasuredWidth());
int duration = (int) (5000*durationMulti);
animScroll.setDuration(duration);
animScroll.setInterpolator(new LinearInterpolator());
animScroll.setRepeatCount(Animation.INFINITE);
tv.startAnimation(animScroll);
}
snooze.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
handler.removeCallbacks(alertLoop);
handler.removeCallbacksAndMessages(null);
AlarmReceiverRepeating.resetPhone(Alarm.this);
AlarmReceiver ar = new AlarmReceiver();
ar.setOnetimeTimer(Alarm.this, Alarm.ALARM_DATA.getId(), (long) (System.currentTimeMillis() + (1000*60*snoozeInt)),Alarm.ALARM_DATA.getId());
Intent mainIntent = new Intent(Alarm.this,Main.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(mainIntent);
finish();
AlarmWakeLock.releaseCpuLock();
}
});
mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {
public void onShake() {
handler.removeCallbacks(alertLoop);
handler.removeCallbacksAndMessages(null);
AlarmReceiverRepeating.resetPhone(Alarm.this);
Intent mainIntent = new Intent(Alarm.this,Main.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(mainIntent);
Notifications.setNextAlarmNotification(Alarm.this);
AlarmReceiverRepeating.resetPhone(Alarm.this);
finish();
AlarmWakeLock.releaseCpuLock();
}
});
AlarmReceiverRepeating.setCurrentState(Alarm.this,Alarm.ALARM_DATA.getVolume());
handler.post(alertLoop);
}
//function for playing the ringer and vibrator
public void playAlarm(){
try {
if(AlarmReceiverRepeating.AUDIO_MANAGER == null){
AlarmReceiverRepeating.setCurrentState(Alarm.this, Alarm.ALARM_DATA.getVolume());
}
AlarmReceiverRepeating.REPEAT_COUNT ++;
if(AlarmReceiverRepeating.REPEAT_COUNT > 1){
AlarmReceiverRepeating.REPEAT_COUNT = 0;
if(AlarmReceiverRepeating.CURRENT_VOLUME < AlarmReceiverRepeating.ADJUSTED_MAX_VOLUME)
AlarmReceiverRepeating.CURRENT_VOLUME++;
}
AlarmReceiverRepeating.AUDIO_MANAGER.setStreamVolume(AudioManager.STREAM_RING, AlarmReceiverRepeating.CURRENT_VOLUME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
Vibrator vibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2000);
AlarmReceiverRepeating.AUDIO_MANAGER.setStreamVolume(AudioManager.STREAM_RING, AlarmReceiverRepeating.CURRENT_VOLUME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
Uri alarm = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(Alarm.this);
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(Alarm.this, alarm);
} catch (Exception e1) {
e1.printStackTrace();
mediaPlayer.release();
return;
}
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
try {
mediaPlayer.prepare();
} catch (Exception e1) {
e1.printStackTrace();
mediaPlayer.release();
return;
}
mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
#Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
mediaPlayer.stop();
mediaPlayer.start();
}
});
mediaPlayer.setVolume(AlarmReceiverRepeating.CURRENT_VOLUME, AlarmReceiverRepeating.CURRENT_VOLUME);
mediaPlayer.start();
}
catch (Throwable t) {
Log.i("ALARM", "ERROR PLAYING ALARM");
Toast.makeText(this, "there was a problem in the playAlarm function", Toast.LENGTH_SHORT).show();
}
}//end playAlarm
#Override
protected void onStop(){
super.onStop();
Log.i("ALARM", "on stop ran");
handler.removeCallbacks(alertLoop);
handler.removeCallbacksAndMessages(null);
Notifications.setNextAlarmNotification(Alarm.this);
AlarmReceiverRepeating.resetPhone(this);
finish();
AlarmWakeLock.releaseCpuLock();
}
#Override
protected void onStart(){
super.onStart();
}
#Override
protected void onPause(){
super.onPause();
Log.i("ALARM", "on pause ran");
}
#Override
protected void onDestroy(){
super.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
turnOnScreen();
Log.i("ALARM", "on resume ran");
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
private void turnOnScreen(){
final Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
private class SetupAlarm extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... urls) {
init();
return null;
}
protected void onPostExecute(Void args) {
setupUI();
}
}
}
I have figured out what was going on. It was not a wakelock issue. The issue is that, for whatever reason the onStop function was (is still) being called when the phone wakes from sleeping. Since I had a finish() function running it was killing the activity. I placed the code in the onStop override so that the alarm will stop if the user hits the back or home button so I will need to address that unless someone can enlighten me on why the onStop is called an how to avoid it. Thanks
You will need to include this permission in your manifest:
uses-permission android:name="android.permission.WAKE_LOCK" or see this it might helpful to you How do I prevent an Android device from going to sleep programmatically?
This question already has answers here:
WakeLock not working
(2 answers)
Closed 8 years ago.
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();
}
}
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.
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.
The idea is to click the spinner and have it give you a list of times to play the sound. once you pick a sound and click the button it should play. it doesnt work and I cant figure out why. I have a home screen and a home activity that when you click a button take you to a new activity and a new layout. I can get the new layout and new activity to load, which is the one featured below, but the sound and spinner do not start.
package com.androidsleepmachine.gamble;
package com.androidsleepmachine.gamble;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
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 int[] TIME_IN_MINUTES = { 30, 45, 60 };
public MediaPlayer mediaPlayer;
public Handler handler = new Handler();
public Button button1;
public Spinner spinner1;
// Initialize the activity
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.ship);
button1 = (Button) findViewById(R.id.btnSubmit);
button1.setOnClickListener(this);
spinner1 = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this,
android.R.layout.simple_spinner_item);
}
// 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[spinner1.getSelectedItemPosition()];
handler.postDelayed(runnable, selectedTime * 60 * 1000);
}
// Handle button callbacks
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSubmit:
playSound(R.raw.ocean_ship);
break;
}
}
// Stop the sound and cleanup the media player
public void cleanup() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
// 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();
}
};
}
It looks like the problem is in your switch statemenet. You are checking for the id of button1 but the only button that you have assigned the listener to is button1 which has an id of btnSubmit. So your playSound() function is never getting called.
Change your onClick() to
// Handle button callbacks
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSubmit:
playSound(R.raw.ocean_ship);
break;
}
}
Edit
For your ArrayAdapter try something like
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);
spinner1.setAdapter(adapter);
Are you doing this on emulator? Mediaplayer doesnt work on emulator. You will have to test this in real device.
I have a memory leak. Here's the code
package fourguys.testing.IntentTest;
import android.app.Activity; import android.media.MediaPlayer; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.media.MediaPlayer; import android.media.AudioManager; import android.content.Context;
public class CanvasDrawingActivity extends Activity {
private static final int FIRE = 0;
private int initVolume = 0;
private Handler handler;
private MyCanvas v;
private MediaPlayer mp;
private AudioManager am;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
am = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
// this method gets the current volume setting for music
initVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
am.setStreamVolume(AudioManager.STREAM_MUSIC,100,AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
mp = MediaPlayer.create(this, R.raw.test);
makeHandler();
v =new MyCanvas(this);
new Thread(new Runnable(){
#Override
public void run() {
while(true)
handler.sendEmptyMessage(FIRE);
}}).start();
setContentView(v);
mp.setLooping(true);
mp.start();
}
private void makeHandler()
{
handler = new Handler(){
#Override
public void handleMessage(Message msg) {
switch(msg.what)
{
case FIRE:
{
v.invalidate();
break;
}
}
}
};
}
protected void onPause() {
super.onPause();
mp.stop();
}
protected void onFinish() {
mp.stop();
}
}
and this:
package fourguys.testing.IntentTest;
import android.app.Activity; import android.content.Intent; import android.media.MediaPlayer; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.view.WindowManager;
public class IntentTest extends Activity { /** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//reciever intentReceiver = new reciever();
// IntentFilter intentFilter = new IntentFilter("com.app.REC");
//registerReceiver(intentReceiver, intentFilter);
Button b = (Button)this.findViewById(R.id.endButton);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(IntentTest.this,CanvasDrawingActivity.class);
startActivity(i);
}
});
}
// the onPause method get called when the app is either being hidden or being closed so this the place where we would want to clean anything up like stoping the media player.
#Override
protected void onPause()
{
super.onPause();
}
}
I run the app and it gets wonky on exit. It locks the handset and causes the battery to run hot. I need to pull the battery physically to reboot. Any thoughts as to why that might be? It runs fantastically on the emulator. Should I be using onFinish instead, or am I not cleaning something up and I'm missing it?
It is this part of your code:
new Thread(new Runnable(){
#Override
public void run() {
while(true)
handler.sendEmptyMessage(FIRE);
}}).start();
You're doing three obvious things wrong here. 1) You're not killing it and/or pausing it in Activity#onPause. 2) You're not calling setDaemon(true); this will cause the process to continue and not die while this thread is running. 3) you're using a hot loop, i.e., you're not calling Thread#sleep() or some other type of equivalent method there to pause and stop fully using the cpu.