MediaPlayer Volume issue-AudioStream issue - java

I am trying to provide a custom beep sound when I get a message in my Application. This beep sound should respect the master phone notification volume level(not ringer volume). Which means if phone notification vol =3/10 , then beep intensity should be 3/10.
I am not able to achieve this,
AudioManager audioMan = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
int volume;
if (mPlayer == null) {
mPlayer = MediaPlayer.create(context, R.raw.mytone);
}
if (mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer.release();
mPlayer = MediaPlayer.create(context, R.raw.mytone);
}
volume = audioMan.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
mPlayer.setVolume(volume, volume);//this doesn't work for me, beep sound is taking media player volume by default.
mPlayer.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer player, int what, int extra) {
player.stop();
player.reset();
return true;
}
});
if (mVibrator == null)
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.cancel();
Can you please share your knowledge and give me directions. Thank you.

It looks like you are playing your sound over the music stream going by the reference to AudioManager.STREAM_MUSIC. Modifying the volume level modifies the level for everything played on that stream. This is why music/media playback is 'mucked up'.
If you want to use the ringer stream (and its volume setting) then you should be using AudioManager.STREAM_RING instead. You say you've tried this but the code snippet you've given just adjusts the volume - you've not shown how you create and configure your MediaPlayer before you ask it to play your sound.
You've got to select the appropriate stream when you set up your MediaPlayer instance. As I've successfully used different streams in the kind of scenario you are describing, this is where your problem lies. To select the audio stream over which your custom beep is played, use setAudioStream on your MediaPlayer instance like this:
// Get a reference to the MP3 file to play
AssetFileDescriptor afd = getContext().getResources().openRawResourceFd(R.raw.my_mp3);
// Create the media player
MediaPlayer mediaPlayer = new MediaPlayer();
// Give it the MP3 you want played
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
// Set the audio stream to play over
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
// Now play the sound
mediaPlayer.prepare();
mediaPlayer.start();
Its good practice to offer your users the option to choose the stream for themselves - in addition to the music and ringer streams there are alarm and notification streams, each with an independent volume level (there are others too, but these are the core ones). Have a look at the Android documentation on AudioManager here.

Related

How can I stop youtube music?

I am using AudioManager in order to make this work.
This is what I have done:
private AudioManager isPlaying = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
if(isPlaying.isMusicActive()) {
isPlaying.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
} else{
Toast.makeText(getApplicationContext() , "There is no music playing..", Toast.LENGTH_SHORT).show();
}
I want to stop the music playing from youtube or any other app. In addition, how can I pause it and resume it?
In Stop MediaPlayer when an other app play music
A person answer
AudioManager manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
if(manager.isMusicActive())
{
// do something - or don't
}

Select microphone source from headset instead of handy mic

is it possible to record audio from my Bluetooth headset instead of using the integrated android smartphone microphone?
When i am connecting my headset to my phone I can use the mic while I am phoning but in any other case it does not record anything, for example when I am trying to record audio with a recording app it uses the mic from the phone. SO is there any solution for selecting the headset mic instead or can I write an application for it?
You have to handle the following intent.
https://developer.android.com/reference/android/speech/RecognizerIntent.html#ACTION_VOICE_SEARCH_HANDS_FREE
You can use the following code to use bluetooth headset mic.
AudioManager audiomanager= (AudioManager)mContext.getSystemService(Context
.AUDIO_SERVICE);
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
mContext.registerReceiver(mBluetoothScoReceiver, intentFilter);
audiomanager.startBluetoothSco();
and listen for the broadcast receiver.
private BroadcastReceiver mBluetoothScoReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
// Start recording audio
log("audio connected");
startRecording();
} else if(state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED){
log("audio disconnected");
}
}
};
and for switching(to disconnect bluetooth headset mic) you can use this code.
mAudioManager.stopBluetoothSco();

How to fix sound?

