MediaPlayer - Alarm is played in headphones AND on the phone - android

I create a MediaPlayer like in the appended code. Everything works fine, but I've one problem: whenever an alarm is played and I'm connected to headphones, the sound is played on the phone and in the headphones. I would like the phone to be quiet in such a situation.
Actually, if I use the same function to create another music player to play music and set the stream type to AudioManager.STREAM_MUSIC, everything works fine.
I'm getting this behaviour on an android 4.4.4 phone and I know, that this code worked as expected on my old phone... With android 4.3 I think...
int streamVolume = ((AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).getStreamVolume(AudioManager.STREAM_ALARM);
if (streamVolume != 0)
{
mAlarmPlayer = createMediaPlayerIfNeeded(mAlarmPlayer, true, true, false);
try
{
mAlarmPlayer.setDataSource(this, Uri.parse(sound));
mAlarmPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mAlarmPlayer.setVolume(streamVolume, streamVolume);
mAlarmPlayer.prepareAsync();
}
catch (IOException e)
{
Log.e("MusicService", "IOException playing alarm: " + e.getMessage());
e.printStackTrace();
}
}
And here is the create function:
private MediaPlayer createMediaPlayerIfNeeded(MediaPlayer player, boolean setListenerOnPrepared, boolean setListenerOnCompletion, boolean setListenerOnError)
{
if (player == null)
{
player = new MediaPlayer();
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
if (setListenerOnPrepared)
player.setOnPreparedListener(this);
if (setListenerOnCompletion)
player.setOnCompletionListener(this);
if (setListenerOnError)
player.setOnErrorListener(this);
}
else
player.reset();
return player;
}

Related

Android MediaPlayer Races Through First Song

I have a list of song objects that I want to iterate through using a MediaPlayer. It works, but the first time I launch the app, it races through the first song (sometimes several seconds, sometimes the whole song). If I completely close and reopen the app, it is fine in subsequent runs. Why is it doing this, and how can I avoid it?
My SoundPlayerMedia class is:
private MediaPlayer _soundPlayer;
public SoundPlayerMedia(Context applicationContext) {
super();
_soundPlayer = MediaPlayer.create(applicationContext, R.raw.ringtone_cesium);
}
private void initializeMedia(Context context, int soundID, boolean startPlaying) {
AssetFileDescriptor afd = context.getResources().openRawResourceFd(soundID);
try {
if (_soundPlayer == null)
return;
_soundPlayer.reset();
_soundPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
_soundPlayer.setVolume(1f, 1f); // Forces MAX volume
_soundPlayer.prepare();
if (startPlaying)
_soundPlayer.start();
afd.close();
} catch (Exception e) {
Log.e("DEBUG", "Unable to switch sound due to exception: " + e.getMessage(), e);
}
}
I use this in a fragment. In the onViewCreated, I have:
_fSoundPlayer = new SoundPlayerMedia(getContext().getApplicationContext());
_fSoundPlayer.setLooping(false);
_soundPlayer.initializeSound(getContext(), currSongId, startPlaying);

Unable to play mp3 in android pie (9)

Below code is working till Oreo but same code is not working in android pie. Please check my code.
int audioFile = R.raw.ring;
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(this,
Uri.parse("android.resource://com.blh.pickupfresh.resturentapp/" + audioFile));
final AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_RING,audioManager.getStreamMaxVolume(AudioManager.STREAM_RING),0);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
mMediaPlayer.setLooping(true);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
Try this code
int audioFile = R.raw.ring;
if(mMediaPlayer == null)
mMediaPlayer = new MediaPlayer();
try {
final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mMediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.build());
} else {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
mMediaPlayer.setLooping(true);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mMediaPlayer.setDataSource(this, Uri.parse("android.resource://com.blh.pickupfresh.resturentapp/" + audioFile));
mMediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG,"ERROR=" + e.getMessage());
}
Here I have used AudioManager.STREAM_MUSIC and also increased volume for the same stream. It will play sound even in Silent mode OR DND.
UPDATE: For Android 9 in some device mMediaPlayer.prepare() takes seconds, so we should use async method with callback and its working.
In android (at least oreo + pie), When Silent mode is ON OR DND mode is ON we can not set AudioManager.STREAM_RING to NORMAL because it will throw an Exception
java.lang.SecurityException: Not allowed to change Do Not Disturb state.
See this for further details In Android 7 (API level 24) my app is not allowed to mute phone (set ringer mode to silent)

How do I play a HTTPS audio stream in MediaPlayer on Android[Nexus 5,7]

