I'm developing an Android App in Android Studio and in that a sound has to play on the WebView. But when I close the app, it automatically stops playing the audio. Now I want to know how do I make the audio to play in the background even if I close the app. (Kindly provide the code, I'm new to android development.) Thanks in advance.
I am sorry, I think it's impossible.
To play a sound in background, you need to play the audio in Service.
It's only one way to play background sound.
I will show a code for that:
public class serv extends Service{
MediaPlayer mp;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onCreate()
{
mp = MediaPlayer.create(this, R.raw.b);
mp.setLooping(false);
}
public void onDestroy()
{
mp.stop();
}
public void onStart(Intent intent,int startid){
Log.d(tag, "On start");
mp.start();
}
}
Related
I am using a Service class to play music in the background. While I am displaying the notification bar on top, there is issue in my app. When I kill the app, the music stops for about 1 second and then it starts again. I can't figure out what's the issue.
I was following this tutorial.
public class MyMusicService extends Service {
MediaPlayer mediaPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public MyMusicService() {
super();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mediaPlayer!= null)
{
mediaPlayer.release();
}
mediaPlayer =MediaPlayer.create(this,R.raw.song);
mediaPlayer.setLooping(true);
mediaPlayer.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
}
Use onTaskRemoved on your main activity and release your mediaplayer on this event.
That tutorial shows you how to build a BACKGROUND service, which can get killed by the system. To play music you should use a FOREGROUND service.
https://developer.android.com/guide/components/services.html#Foreground
According to: https://developer.android.com/reference/android/app/Service.html
Change
START_STICKY
to
START_NOT_STICKY
EDIT:
The issue with music stopping for a while is connected with the fact that you run app and service in the same process. And 'killing app' means stopping the whole process bound to it. What you need to do is to run your service in seperate process:
Start a service in a separate process android
I am using a Service class to play music in the background. While I am displaying the notification bar on top, there is issue in my app. When I kill the app, the music stops for about 1 second and then it starts again. I can't figure out what's the issue.
I was following this tutorial.
public class MyMusicService extends Service {
MediaPlayer mediaPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public MyMusicService() {
super();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mediaPlayer!= null)
{
mediaPlayer.release();
}
mediaPlayer =MediaPlayer.create(this,R.raw.song);
mediaPlayer.setLooping(true);
mediaPlayer.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
}
Use onTaskRemoved on your main activity and release your mediaplayer on this event.
That tutorial shows you how to build a BACKGROUND service, which can get killed by the system. To play music you should use a FOREGROUND service.
https://developer.android.com/guide/components/services.html#Foreground
According to: https://developer.android.com/reference/android/app/Service.html
Change
START_STICKY
to
START_NOT_STICKY
EDIT:
The issue with music stopping for a while is connected with the fact that you run app and service in the same process. And 'killing app' means stopping the whole process bound to it. What you need to do is to run your service in seperate process:
Start a service in a separate process android
I have a MediaPlayerService, currently started when the Play/Pause Button on a ListView item is clicked. See code below (CustomListAdapter):
Intent intent = new Intent(v.getContext(),MediaPlayerService.class);
intent.putExtra("StreamLink",audio);
activity.startService(intent);
When this service is started by the code above I want to create a Notification with a Play/Stop button. The user should be able to get out of the app, be able to stop Media Playback e.g. player.stop() and start player.start(). Also when the Notification is clicked it should return the user to the MainActivity.
The code for my MediaPlayerService.java:
public class MediaPlayerService extends Service implements MediaPlayer.OnPreparedListener {
MediaPlayer mMediaPlayer = null;
public String audioStreamLink;
public int onStartCommand(Intent intent, int flags, int startId) {
// Get the Audio Streaming Link from the parsed JSON in the Main Activity
audioStreamLink = intent.getStringExtra("StreamLink");
// Instantiate MediaPlayer, set the Audio Type and acquire a wakelock, set the Media Player Data Source and Prepare.
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mMediaPlayer.setDataSource(audioStreamLink);
} catch (IOException e) {
e.printStackTrace();
}
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
/** Called when MediaPlayer is ready */
#Override
public void onPrepared(MediaPlayer player) {
player.start();
}
#Override
public void onDestroy() {
mMediaPlayer.stop();
mMediaPlayer.reset();
if (mMediaPlayer != null) mMediaPlayer.release();
}
}
The process of getting a notification is completely documented down there in the documents, for example, see this.
To help you go through all this huge documentation these are the points :
You need to create the custom notification using a NotificationCompat.Builder
A typical music player service would start the notification using startForeground()
To add clickable buttons to the notification use addAction() when building the notifications.
Actions in Notifications are defined by PendingIntent, its a kind of normal Intent when it comes to responding to it.
When a button on the notification is clicked, the onStartCommand() is triggered with the intent you specified for that button (if you configure the intent correctly).
Each button's intent should have a different action so that you can identify the intent when it is received.
Inside the onStartCommand() you can play/pause and do other operations based on this intent's action.
Some reference I would suggest you to read :
https://developer.android.com/guide/topics/ui/notifiers/notifications.html
https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Updating
https://developer.android.com/reference/android/app/Service.html#startForeground(int,android.app.Notification)
Things would have been a bit different if you were using a MediaSession to play the media.
I am working on a music player
The logic is like this:
First, I click on the play button , if there is music playing, stop the service , otherwise , start it.
Play / Pause Button:
playM.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AudioManager manager = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
if (!manager.isMusicActive()) {
playM.setText("Pause");
Intent svc=new Intent(getContext(), Music.class);
svc.putExtra("uri", tt1.getText().toString());
getContext().startService(svc);
} else {
playM.setText("Play");
//if (mPlayer != null && mPlayer.isPlaying()) {
Intent svc=new Intent(getContext(), Music.class);
getContext().stopService(svc);
//}
}
}
});
Service:
public int onStartCommand(Intent intent, int flags, int startId) {
path = (String) intent.getExtras().get("uri");
Uri uriMusic = Uri.parse(path);
player = MediaPlayer.create(this, uriMusic);
player.start();
player.setLooping(true); // Set looping
return 1;
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
The problem is, if the music is playing by another apps, my music player will crash. But I can not find any way to track the service status. For example, if I play the music, close the app , the music is still playing , but when I open the app again , how to know the specific service (play music which is fire by my app only, in this case) is running? Thanks
Please take a look at my simple three-methods Service class that streams audio and play it directly.
public class StreamService extends Service {
private static final String TAG = "MyService";
String url;
MediaPlayer mp;
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
mp.stop();
}
#Override
public int onStartCommand(Intent intent, int flags, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
url = intent.getExtras().getString("url");
try {
mp.setDataSource(url);
mp.prepare();
mp.start();
} catch(Exception e){}
return START_STICKY;
}
}
In my activity, I have two buttons to play/stop the media file:
The playButton execute this:
Intent i = new Intent(this, StreamService.class);
i.putExtra("my_mp3_url_string");
startService(i);
The stopButton execute this:
stopService(new Intent(this, StreamService.class));
Now, I have some questions:
how I can implement the pauseButton? I want to pause the media running in the Service
Does my way of playing/stopping the media/Service correct ? Is there any better way?
How I can (periodically) update my Activity's UI from my Service? do I need to add something?
I would recommend not using the lifetime of the Service as a way to start and stop playback. Using that approach will mean that every time you want to start a new stream, the code will be slowed down even more by having to bring up a new Service. You can save some time by just having the same Service play everything. Though that doesn't mean it should remain running all the time.
To accomplish that (and to be able to pause), you'll need to bind to the Service after it is started. With the bound Service, you'll be able to make calls to it - such as pause, play, stop, etc.
Here are some links that should help you with what you're looking for:
Using a Service with MediaPlayer
Binding to a Service