I want to connect Android OS default tick sound (for example, the sound you hear when you long click Home button and select previous app to start) with my button click. I know how to play sounds via MediaPlayer, but I do not know where to search for this default tick sound. It had to be in some default resources, but I could not find it.
MediaPlayer mp = MediaPlayer.create(getBaseContext(), sound);
mp.setLooping(false);
mp.start();
Anyone can help?
PS. this sound will be activated inside of onClick method.
PPS. I know I can user /raw dir, but I do not think there's a need for it. Not to say, it's cooler to play this tick sound prepared for user's phone.
You can play the default Android 'tick' sound using the view.playSoundEffect() method on any View - surprisingly enough, all views can play a selection of 'system' sounds:
view.playSoundEffect(SoundEffectConstants.CLICK);
and don't forget to add this to your view :
android:soundEffectsEnabled="true"
This is probably the simplest answer to your problem :)
If you want control over the volume of the sound, use the AudioManager system service. Plus this can be used from a Service if you don't have a view handy.
// get the AudioManager once onCreate or similar
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
...
// Play a System Sound
audioManager.playSoundEffect(SoundEffectConstants.CLICK);
// OR at 50% Volume
audioManager.playSoundEffect(SoundEffectConstants.CLICK, 0.5F);
If you are on Google GLASS you can use the com.google.android.glass.media.Sounds constants
audioManager.playSoundEffect(Sounds.TAP);
The following are included in Sounds
DISALLOWED, ERROR, SUCCESS, TAP, SELECTED, DISMISSED
Roberto Tyley's answer is correct.
You can play a sound from every view just by calling it this way:
Button01.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
v.playSoundEffect(SoundEffectConstants.CLICK);
}
});
Just note that the sound will not play if touch sounds are off by default. This is set in the general device sound preferences (Settings-->Sound-->Audible or on newer OS: Options > Sound > Touch)
Also, if this setting is set, most click events will trigger the click sound anyway!
You can use tick, beep or any kind of inbuilt sound by Tone Generator
ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);
NOTE: This is a pretty old answer. Check Roberto Tyley's answer below.
I think the sound that you are looking for is and is in - /system/media/audio/ui/KeypressStandard.ogg
I think you can give that path to the SetDataSource API of the mediaplayer. But I am not really sure if it will have the same name in all android phones.
There might be a better way to query for default click sound..
Related
hi ive been working on my app and have found a hurdle in an activity i just cant seem to overcome. the activity is essentially a large novelty piano with 8 keys that play sounds there are 6 buttons along the side that change the picture of the notes and the notes themselves, this i accomplished :-) now i would like to add a background song to each different set of notes (instruments) only when i do the app crashes i have set the mediaplayer at the top (globally?) using MediaPlayer mp; MediaPlayer mp2; etc and im using this in my code to check if any music is playing, stop it, release it, and then play the piece i want,
if(mp!=null&&mp.isPlaying()){
mp.stop();
mp.release();
}
if(mp2!=null&&mp2.isPlaying()){
mp2.stop();
mp2.release();
}
if(mp3!=null&&mp3.isPlaying()){
mp3.stop();
mp3.release();
}
mp3 = MediaPlayer.create(MusicActivity.this, R.raw.snaps);
mp3.setLooping(true);
mp3.start();
this again works but going from one to another and then back crashes the app. is there something else i should be doing? or is just an out of memory error?
EDIT--
Thanks to ranjk89 for his help
changed to soundpools but they wont stop ranjk89 suggests referring to the stream id and not the sound id looking for a little more clarification if possible i have
farmback =0;
drumback =0;
at the top then its loaded in oncreate using
drumback = sp.load(this, R.raw.snaps,1);
farmback = sp.load(this, R.raw.oldmacdonaldbeta,1);
and then way down, in the same method i change the button icons, not the same method i change all my other sounds for my notes i call
sp.stop(drumback);
sp.play(farmback, 1, 1, 0, -1, 1);
in one and
sp.stop(farmback);
sp.play(drumback, 1, 1, 0, -1, 1);
in another but there are 6 different instruments in total that all need a different backing track which should stop when the instrument is changed and play the one associated to it so something like
if (sp !=null && sp.isplaying()){
sp.stop();
sp.play(dumback);
}
but obviously this is not possible any help appreciated
My Initial reaction is, you shouldn't be using multiple MediaPlayer at all in the first place.
I would suggest you to use SoundPool as you can load all the media(audio) initially, once they are all loaded you can play them at will. Plus you won't have multiple players which would downsize the complexity of your code.
But if you do want to use Media player,
See this. But be aware that once you release you will not be able to reuse that instance of MediaPlayer. Even if you are using multiple MediaPlayers, do not call release on them unless you are sure you don't want to use them any more. Use stop()/prepare() combination.
For application doing too much work on the Main Thread,
If you either use a SoundPool or only one MediaPlayer and still bump in to the same issue, Use AsyncTask. Android dev site has a very good tutorial on this
I'm developing a game in Android and I came across a very annoying, hard-to-find bug. The issue is that when you are using SoundPool to play your sounds, you can actually loop whatever sound you are playing. In this case, the issue is the "running steps" sound; this sound gets executed quite fast and continually (around every 400ms) when the main character is running.
Now when playing the sound on a regular (not so powerful) device e.g. Samsung SII, the sound is played every 500ms - however, if I run the very same code on another device (let's say, Samsung SIV, Samsung SIII), the sound plays twice or even three times faster.
It seems like the more powerful the device hardware specs are, the faster it plays. On some devices, it plays so fast that you almost hear one solid continuous sound. I've been looking for techniques to set a specific ratio on the time period between sound plays, but it doesn't work properly and the issue remains. Does anyone know how to fix it, either using SoundPool, MediaPlayer, or any other sound-controlling API on Android?
You could use an AudioTrack to play a continuous stream of PCM data, since you would pass a stream you could be sure about the interval between sounds. the downside could be a little delay when first starting the sound but it depends on the minimum buffer size, and it depends, I think, on android version and device. On my galaxy s2 android 4.1 it was about 20ms.if you think this could be an option I can post some code
The problem with just looping or using a regular interval for something like footsteps is that you have a possible decoupling of sound and visuals. If your sound gets delays or sped up, or your visuals get delayed or sped up, you would have to adjust for that delay dynamically and automatically. You already have that issue right here
A better solution would be to place a trigger on the exact event which should trigger the sound (in this case, the foot being placed down), which then plays the sound. This also means that if you have multiple sources of the sound (like multiple footsteps), you don't have to manually start the sound with the right interval.
I can't seem to replicate the issue on Galaxy Nexus and Nexus S, does that mean I fixed it? Or maybe you could show what you're doing differently from this:
SoundPool soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
Integer sound1 = soundPool.load(this, R.raw.file1, 1);
Integer sound2 = soundPool.load(this, R.raw.file2, 1);
playSound(sound1);
public void playSound(int sound) {
AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
float volume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC)
/ mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundPool.play(sound, volume, volume, 1, -1, 1.0f);
}
If the problem is that you want to control the interval between the discrete sounds, The easiest way to do this is with a handler.
Basically you start a sound playing which is an asynchronous process. Then you use a handler to schedule a message to play the next sound sometime in the future. It will take some trial and error to get it right, but you will be guaranteed that the sound will start at the same interval after the previous sound on every device.
Here is some code to illustrate what I am talking about.
Here is a handler implementation you could use:
handler = new Handler() {
/* (non-Javadoc)
* #see android.os.Handler#handleMessage(android.os.Message)
*/
#Override
public void handleMessage(Message msg) {
if (msg.what == NEXT_ITEM_MSG) {
playNextSound();
}
else if (msg.what == SEQUENCE_COMPLETE_MSG) {
// notify a listener
listener.onSoundComplete()
}
}
};
Then you could write playNextSound like this:
private void playNextSound() {
if (mRunning) {
// Get the first item
SoundSequenceItem item = currentSequence.getNextSequenceItem();
if (item == null) {
Message msg = handler.obtainMessage(SEQUENCE_COMPLETE_MSG);
handler.sendMessage(msg);
return;
}
// Play the sound
int iSoundResId = item.getSoundResId();
if (iSoundResId != -1) {
player.playSoundNow(soundResId);
}
// schedule a message to advance to next item after duration
Message msg = handler.obtainMessage(NEXT_ITEM_MSG);
handler.sendMessageDelayed(msg, item.getDuration());
}
}
and your SoundSequenceItem could just be a simple class that has a sound file resource id and a duration. If you want to keep playing the sound while the character is moving you could do something like this:
public void onSoundComplete() {
if (character.isRunning()) {
currentSequence.addSequenceItem(new SoundSequenceItem(R.id.footsteps,500);
playNextSound();
}
}
Or you could modify playNextSound to continually play the same sound. Mine is written this way to be able to play different sounds in sequence.
I have had a lot of problems developing apps which used sounds and stuff like that. I would not suggest you to use SoundPool since it is bug-affected, and also be aware that looping sounds with SoundPool won't work on devices which are 4.3 and higher, see this open issue, at AOSP - Issue tracker.
I think that the solution is to go native and use OpenSL ES o similar libraries.
Just to specify the question a little more, I will give an example. I have a car stereo and when I get in the car I can just press play and it plays the last song I was listening to on my phone. So what I need is like a very general Android button that does just that. I just want this button to start media. It's difficult to explain but I know like Google Music when you open it always has a song at the bottom that you can press play. So it's kind of like just continuing a previous queue? If more details are needed please let me know. Sorry I do not have any code for this problem because I have never worked with media but if you would like the source to my app that this code will go into please visit
http://mellowdev.net
The app is called Mango. Open source.
EDIT: I have tried the following but nothing plays.
MediaPlayer mediaPlayer = new MediaPlayer();
int position = mediaPlayer.getCurrentPosition();
mediaPlayer.seekTo(position);
mediaPlayer.start();
As I understand you want to play the music from last known position (or better say from the last known time of the sound). It's something similar like the user change the orientation then you want to play the sound from current position and don't want to start the sound again.
Therfore you have two method in the MediaPlayer:
int position = mediaPlayer.getCurrentPosition();
mediaPlayer.seekTo(position):
I think this post will help you (the example is for a VideoView, but it should be similar to the MediaPlayer).
Hope this will help you :)
EDIT (2013 08 16)
// create a MediaPlayer Instance with the sound you want to play
MediaPlayer mediaPlayer = MediaPlayer.create(context, mySound);
I couldnt't exactly understand your code. But if you need to play media in android, you need to create instance of MediaPlayer and can start to play using a button. Below link will give you more insight:
http://developer.android.com/guide/topics/media/mediaplayer.html
Sorry if I mis understood your question.
To just launch music player:
Intent intent = new Intent(MediaStore.INTENT_ACTION_MUSIC_PLAYER);
startActivity(intent);
I've got a SoundPool[] that I use to play mixed audio files.
Soundpools play together without any problem, and it's very efficient!
Very briefly:
private SoundPool[] sound = new SoundPool[C.ROWS];
// every sound is initizialized with a load()
// and when asked...
public void play(int row, int variation) {
if (mute[row]) return;
if (variation != 0)
sound[row].play(variation_scheme[row][variation-1], volume[row], volume[row], PRI, 0, 1f);
}
This is just to show! :)
I don't put other pieces of code because everything works very fine and it is not really a problem.
My question, instead, is:
how can I redirect the whole output of the application to a file, instead of (or in addition to) the audio speaker?
In other words, there are two main solutions:
1. how can I instruct AudioPool to play() the sounds to a file instead of to an audio device?
2. or how can I redirect all the audio output of my app (or even of all the phone) to a file?
Thank you.
The only way I found how to record audio is by recording each information of the sound being press such as, duration (using mediaplayer), soundID, millisecond time stamp to do play back to the millisecond, volume, rate (if needed). Then write these to a text file (internally or externally) for later use. Create a play back system that decodes that saved information from text file and organize it in some arrays or hashmaps and play back throught some sort of play back method with maybe using a handler and postDelay to play sound and desired time and then plug in necessary data to play sound from array or hashmap.
In this way you can have your own data files for playing sound sequences.
I am working on a life saving medical app and if the user is in a life threatening situation, they need to hear the alert.
When I have a notification to the status bar or have a dialog appear for a critical message to the user, I need to get their attention. If the media volume or ringer volume is low or off, I want to override it for my alert only. I would prefer not to change the settings for the phone, just for my one sound that I want to play.
When I try:
AudioManager audioManager = (AudioManager)getSystemService(this.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_RING,
audioManager.getStreamMaxVolume(AudioManager.STREAM_RING), 0);
This correctly sets the volume for my stream but has the side effect of changing the stream volume for everyone else.
Is there a way of setting the volume for one song only?
It could be set back after the song is done.
AudioManager audioManager = (AudioManager)getSystemService(this.AUDIO_SERVICE);
int current_volume=audioManager.getStreamVolume(AudioManager.STREAM_RING);
audioManager.setStreamVolume(AudioManager.STREAM_RING,
audioManager.getStreamMaxVolume(AudioManager.STREAM_RING), 0);
// Play here
audioManager.setStreamVolum(AudioManager.STREAM_RING,current_volume,0);