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
Related
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();
}
}
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.
In My Application im using following code to play audio file
Uri data = Uri.parse("file:/" + songnameandpath);
intent.setDataAndType(data, "audio/*");
PackageManager packageManager = getActivity()
.getPackageManager();
List<ResolveInfo> activities = packageManager
.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
startActivity(intent);
so now when user clicks on back button audio get stopped what if i want to play audio even if the user presses back button on activity and moreover it has to play in background exactly how audio will in mobiles.
Sample code will helps me a lot.
Thanks in advance
Have you tried working with media player?
here is the code that worked for me, just delete the on pause/destroy methods or redefine them and you will have sound playing even when the user presses back..
public class MainActivity extends Activity {
private MediaPlayer mp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mp= MediaPlayer.create (this, R.raw.sound); // sound is for example your mp3 song
mp.start ();
}
protected void onDestroy() {
super.onDestroy();
mp.release();
}
protected void onPause() {
super.onPause();
mp.pause();
}
protected void onResume() {
super.onResume();
mp.start();
}
protected void onStart() {
super.onStart();
}
}
update
The MediaPlayer will continue playing file even after the activity is finished unless you explicitly stop it by stop function
I have a working alarm app, but wanted to add a feature where the user gets the choice between "Play alarm continuously till acknowledged" and "play alarm sound once".
I then looked at my alrm ringing code expecting to see some kind of "repeat" flag which I could optionally remove - but there was none. So how do I play the alarm sound just once?
My existing code looks like this:
private void playSound(Context context, Uri alert)
{
mMediaPlayer = new MediaPlayer();
try
{
mMediaPlayer.setDataSource(context, alert);
final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0)
{
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
}
catch (IOException e)
{
// oops!
}
}
Actually in each alarm sound there is a FLAG named ANDROID_LOOP which force your sound to loop. Unfortunatly you can't change that flag even using MediaPlayer.setLooping(false).
But you still can manually stop your player after a certain time. For example getDuration will give you the length of your sound.
int duration = mMediaPlayer.getDuration();
Runnable stopSoundRunnable = new Runnable() {
#Override
public void run() {
mMediaPlayer.stop();
}
};
mSoundHanlder.postDelayed(stopSoundRunnable, duration);
I have a receiver that listens for headset MEDIA_PAUSE_PLAY and for AUDIO_BECOMING_NOISY they work fine if only one is called. But some Ford Sync systems will send a play/pause command when turning off the car. So this then has 2 receivers active at the same time and it causes a force close because I am stopping the media player in either situation. I have tried using a boolean but from what I have read the on receive gets killed after each event so the boolean value never gets used. So how can I ignore the audio becoming noisy if the media play pause is received at the same time? Thanks in advance.
Here is my code:
package com.joebutt.mouseworldradio;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.view.KeyEvent;
public class RemoteControlReceiver extends BroadcastReceiver
{
//I created stopCounter to try and keep this from running more than 1 time
int stopCounter = 0;
//I created mediaAction to try and keep both receivers from activating
boolean mediaAction = false;
#Override
public void onReceive(Context context, Intent intent)
{
//boolean mediaAction = false;
//int stopCounter = 0;
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()))
{
mediaAction = true;
//stopCounter = 1;
if (stopCounter < 1)
{
//mediaAction = true; force closes here to
KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE == event.getKeyCode())
{
stopCounter = 1;
//mediaAction only works here if you hit the stop button 1 time, then it will work the next time you shut the car off
mediaAction = true;
//stop and release the media player
if (Play.mp.isPlaying())
{
Play playService = new Play();
playService.stopPlaying();
//stop the play service
Intent stopPlayingService = new Intent(context, Play.class);
context.stopService(stopPlayingService);
//switch back to the main screen
Intent showMain = new Intent(context, MouseWorldRadioActivity.class);
showMain.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(showMain);
}
}
}
}
else if (!mediaAction)
{
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction()))
{
if (Play.mp.isPlaying())
{
//stop and release the mediaplayer
Play playService = new Play();
playService.stopPlaying();
//}
//stop the play service
Intent stopPlayingService = new Intent(context, Play.class);
context.stopService(stopPlayingService);
//switch back to the main screen
Intent showMain = new Intent(context, MouseWorldRadioActivity.class);
showMain.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(showMain);
}
}
}
}
}
Here is my method to stop the playback:
public void stopPlaying()
{
if (mp.isPlaying())
{
//stop playback and release everything
mp.setOnBufferingUpdateListener(null);
mp.setOnErrorListener(null);
mp.stop();
mp.release();
mp = null;
}
It should be okay to have two receivers active at the same time. If the issue is that you are trying to stop the media player when it is already stopped try this in your receiver:
if (mp.isPlaying()) {
mp.stop();
}
That way you only stop the media player if it is playing. If that's not the case, can you post code so we can see exactly what you're trying.
To solve the problem I checked to see if the media player was null for the audio becoming noisy listener. This prevented it from trying to stop a media player that no longer existed. Now it works great with my sync system.