I am trying to build a custom type of alarm clock for Android, and I have set up a settings page to allow the users to choose which alarm sound they would like to use. After they select it, it is placed into SharedPreferences, easy enough.
The problem I am having is how to play the alarm they have chosen, while using the RingtoneManager.TYPE_ALARM, so that the volume is based off the systems alarm sound instead of the systems notification volume.
I have tried multiple ways to even get it to use the Alarm volume, but nothing seems to be doing the trick.
1.
Uri currentRingtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
currentRingtone = RingtoneManager.getRingtone(context, currentRingtoneUri);
currentRingtone.play();
2.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString("alarm_new_alarm_sound", null);
if (syncConnPref != null) {
RingtoneManager.getRingtone(this, Uri.parse(syncConnPref)).play();
}
I cannot seem to find any other direct ways of playing the actual alarm volume sound. Everything online looks at just playing ringtones.
I would really appreciate if anyone had any insight on using the alarm volume.
Somewhat old thread, but maybe this will help someone in the future.
I am currently working on an alarm clock myself and I'm doing this:
int audioFile = prefs.getInt("audioFile", R.raw.yourFile);
MediaPlayer mp = new MediaPlayer();
try {
mp.reset();
mp.setDataSource(PlayerActivity.this,
Uri.parse("android.resource://your.package.here/" + audioFile));
mp.setAudioStreamType(STREAM_ALARM);
mp.setLooping(true);
mp.prepare();
mp.start();
}
catch (...) {
...
}
It's working fine for me.
Related
I'm developing a Voip-Application and i have an edge case where i want to play two raw files at the same time.
When i have an incoming call from my application i am creating a new Mediaplayer and play a custom ringtone. When i get shortly after also an incoming GSM-call i create a new mediaplayer and play a knocking sound to give the user feedback that there is also a GSM-Call incoming. At the same time i want the custom ringtone to continue playing.
private fun setAudioAttributesForFile(audioUsage: Int): AudioAttributes {
return AudioAttributes.Builder()
.setUsage(audioUsage)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
}
private fun startRingtone(fileToPlay: Int): MediaPlayer {
return MediaPlayer().apply {
reset()
if (fileToPlay == R.raw.ring {
setAudioAttributes(setAudioAttributesForFile(AudioAttributes.USAGE_NOTIFICATION_RINGTONE))
} else {
setAudioAttributes(setAudioAttributesForFile(AudioAttributes.USAGE_MEDIA))
}
isLooping = true
Main.get().resources.openRawResourceFd(fileToPlay).use {
setDataSource(
it.fileDescriptor,
it.startOffset,
it.length
)
}
setOnPreparedListener { start() }
prepareAsync()
}
}
The problem that i have with this code is that as soon as the knocking sound is playing the ringtone gets muted by the system and as soon as the knocking sound is stopping the ringtone continues.
What i also tried:
Using only
AudioAttributes.USAGE_NOTIFICATION_RINGTONE. As soon as the knocking sound starts to play both mediaPlayers are getting muted.
If i leave the setAudioAttributes() call away and replace these four lines to
if (fileToPlay == R.raw.ring) {
setAudioAttributesForFile(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
} else {
setAudioAttributesForFile(AudioAttributes.USAGE_MEDIA)
}
then i can play those two files at the same time. The problem then is that the ringtone file is not shown as a ringtone instead it is only shown as a media file. So when i increase and decrease the volume of the ringtone the flag does not show that it is a ringtone.
Is there a way to play one sound as a Ringtone and another sound over it as a normal Media Sound?
Thanks in advance. Any help is appreciated.
Use sound pool if you want to play both sounds at the same time.
I'm developing a game. I need a button to turn on and off game sounds.
In my app, I play background music which I want to be muted upon clicking a button. Here's my code:
AudioManager aManager = (AudioManager)getSystemService(AUDIO_SERVICE);
if (aManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
aManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
} else {
aManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
When I debug, the conditions are right but nothing happens! The sound is never turned off!
Check for method "isVolumeFixed()". If true, your device can't have it's sound changed. Some devices have a policy about that.
I'm developing a spam call filtering app and I'm trying to silence ringer for incoming (spam) call. The problem is none of AudioManager.setStreamMute nor AudioManager.setRingerMode is working in Lollipop. Here is my code snippet:
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamMute(AudioManager.STREAM_RING, false);
Log.i(TAG, "unmute");
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamMute(AudioManager.STREAM_RING, true);
Log.i(TAG, "mute");
}
}
When there's an incoming call, the mute part always gets executed but it sometimes succeeds and sometimes fails to mute the ringer. I can't find any rule. And audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT) doesn't work either. This seems work fine when tested on emulators < 5, so I guess it's somehow related to Lollipop not having silent mode but interruptions filter. Commercial spam call filters are woking fine, so can somebody let me know how I could silence incoming calls with Lollipop?
I've got the same issue for android 5. AudioManager.setStreamMute with the value false to unmute is never working.
I tried AudioManager.setStreamSolo and it worked for me.
//to mute ringtone
Global.app().getAudioManager().setStreamSolo(AudioManager.STREAM_MUSIC, true);
//unmute ringtone
Global.app().getAudioManager().setStreamSolo(AudioManager.STREAM_MUSIC, false);
It mutes all other streams except one you want to play. In may case I needed to play my own audio instead of ringtone.
But you can try to play a silence audio to hack if you need absolute silence.
I have some code that plays a small notification beep from an mp3 (included in res/raw) that works fine on regular Android devices (various 2.2 and up), which I am trying to also use on Google TV and it doesn't seem to do anything, no errors, just no sound.
What could I be doing wrong (this has to be something simple that I am missing?).
Here is the basic code I'm using:
private void beep() {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(null, AudioManager.STREAM_NOTIFICATION, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
try {
Log.d(App.LOG_TAG, "playing the damn beep ****************");
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.beep);
// tried with and without volume
///mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.setLooping(false);
mediaPlayer.start();
} catch (Exception e) {
Log.e("beep", "error: " + e.getMessage(), e);
}
} else {
Log.d(App.LOG_TAG, "could not gain audio focus");
}
}
(NOTE: In real life I don't recreate the MediaPlayer and AudioManager every time, but I tried just putting everything in one method for test purposes. This works fine on the regular Android emulator, and on regular Android [phone] devices, but plays no sound on GTV emulator or Logitech Revue -- even though it does get into the MediaPlayer block fine and logs that it's playing the beep.)
Did you enable Notification sound in Settings->Picture & sound ->Notification sounds->Sounds->Default ?
I had the same problem. For whatever reason, it looks like the files need to be in ogg format. I tried .mp3, and a few versions of .wav. Even the GTV dev docs (https://developers.google.com/tv/android/docs/gtv_media_formats#StandardFormats) say .mp3 is okay.
My HiSense Pulse Google TV only plays the files if they are .ogg files.
This online converter seems to work: http://media.io/
I have an Android application that makes use of TTS (Text to speech) API. Everything is working perfectly, but now i want to fade in/out or even stop music (in case user is playing music with prebuilt Music Player), when application speaks a text. Right now, i think both music and TTS messages are played on the same stream (MUSIC), and it can be difficult to understand the voice messages.
I've tried to play the text on a different stream, like AudioManager.STREAM_NOTIFICATIONS. It does stop the music, but doesn't come back when the text is spoken, so i didn't achieve the goal. Haven't found anything yet, so i hope someone can help here. Thanks!
I finally got something that is working. Not perfect though. A quite dirty trick. Just in case it can help to someone:
This is fixed on API 8 with requestAudioFocus and abandomAudioFocus methods of AudioManager.
But for former versions, you can try this. Play TTS through a different stream channel, let's say STREAM_NOTIFICATIONS. Then you just need to return audio focus to STREAM_MUSIC. How can you achieve that?. Sending a silence string (" ") to TTS but this time through STREAM_MUSIC. The effect will be: music is stopped, your TTS message gets spoken, and finally your music is back after the voice alert. Not nice or something to feel proud of, but... if someone knows of a different way, i will appreciate it
Here is a way of doing this in Dec-2021
TexToSpeech needs to be initialized and assigned to tts before calling this method
Method 1 (Recommended):
private void speak(String textToSay) {
AudioAttributes mPlaybackAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANT)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
//add this below flag if you need the TTS to speak in a louder volume or TTS volume be heard for sure at any cost
//.setFlags(FLAG_AUDIBILITY_ENFORCED)
.build();
tts.setAudioAttributes(mPlaybackAttributes);
AudioFocusRequest mFocusRequest =
new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)
.setAudioAttributes(mPlaybackAttributes)
.setAcceptsDelayedFocusGain(false)
.setWillPauseWhenDucked(false)
.build();
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(mFocusRequest);
tts.speak(textToSay, TextToSpeech.QUEUE_FLUSH, null, textToSay);
Handler ttsSpeak = new Handler();
Runnable checkTTSRunning = new Runnable() {
#Override
public void run() {
if (tts.isSpeaking()) {
ttsSpeak.postDelayed(this, 1000);
} else am.abandonAudioFocusRequest(mFocusRequest);
}
};
ttsSpeak.postDelayed(checkTTSRunning, 3000);
}
Method 2: Use this only if you need the TTS to speak in a louder volume and/or TTS volume needs to be heard for sure at any cost
private void speak(String textToSay) {
AudioAttributes mPlaybackAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANT)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setFlags(FLAG_AUDIBILITY_ENFORCED) //VERY IMPORTANT
.build();
tts.setAudioAttributes(mPlaybackAttributes);
tts.speak(textToSay, TextToSpeech.QUEUE_FLUSH, null, textToSay);
}
Could you use the TextToSpeech.OnUtteranceCompletedListener along with AudioManager.setStreamVolume to achieve this?