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
Related
I'm trying to stop my music when the user leaves the app or clicks the home button. My application plays music even if it is in the background. How can I stop the music if the user clicks the home button? If the user returns, the music is played again.
Here is my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.vaporv2);
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mediaPlayer.start();
}
});
//toggle off and on :
MusicButton = (ToggleButton) findViewById(R.id.toggleButton);
MusicButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (MusicButton.isChecked() && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
mediaPlayer.start();
}
}
});
In your Activity:
Check for two states:
on pause state: When you press home button
#Override
protected void onPause() {
super.onPause();
if(mediaPlayer!=null && mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
}
on resume state: When you come back to your screen
#Override
protected void onResume() {
super.onResume();
if(mediaPlayer!=null && !mediaPlayer.isPlaying()){
mediaPlayer.start();
}
}
Since you are in Activity you can override onResume and onStop methods
and then play/pause your app.
#Override
protected void onResume() {
super.onResume();
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
}
}
#Override
protected void onStop() {
super.onStop();
mediaPlayer.pause();
}
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;
}
}
});
}
}
I am creating a game, I want to play a background music for one activity only(For main menu of game), my code shown below, The problem is that the music plays more than one time, I want to play the same music also when activity Resumes.
public class Menu extends Activity {
MediaPlayer mp
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
mp = MediaPlayer.create(Menu.this, R.raw.adalante);
if(!mp.isPlaying()) {
mp.start();
}
public void play(View ButtonClicked) {
mp.stop();
mp.release();
//mp = MediaPlayer.create(Menu.this, R.raw.l);
//mp.start();
goToActivity(Game.class);
}
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
//coins
coin.setText(data.getString("coin"));
mp = MediaPlayer.create(Menu.this, R.raw.adalante);
if(!mp.isPlaying()) {
mp.start();
}
//mps.release();
}
In your onResume don't initialise MediaPlayer again and again. It creates new instance every time when you come to onResume. So add a check in onResume like this :
#Override
protected void onResume() {
super.onResume();
if (mp==null)
mp=MediaPlayer.create(MainActivity.this,R.raw.adalante);
if (!mp.isPlaying())
mp.start();
}
and additionally add this for prevention to play when activity goes to onPause
#Override
protected void onPause() {
super.onPause();
mp.pause();
}
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
This is my activity for a video player:
public class myActivity extends Activity
implements MediaPlayer.OnPreparedListener,
MediaController.MediaPlayerControl {
....
}
and in its onPause method I don't release the MediaPlayer and I just pause it:
#Override
protected void onPause() {
super.onPause();
lastPlaybackInfo.IsPlaying = mMediaPlayer.isPlaying();
mMediaPlayer.pause();
lastPlaybackInfo.SeekPosition = mMediaPlayer.getCurrentPosition();
}
and in onResume
#Override
protected void onResume() {
super.onResume();
if (mMediaPlayer != null) {
if (lastPlaybackInfo.IsPlaying) {
mMediaPlayer.start();
} else {
mMediaPlayer.seekTo(lastPlaybackInfo.SeekPosition);
}
mMediaController.show();
}
}
and the onTouchEvent:
#Override
public boolean onTouchEvent(MotionEvent event) {
mMediaController.show();
return true;
}
I have two problems:
The first problem is that the once the app is resumed, the MediaController which is tied to MediaPlayer is shown only one time (the call in onResume), and after that, the calls in onTouchEvent doesn't show MediaController.
The second one is that, if MediaPlayer was paused before app getting paused, after resuming the app, the SurfaceView tied to MediaPlayer is black and doesn't show the very last rendered frame.
In fact I found out if we run the code inside onResume with a delay to let the layout refresh itself, both of the problems would get resolved.
Here's how:
protected void onResume() {
super.onResume();
try {
if (IsMediaReady && IsSubtitleReady) {
if (mMediaPlayer != null) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (lastPlaybackInfo.IsPlaying) {
mMediaPlayer.start();
} else {
mMediaPlayer.seekTo(lastPlaybackInfo.SeekPosition);
}
mMediaController.show();
}
}, 100);
}
}
} catch (NullPointerException e) {
Log.e(TAG, "Exception in resume");
}
}