Unable to play mp3 in android pie (9) - android

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)

Related

Why Android MediaPlayer stuck in prepare() when the URL returns not found?

So this is the simple code I use to play an audio file in my app:
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
And here is the error log:
java.io.IOException: Prepare failed
at android.media.MediaPlayer._prepare(Native Method)
This error makes the app freeze for like 10 seconds and happens when the url providing the mp3 file returns 404 (not found). So how can I solve the issue?
I have used mediaPlayer.prepareAsync(), but nothing changed.
Please try the below way, the below code is in kotlin but you can use this way in java
mPlayer = MediaPlayer.create(mContext, myUri(uriAudio))
if (Build.VERSION.SDK_INT >= 21) {
val audioAttributes: AudioAttributes =
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
mPlayer!!.setAudioAttributes(audioAttributes)
} else {
mPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
}
if (mPlayer != null && !mPlayer!!.isPlaying) {
mPlayer!!.start()
}
You can try below method:
https://developer.android.com/reference/android/media/MediaPlayer#setAudioStreamType(int)
the method, setAudioStreamType, was deprecated in API level 26.
use setAudioAttributes(android.media.AudioAttributes)

MediaPlayer - Alarm is played in headphones AND on the phone

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;
}

Sound not playing in Android version greater than 4.0

I am using following code to play sound in my app. Everything worked fine before ICS. But on ICS and more recent versions no sound can be heard although there is no error appearing.
EDIT: Note, the following code is triggered by a broadcase receiver. BroadCast receiver invokes a async task. In the post process method of asycn task the following method is called.
This error happens only on specific mobile models (Eg nexus ) and on some models users are able to play sounds which comes with stock os but not their own sounds which they places in rigtones folder.
I am not able get whats the issues as it happens on specific handset
What could the error possibly be?
public static void playSound(final Context context, final int volume,
Uri uri, final int stream, int maxTime, int tickTime) {
//stopPlaying();
/*
if (stream < 0 || stream > 100) {
throw new IllegalArgumentException(
"volume must be between 0 and 100 .Current volume "
+ volume);
}*/
final AudioManager mAudioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
int deviceLocalVolume = getDeviceVolume(volume,
mAudioManager.getStreamMaxVolume(stream));
Log.d(TAG,
"device max volume = "
+ mAudioManager.getStreamMaxVolume(stream)
+ " for streamType " + stream);
Log.d(TAG, "playing sound " + uri.toString()
+ " with device local volume " + deviceLocalVolume);
final int oldVolume = mAudioManager.getStreamVolume(stream);
// set the volume to what we want it to be. In this case it's max volume
// for the alarm stream.
Log.d(Constants.APP_TAG, "setting device local volume to " + deviceLocalVolume);
mAudioManager.setStreamVolume(stream, deviceLocalVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
final MediaPlayer mediaPlayer = new MediaPlayer();
golbalMMediaPlayer = mediaPlayer;
try {
final OnPreparedListener OnPreparedListener = new OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mp) {
Log.d(TAG, "onMediaPlayercompletion listener");
mp.start();
countDownTimer.start();
}
};
mediaPlayer.setDataSource(context.getApplicationContext(), uri);
mediaPlayer.setAudioStreamType(stream);
mediaPlayer.setLooping(false);
mediaPlayer.setOnPreparedListener(OnPreparedListener);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Log.d(Constants.APP_TAG, "Entered onCompletion listener of mediaplayer");
mAudioManager.setStreamVolume(stream, oldVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
try{
if(mediaPlayer != null && mediaPlayer.isPlaying()){
mediaPlayer.release();
}
}catch(Exception ex){
Log.e(Constants.APP_TAG, "error on oncompletion listener" ,ex);
}
}
});
CountDownTimer timer = new CountDownTimer(maxTime*1000, tickTime*1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.d(TAG, "tick while playing sound ");
}
#Override
public void onFinish() {
Log.d(TAG, "timer finished");
stopPlaying();
}
};
countDownTimer = timer;
mediaPlayer.prepareAsync();
} catch (Exception e) {
Log.e(TAG, "problem while playing sound", e);
} finally {
}
}
LOGS
:07-01 00:00:00.030: D/beephourly(9500): device max volume = 7 for streamType 5
07-01 00:00:00.030: D/beephourly(9500): playing sound content://media/internal/audio/media/166 with device local volume 7
07-01 00:00:00.030: D/beephourly(9500): setting device local volume to 7
07-01 00:00:00.080: D/beephourly(9500): vibrating with pattern = [J#428bae20
07-01 00:00:00.090: D/beephourly(9500): will show normal notification
07-01 00:00:00.100: D/beephourly(9500): notification is enabled
07-01 00:00:00.100: D/usersettings(9500): hr = 0
07-01 00:00:00.110: D/beephourly(9500): onMediaPlayercompletion listener
07-01 00:00:00.451: D/beephourly(9500): tick while playing sound
07-01 00:00:20.460: D/beephourly(9500): timer finished
07-01 00:00:20.460: D/beephourly(9500): got request to stop playing
07-01 00:00:20.460: D/beephourly(9500): cancelling countdowntimer
07-01 00:00:20.460: D/beephourly(9500): releasing mediaplayer now
This question is a follow up question to question which i asked previously:
sound not playing in android > icecream sandwich
You should be requesting audio focus, even for notifications. In your case it would look something like this:
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//request a transient lock on the notification stream
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_NOTIFICATION,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// could not get audio focus.
}
I suspect there is some other app(s) running on the devices which are giving you problems which are requesting audio focus. If other apps request audio focus, and you do not, it is possible your app will not be played out to the final stream. Requesting focus yourself will ensure no other processes are interfering with your notification sound. Although this was introduced a while ago, newer versions of Android are much more sensitive to apps using this mechanism, especially from the background.
To be proper, when you're done with the notification, you can then release the focus:
audioManager.abandonAudioFocus(this);

Issue with MediaPlayer and android 4.4

I'm developing a Streaming Video App. Video start in 3-5 seconds in android 4.0-4.3 but I don't know what happen in Android 4.4+ start is more than 20 sec long. Any fix or hack?
private void playVideo(String url) {
doCleanUp();
try {
// Create a new media player and set the listeners
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setOnPreparedListener(mOnPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
mMediaPlayer.setOnCompletionListener(mOnCompletionListener);
mMediaPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener);
//mMediaPlayer.setDataSource(mVideoPath2);
//wifiLock.acquire();
mMediaPlayer.setDataSource(url);
mMediaPlayer.setDisplay(mVideoSurfaceViewHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
prepareAsync() is called
then in 2 sec onPrepare() callback
but video start in more than 20 sec in 4.4. In android 4.3 start in 3 sec...
Bug?? https://code.google.com/p/android/issues/detail?id=62304
any fix/hack?

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