I have been stuck on this for way too long now. In my main menu screen, I have a mute button. I want it to call a method in my background service, which mutes all of the MediaPlayer audio that would be played in the background of my game.
Here I am calling mute from my Main_Menu (x starts as 0):
if ((x%2) == 0) { //If it's even
TwentySeconds.unMute();
Toast.makeText(Main_Menu.this, "UNMUTED", Toast.LENGTH_SHORT).show();
x++;
} else { //If its odd
TwentySeconds.myMute();
Toast.makeText(Main_Menu.this, "MUTED", Toast.LENGTH_SHORT).show();
x++;
}
Here are the methods in the service which actually do the muting:
public static void myMute() {
ten.setVolume(0, 0);
three.setVolume(0, 0);
}
public static void unMute() {
ten.setVolume(1, 1);
three.setVolume(1, 1);
}
Here are the actual media players, which play at intervals:
static MediaPlayer ten;
static MediaPlayer three;
The problem is, I am getting a null pointer exception here:
TwentySeconds.myMute();
and
ten.setVolume(0, 0);
By the way, manager is instantiated like so:
AudioManager manager;
and later on:
manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Here is something that might be causing the issue:
I am getting the error whenever the audio plays (which plays fine):
QCMediaPlayer mediaplayer NOT present
E/MediaPlayer﹕ Should have subtitle controller already set
I would really appreciate any feedback (positive or negative)!
Let me know if you need any more code.
You must start your service first
In the method in Main_Menu
Intent svIntent = new Intent(this, TwentySeconds.class);
startService(svIntent);
And then you call TwentySeconds.myMute();
Remember add service to manifest file:
<service android:enabled="true" android:name=".TwentySeconds" />

No error event when WiFi connection is lost for MediaPlayer

I have registered an OnErrorListener with my MediaPlayer and to test it I simply turn off the WiFi. There is no other Internet connection available than WiFi so the playback stops, but the event handler is not fired. Isn't that supposed to happen or how would I deal with these problems?
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(uri);
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
// logging stuff
return false;
}
});
mp.prepare();
mp.start();
I think that the MediaPlayer class does not count that as an error. You could try using setOnBufferingUpdateListener. According to the documentation, this is called
when the status of a network stream's buffer has changed.

Android MediaPlayer volume is very low ( already adjusted Volume )

I m using the MediaPlayer to play one of the internal alarm ringtone.
i m using the setVolume(1.0f, 1.0f) to maximize the volume when the ringtone is played. but the ringtone doesn't play full volume ( when I compare it to playing the ringtone separately or through the built it android alarm)
here is my code
mediaPlayer.setDataSource(context, ringtoneUri);
mediaPlayer.setLooping(looping);
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.prepare();
mediaPlayer.start();
I added the following permission android.permission.MODIFY_AUDIO_SETTINGS
( not sure if this is needed )
Any Idea why the mediaPlayer still won't play the sound at maximum?
Here is the solution I found.
AudioManager amanager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
int maxVolume = amanager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
amanager.setStreamVolume(AudioManager.STREAM_ALARM, maxVolume, 0);
MediaPlayer mediaPlayer= new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); // this is important.
mediaPlayer.setDataSource(context, ringtoneUri);
mediaPlayer.setLooping(looping);
mediaPlayer.prepare();
mediaPlayer.start();
I encountered the same issue, and then noticed this this in the MediaPlayer documentation:
While in the Prepared state, properties such as audio/sound volume, screenOnWhilePlaying, looping can be adjusted by invoking the corresponding set methods.
Calling setVolume after calling prepare fixes this, so that audio is played at max volume. Actually, according to the docs I just quoted, you should call setLooping after prepare as well:
mediaPlayer.setDataSource(context, ringtoneUri);
mediaPlayer.prepare();
mediaPlayer.setLooping(looping);
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.start();
Since setAudioStreamType() is now deprecated you should use the method setAudioAttributes() instead. Below is the full example
var mediaPlayer: MediaPlayer = MediaPlayer()
fun playAudio(audioUrl: String) {
mediaPlayer.apply {
if (isPlaying) {
stop()
reset()
release()
}
}
mediaPlayer = MediaPlayer()
try {
mediaPlayer.apply {
setAudioAttributes(
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
)
setVolume(2f,2f)
setDataSource(audioUrl)
prepare()
start()
}
} catch (e: IOException) {
e.printStackTrace()
}
}

Categories