Our APP has to stream music from network source. My question is why the mediaplayer play well when I play music using http stream, but I always got ERROR(1,-1004) when I use https stream source to play in some devices. **Important:**It only got this ERROR(1,-1004) in some devices, such as Nexus5, Nexus7 and Asus Fonepad 7.
Here is a snippet :
String url ="http://10.0.0.45/O0$1$8I87308.mp3";
MediaPlayer myMediaPlayer = new MediaPlayer();
myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
myMediaPlayer.setDataSource(url);
myMediaPlayer.prepareAsync(); // might take long! (for buffering, etc)
} catch (IOException e) {
Toast.makeText(this, "mp3 not found", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
//mp3 will be started after completion of preparing...
myMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
player.start();
System.out.println("onPrepared");
}
});

How do I get my Media Player to double buffer?

My media player is in a service object of it's own. Here's the create code.
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
player = new MediaPlayer();
try {
player.setDataSource(path);
player.prepare();
} catch (Exception e) {
}
player.setLooping(false); // Set looping
}
It is streaming from online. However, it's pretty choppy 3 minutes later. I want to double buffer this to help remove that. Any ideas on how I should do this?
Have you looked at the android Double Buffer class?

Problems with MediaPlayer, raw resources, stop and start

I'm new to Android development and I have a question/problem.
I'm playing around with the MediaPlayer class to reproduce some sounds/music. I am playing raw resources (res/raw) and it looks kind of easy.
To play a raw resource, the MediaPlayer has to be initialized like this:
MediaPlayer mp = MediaPlayer.create(appContext, R.raw.song);
mp.start();
Until here there is no problem. The sound is played, and everything works fine. My problem appears when I want to add more options to my application. Specifically when I add the "Stop" button/option.
Basically, what I want to do is...when I press "Stop", the music stops. And when I press "Start", the song/sound starts over. (pretty basic!)
To stop the media player, you only have to call stop(). But to play the sound again, the media player has to be reseted and prepared.
mp.reset();
mp.setDataSource(params);
mp.prepare();
The problem is that the method setDataSource() only accepts as params a file path, Content Provider URI, streaming media URL path, or File Descriptor.
So, since this method doesn't accept a resource identifier, I don't know how to set the data source in order to call prepare(). In addition, I don't understand why you can't use a Resouce identifier to set the data source, but you can use a resource identifier when initializing the MediaPlayer.
I guess I'm missing something. I wonder if I am mixing concepts, and the method stop() doesn't have to be called in the "Stop" button. Any help?
Thanks in advance!!!
Here is what I did to load multiple resources with a single MediaPlayer:
/**
* Play a sample with the Android MediaPLayer.
*
* #param resid Resource ID if the sample to play.
*/
private void playSample(int resid)
{
AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
try
{
mediaPlayer.reset();
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
mediaPlayer.prepare();
mediaPlayer.start();
afd.close();
}
catch (IllegalArgumentException e)
{
Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
}
catch (IllegalStateException e)
{
Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
}
catch (IOException e)
{
Log.e(TAG, "Unable to play audio queue do to exception: " + e.getMessage(), e);
}
mediaPlay is a member variable that get created and released at other points in the class. This may not be the best way (I am new to Android myself), but it seems to work. Just note that the code will probably fall trough to the bottom of the method before the mediaPlayer is done playing. If you need to play a series of resources, you will still need to handle this case.
this is how MediaPlayer.create method works to open a raw file:
public static MediaPlayer create(Context context, int resid) {
try {
AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
if (afd == null) return null;
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
return mp;
} catch (IOException ex) {
Log.d(TAG, "create failed:", ex);
// fall through
} catch (IllegalArgumentException ex) {
Log.d(TAG, "create failed:", ex);
// fall through
} catch (SecurityException ex) {
Log.d(TAG, "create failed:", ex);
// fall through
}
return null;
}
Or, you could access the resource in this way:
mediaPlayer.setDataSource(context, Uri.parse("android.resource://com.package.name/raw/song"));
where com.package.name is the name of your application package
You can use
mp.pause();
mp.seekTo(0);
to stop music player.
Finally, the way it works for me:
public class MainStart extends Activity {
ImageButton buttonImage;
MediaPlayer mp;
Boolean playing = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonImage = (ImageButton)findViewById(R.id.ButtonID);
buttonImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(playing){
mp.stop();
playing = false;
}else{
mp = MediaPlayer.create(getApplicationContext(), R.raw.sound_u_want);
mp.start();
playing = true;
}
}
});
}
}
MR. Rectangle, this message maybe too late for it, but I proudly write these codes to your idea: I have mp for mediaplayer and sescal9 is a button.
....
if(btnClicked.getId() == sescal9_ornek_muzik.getId())
{
mp.start();
mp.seekTo(380);
mp2.start();
mp2.seekTo(360);
mp3.start();
mp3.seekTo(340);
...
}
Recheck your passing parameters not null
Possible reasons
Context may be null
Your media file may be corrupted

Categories

Resources