I am using a music in background of my activity. But when i am trying to cancel it its not working. The music is just continuously running until it finishes itself. Below is the code:
public class xx extends Activity
{ BackgroundSound mBackgroundSound = new BackgroundSound();
#Override
protected void onCreate(Bundle savedInstanceState)
{ ....
}
#Override
protected void onResume()
{
super.onResume();
mBackgroundSound.execute();
}
#Override
protected void onPause()
{
super.onPause();
mBackgroundSound.cancel(true);
}
and for options menu selection:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mBackgroundSound.cancel(true);
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.menu_Add:
{ mBackgroundSound.cancel(true);
Intent intent = new Intent(xx.this,yy.class);
intent.putExtra("flag", "add");
intent.putExtra("AddObj", "mm");
startActivity(intent);
break;
}
case R.id.menu_list_quote:
{
mBackgroundSound.cancel(true);
Intent intent = new Intent(xx.this,zz.class);
intent.putExtra("Obj", "nn");
startActivity(intent);
break;
}
}
//return true;
return super.onOptionsItemSelected(item);
}
and the asynTask:
public class BackgroundSound extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try
{
while( !isCancelled())
{
// FileDescriptor afd = openFd("cock_alarm.mp3");
MediaPlayer player = new MediaPlayer();
player.setDataSource(_musicFilePath);
player.prepare();
//player.setLooping(true); // Set looping
player.setVolume(100,100);
player.start();
// if(isCancelled())
// player.stop();
}
}
catch(Exception exp)
{
exp.printStackTrace();
}
return null;
}
}
Also, tried using for loop:
for(int i=0;i<100 && !isCancelled();i++)
and tried this inside try block of asyncTask:
if(isCancelled())
player.stop();
How am i going to solve it?
Instead of creating an AsyncTask, why not just create the MediaPlayer, and start it from your activity?
The MediaPlayer has its own threading logic built into it. You don't need to create a thread to manage the media player. You can read more here: http://developer.android.com/guide/topics/media/mediaplayer.html
In your activity, you could do the following:
private MediaPlayer mMediaPlayer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initalize the media player
mMediaPlayer = ... however you are initializing it ...;
// Set the listener so the media player can tell you when it is finished preparing
mMediaPlayer.setOnPreparedListener(this);
// Prepare the MediaPlayer asynchronously so that the UI thread does not lock up
mMediaPlayer.prepareAsync();
}
// You need to listen for when the Media Player is finished preparing and is ready
public void onPrepared(MediaPlayer player) {
// Start the player
player.start();
}
Then whenever you need to stop the player, simply call
mMediaPlayer.stop();
As, vogella explains it on his website:
"The AsyncTask does not handle configuration changes automatically, i.e. if the activity is recreated, the programmer has to handle that in his coding.
A common solution to this is to declare the AsyncTask in a retained headless fragment."
Look for full text to:
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html#androidbackground
Related
I want a play button in my app that when clicked plays the audio and changes to pause, and when the pause button is clicked the audio stops and the button changes to play again and so on. But the button is not working as expected. Please help. I'm adding my java code below.
public class surah extends AppCompatActivity {
MediaPlayer mp = new MediaPlayer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_surah);
mp=MediaPlayer.create(surah.this, R.raw.surahkahf);
final ImageView audio = (ImageView)findViewById(R.id.btn);
audio.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mp.isPlaying()){
mp.stop();
audio.setBackgroundResource(R.drawable.play);
try {
mp.prepare();
}catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
mp.start();
audio.setImageResource(R.drawable.pause);
}
}
});
}
}
Use audio.setImageResource(R.drawable.play) instead of audio.setBackgroundResource(R.drawable.play). Use mp.pause() instead of mp.stop();
First, as aborocz mentions in comments, you probably intend to pause playback instead of stop it, so the method you want to use is pause(). In that case you would not need to prepare the MediaPlayer again, and it will start from the same place it was paused when playback is resumed.
Second, the isPlaying() method is not particularly appropriate for this purpose. There are race conditions that prevent the desired behavior. From the Android MediaPlayer documentation:
Note that the transition from the Started state to the Paused state
and vice versa happens asynchronously in the player engine. It may
take some time before the state is updated in calls to isPlaying(),
and it can be a number of seconds in the case of streamed content.
Instead, store your own boolean value.
public class surah extends AppCompatActivity {
private MediaPlayer mp;
private boolean isMediaPlaying = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_surah);
mp = MediaPlayer.create(surah.this, R.raw.surahkahf);
final ImageView audio = (ImageView)findViewById(R.id.btn);
audio.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isMediaPlaying) {
mp.pause();
audio.setBackgroundResource(R.drawable.play);
isMediaPlaying = false;
} else {
mp.start();
audio.setImageResource(R.drawable.pause);
isMediaPlaying = true;
}
}
});
}
}
hi i'm trying to create a simple Online Radio i want to keep radio playing in bakcground and i know i should use Service but i don't how to use it please help me to make my app radio keep playing in background
this my code :
Button b_play ;
MediaPlayer mediaPlayer ;
boolean prepared = false;
boolean started = false;
String stream = "http://stream.radio.co/s98f81d47e/listen";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b_play = (Button)findViewById(R.id.b_play);
b_play.setEnabled(false);
b_play.setText("Loading");
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
b_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(started){
started = false;
mediaPlayer.pause();
b_play.setText("Play");
}else{
started = true;
mediaPlayer.start();
b_play.setText("Pause");
}
}
});
}
class PlayerTask extends AsyncTask<String, Void ,Boolean>{
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
b_play.setEnabled(true);
b_play.setText("Play");
}
}
#Override
protected void onPause() {
super.onPause();
if(started){
mediaPlayer.pause();
}
}
#Override
protected void onResume() {
super.onResume();
if(started){
mediaPlayer.start();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(prepared){
mediaPlayer.release();
}
}
}
Play the music from the foreground service.
Official Android documentation says:
that is a service that the user is actively aware of and is not a
candidate for the system to kill when low on memory. A foreground
service must provide a notification for the status bar, which is
placed under the Ongoing heading. This means that the notification
cannot be dismissed unless the service is either stopped or removed
from the foreground.
In your case a radio that plays music from a service should be set to run in the foreground, because the user is explicitly aware of its operation. The notification in the status bar might indicate the current song and allow the user to launch an activity to interact with the music player.
Here is an example
I am developing an app that plays a stream by using the built-in Android Mediaplayer. Everything works fine apart the fact that when I press the "home" button and then open the activity again, the app just starts a new instance of the mediaplayer and I can hear the stream twice without the possibility to stop the first one.
Scenario.
My app is only made of one activity.
I open my app first time and the stream starts.
Push the home button and the activity is "minimized" but the music still plays
I open my app again and it just starts a new instance of the mediaplayer playing the same music twice.
I check onResume if the mediaplayer is null or playing but somehow it appears to be always null thus a new instance is created.
My pseudo code...
public class MainActivity {
private MediaPlayer _mp;
private PlayTask _playTask;
private PauseTask _pauseTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume(){
super.onResume();
if(_mp != null && _mp.isPlaying()){
// I should find a playing mediaplayer here but it's always null!!!
Toast.makeText(MainActivity.this, "Playing mediaplayer found!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(MainActivity.this, "No mediaplayer found :(", Toast.LENGTH_SHORT).show();
}
}
/* ...:::============= *** ASYNCTASK Definition START *** =============:::... */
private class PlayTask extends AsyncTask<Void, Void, Integer> {
#Override
protected void onPreExecute() {
if(_mp == null)
_mp = new MediaPlayer();
else if(_mp.isPlaying()){
_mp.stop();
_mp.release();
_mp = null;
_mp = new MediaPlayer();
}
}
#Override
protected Integer doInBackground(Void...voids) {
try{
_mp.setDataSource(URL_DATASOURCE);
_mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
_mp.prepare();
_mp.start();
}
catch(Exception ex){
}
return 0;
}
#Override
protected void onPostExecute(Integer i) {
}
}
private class PauseTask extends AsyncTask<Void, Void, Integer> {
#Override
protected void onPreExecute() {
// Do Nothing here...for now
}
#Override
protected Integer doInBackground(Void...voids) {
_mp.stop();
_mp.release();
_mp = null;
return 0;
}
#Override
protected void onPostExecute(Integer i) {
}
}
public void playPause(View view){
if(_play){
_playTask = new PlayTask();
_playTask.execute();
}
else{
_pauseTask = new PauseTask();
_pauseTask.execute();
}
}
}
Any idea? Thanks
I would like to use the same button to start and stop playing some sounds with a for loop inside function play().
I thought to use lock variable to do this, but button after click remains pressed till the function play end is execution.
Can you suggest some solution?
I have a situation like this:
public class MainActivity extends Activity {
private static SoundPool sound;
static int lock=1;
int s;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sound=new SoundPool(20, AudioManager.STREAM_MUSIC, 100);
s=sound.load(this,R.raw.bipsound, 0);
Button button = (Button) findViewById(R.id.button);
}
public void onClick(View v) {
switch(lock) {
case 0:
lock=1;
break;
case 1:
lock=0;
play();
break;
}
}
public void play(){
for(int i=0;i<10;i++){
sound.play(s,1.0f, 1.0f, 1, 0, 1);
if(lock==1)
return;
try {Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This is a problem try {Thread.sleep(1000); inside play(). You are telling the main Thread to sleep which is almost always a bad idea. The Button becomes pressed and remains in that state until the sleep() time has finished.
Remove that line. And I'm not sure what you are trying to accomplish there but you can run it in a separate Thread with things like TimerTask, use a handler or other such features. If you need more help then please explain what you are trying to do with that.
That's normal because you're using try {Thread.sleep(1000); and it stop the main thread during 1 seconde.
You've to use an AsyncTask to do that :)
Here's an example.
private void goToMainActivity() {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Intent intent = new Intent(fa, Main.class);
startActivity(intent);
}
}.execute();
}
Here is my problem, when I start the Activity the Music start like I want it to, but when I leave the Activity (by pressing the back button) the Application crashes and "stopped unexpectedly" :( All I want to do is have the audio STOP and go to another activity without the unexpected stop. How can I do this?
public class Run extends Activity {
/** The OpenGL View */
private GLSurfaceView glSurface;
private MediaPlayer mPlayer;
/**
* Initiate the OpenGL View and set our own
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
//Set our own Renderer and hand the renderer this Activity Context
glSurface.setRenderer(new Lesson06(this));
//Set the GLSurface as View to this Activity
setContentView(glSurface);
new Thread(new Runnable() {
public void run() {
try{
MediaPlayer mPlayer = MediaPlayer.create(Run.this, R.drawable.theygonelovemeformyambition);
mPlayer.setLooping(true);
mPlayer.start();
while(mPlayer.isPlaying()){
android.os.SystemClock.sleep(100);
}
}catch(Exception e){
String TAG = null;
Log.d(TAG,"ERROR PLAYING");
e.printStackTrace();
}
}}).start();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mPlayer.release();
}
}
hi before you have to release media player resources. You should stop media player like below.
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
if(mPlayer.isPlaying())
mPlayer.stop();
mPlayer.release();
super.onDestroy();
}
You dont have innitialized the mPlayer
In the public void run() you are just creating a new MediaPlayer
and so when you are trying mPlayer.release(); you are reffering to the null mPlayer and so you get a nullPointerExceptionerror (i guess)