I am creating a alarm kind of application.When I open a particular activity, I want to play a custom sound with alarm volume level of device.
If device's media volume is off and alarm volume is on then my custom sound should play.
What have I already tried:
private void playAlarmSound(String fileName) {
MediaPlayer p = new MediaPlayer();
AudioManager audioManager= (AudioManager) getSystemService(AUDIO_SERVICE);
try {
AssetFileDescriptor afd = this.getAssets().openFd(fileName);
int volumeLevel=audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
p.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
p.setVolume(volumeLevel,volumeLevel);
afd.close();
p.prepare();
} catch (Exception e) {
e.printStackTrace();
}
p.start();
}
But by this when media volume is on it is playing sound but when media volume is off it is not playing the sound.
You are reading the alarm volume level but this doesn't mean that the audio will be played through that stream.
You need to build and set the AudioAttributes on the MediaPlayer, indicating USAGE_ALARM.
In other words:
p.setAudioAttributes(
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
);
Related
I am working on an Audio calling app and trying to play .mp3 file stored in raw folder.
I wanted this this file to be played as an Ringtone
For this I used mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
When I use this stream the .mp3 is not played (or may be playing I am not able to hear the sound )
If I don't specify any AudioStreamType , then the file is played as an MUSIC stream , which I don't want
Note: Volume of every type (Ringtone,Notification,Call,Music) is set to full in my device
My code
public MediaPlayer playRingtone(int fileName, boolean loopRingtone) {
mediaPlayer = MediaPlayer.create(mContext, fileName);
if (android.os.Build.VERSION.SDK_INT >= 21) {
AudioAttributes.Builder b = new AudioAttributes.Builder();
b.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
b.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN);
mediaPlayer.setAudioAttributes(b.build());
} else {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
}
mediaPlayer.setLooping(loopRingtone);
mediaPlayer.start();
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnCompletionListener(this);
return mediaPlayer;
}
I am trying to find out if my device is recording audio correctly (Volume of recorded audio is not too low and actually the recorded file has sound). The way I tried doing it is:
start recording --> play sound --> stop recording --> get file recorded max volume
The code I used to record sound:
public void playSound() {
File myDataPath = new File(getActivity().getFilesDir().getAbsolutePath()
+ File.separator + ".CheckAudio");
if (!myDataPath.exists())
myDataPath.mkdirs();
recordFile = myDataPath + File.separator + "Recording_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()) + ".mp3";
am.setStreamVolume(AudioManager.STREAM_RING, am.getStreamMaxVolume(AudioManager.STREAM_RING), 0);
am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION), 0);
Uri defaultRingtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
try {
md = new MediaRecorder();
md.setAudioSource(MediaRecorder.AudioSource.MIC);
md.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
md.setOutputFile(recordFile);
md.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
md.prepare();
md.start();
} catch (IllegalStateException | IOException e) {
recording = false;
removeItem("Unable to record audio, please try again."); // (Show toast)
return;
}
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(getActivity(), defaultRingtoneUri);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mediaPlayer.prepare();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
md.stop();
md.release();
mediaPlayer.release();
mediaPlayer = null;
// get recordfile volume
}
});
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
removeItem("Unable to play audio");
sound = false;
}
}
However, I can't find out how to analyze the mp3 file created and check if it is not empty (from sound), is there a library or another way?
I hope you guys understood what I am trying to achieve as my English is pretty bad, Thanks.
EDIT:(Some more explaination)
If you play sound (ringtone or something) while recording sound from microphone, the decibels recorded should be around 90 decibels. meaning the sound playing working and also the microphone, but if the decibels recorded around 30 means only microphone is working, and playing sound not, if the decibels are around zero then the microphone is not working.
You can use a visualiser to visualise real time if recording sound is getting too low or too loud.
I have build a project which visualise recording sound strength via bar graph . Higher the bar louder the recorded sound lower the bar low decibels .
This project also have inapp player which allow user to play all his recordings. The inbuilt player also visualise playback sound data.
I am suggesting this because I thought this is what you are trying to achieve in
start recording --> play sound --> stop recording --> get file recorded max volume.
Instead of getting max volume each time you can rely on visualiser to keep an eye on recorder if recording file is getting recorded above acceptable decibals.
You can find source code on github
https://github.com/hiteshsahu/Android-Audio-Recorder-Visualization-Master
I am playing voicemail recordings in my app. The way I currently have it set up, it plays the voicemail through the speakerphone. What is the best way to be able to toggle between speakerphone and earpiece. Here is how I set up my MediaPlayer:
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(url);
} catch (Exception e) {
e.printStackTrace();
return;
}
mediaPlayer.prepareAsync();
I am building for 4.1 plus.
You need to set audio manager mode too. and then using audiomgr.setSpeakerphoneOn(false) api you can toggle.
audiomgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audiomgr.setMode(AudioManager.STREAM_MUSIC);
audiomgr.setSpeakerphoneOn(false);
I want to play a sound automatically when I call to somebody
but I don't know the way for this.
It is possible because we have some application that play some noise (traffic and ...) to background of call but I could not find a code or something for this
example of sound play in background
this is a code to play music
MediaPlayer player;
AssetFileDescriptor afd;
try {
// Read the music file from the asset folder
afd = getAssets().openFd(“home.mp3″);
// Creation of new media player;
player = new MediaPlayer();
// Set the player music source.
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),afd.getLength());
// Set the looping and play the music.
player.setLooping(true);
player.prepare();
player.start();
} catch (IOException e) {
e.printStackTrace();
}
but can we use this during call?
So on my 2.3 devices, I can play a sound with SoundPool or MediaPlayer at full volume, even if the device volume is set to 0/mute. It was my understanding that you had to manually get the device level and set it when you played back a sound.
This is how I want the behavior to work.
However, I now notice on my 4.0 device, that the sounds are automatically played at the device's set level, which I do not want!
Is this a difference between versions of the OS? If so, is there a way to ignore the devices volume? So even if it is muted, I can play a sound and have it be heard?
I can't go into why I need this feature, but I really really do.
Thanks!
I had a similar need for an alarm clock application. Here is the relevant code with comments regarding the volume.
This works on my HTC Rezound Android Version 4.0.3 when the sound profile is set to silent, when the alarm stream volume is manually set to zero and when the ringtone volume is set to zero.
Context context;
MediaPlayer mp;
AudioManager mAudioManager;
int userVolume;
public AlarmController(Context c) { // constructor for my alarm controller class
this.context = c;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
//remeber what the user's volume was set to before we change it.
userVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
mp = new MediaPlayer();
}
public void playSound(String soundURI){
Uri alarmSound = null;
Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
try{
alarmSound = Uri.parse(soundURI);
}catch(Exception e){
alarmSound = ringtoneUri;
}
finally{
if(alarmSound == null){
alarmSound = ringtoneUri;
}
}
try {
if(!mp.isPlaying()){
mp.setDataSource(context, alarmSound);
mp.setAudioStreamType(AudioManager.STREAM_ALARM);
mp.setLooping(true);
mp.prepare();
mp.start();
}
} catch (IOException e) {
Toast.makeText(context, "Your alarm sound was unavailable.", Toast.LENGTH_LONG).show();
}
// set the volume to what we want it to be. In this case it's max volume for the alarm stream.
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM), AudioManager.FLAG_PLAY_SOUND);
}
public void stopSound(){
// reset the volume to what it was before we changed it.
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, userVolume, AudioManager.FLAG_PLAY_SOUND);
mp.stop();
mp.reset();
}
public void releasePlayer(){
mp.release();
}
An easy and alternative way for playing music from raw folder;
try {
String uri = "android.resource://" + getPackageName() + "/" + R.raw.beep;
//Strign uri = "http://bla-bla-bla.com/bla-bla.wav"
Uri notification = Uri.parse(uri);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}