Android Sound Resetting - java

My app plays a coin sound every time a button is pressed.
coin_sound.start();
You can easily press faster than the coin sound. When this happens I want the coin sound to start from the beginning ever time the button is pressed.
if(coin_sound.isPlaying()){
coin_sound.reset();
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
}
coin_sound.start();
The problem with this is that loading a media file tiny as it may be is still a relatively slow process. When you start to click the button really fast the app lags hard.
Are there any solutions to my problem? The only idea I have is to do something with an array of coin_sounds, but this method seems like it will be messy and gross...

The other answer posted here is somewhat correct. You should not call create over and over.
The code in that answer has a problem, though. The reset method sends the MediaPlayer into the idle state, where it is illegal to call most other methods. If you were to go that route, you have to call methods in the following order:
coin_sound.reset();
coin_sound.setDataSource(...);
coin_sound.prepare();
coin_sound.start();
The difference between calling create and the previous sequence of method calls is simply the creation of a new instance. That, however, is not the quickest way to do what should be done.
You should simply call coin_sound.seekTo(0); when you want the current playing sound to restart. So do something like:
if (coin_sound.isPlaying()) coin_sound.seekTo(0);
else coin_sound.start();
That assumes you have left the MediaPlayer in the prepared state so start can be called. You can accomplish that by calling reset, setDataSource, and prepare in the onCompletion listener. Also, make sure to call release when the sound is no longer needed.

It is because you are initiating coin_sound in the button click event, try this
initiate this variable in your oncreate method
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
then make this your code for your button
if(coin_sound.isPlaying()){
coin_sound.reset();
}
coin_sound.start();
the problem is you are recreating a new media player each time the button is clicked so the new media player doesnt think there is a sound
and do you need to start it again with coin_sound.start();? doesnt restart stop then start the sound for you?

Related

Should I release every time?

I was wondering if releasing my media player before I play a random sound is bad practice:
So I don't usually deal with media output too much, but I am making a simple app that plays a random sound every time a button is clicked (sounds [] is an array filled with raw media files)
public void onClick(View v){
if(mediaplayer != null){
mediaplayer.release();
}
mediaplayer = MediaPlayer.create(this, sounds[randomNum])
mediaplayer.start();
}
So my question is, would releasing my media player every time before creation be considered good/bad practice? Would there be any better way to do this, as releasing and re-initializing the MediaPlayer object seems like it would consume resources...
Thanks,
Ruchir
You typically use release() when you no longer want to use a MediaPlayer any more. Once you call that, it can never be used again. It effectively destroys the native components that back its functionality.
If you do release, you will have to prepare the media all over again the next time you want to play it. This can be a time consuming process. If you want a sound to play responsively to a button press, you probably don't want to have to prepare it each time.

Show(), what to put here?

I understand that the show() method is used to bring the screen back to the front when the user re-opens the app or brings it to the foreground.
However, what should go here?
Lets say I have a bunch of objects, with textures attached and actively being rendered and constantly moving position.
If I say, hit the pause button, the hide() function gets called and I the initiate a new screen. Say I come back to the GameScreen, does libGDX/Box2d automatically take care of everything for me or do I have to make sure that I have some sort of code in the show() method?
Anything that needs to be stopped in hide() should be restarted if needed in show(). This could include music, background threads, etc. I use show() to refresh the data behind the screen, since I keep instances around to avoud garbage collection.
There's no need for you to do anything, unless you want to put here some specific initializations. For instance, show() method is a good place to start playing a background music for the recently showed scene.

Preventing tilt from calling onCreate, and time measurement of an activity running.

Hi and thanks in advance for your time and attention.
I actually have 2 questions i'm not too sure about building an android app. Pretty basic stuff I believe:
1) My app is fully on Horizontal mode, like AngryBirds for example. When it starts the user figures out he should hold the phone like that, if he isn't already. And that is setup in the manifest for all the activities and works fine. but is there a way to prevent the physical device tilting to call onCreate again? can i override it's method or whatever? the reason i'm asking, is because i have a few ButtonViews that after you click on them, change their picture. i am using onRetainNonConfigurationInstance() to save the array of those ImageButtons, and i even mark the ones changed with the ImageButton setTag() and getTag() methods, so when onCreate is called because of the device tilt it gets the saved array from getLastNonConfigurationInstance() , but i've been trying to make it work for quite some time now and I just can't get it right. After the device tilt (I'm actually using the emulator so it's Ctrl+F11 but i believe it will happen with a device as well) all of the ImageButtons loose their pictures.. Long story short - are there better ways of doing this that you can recommend or is preventing the tilt from doing anything is possible or better?
2) What is the best way to know how many seconds the user has been on a screen? I tried to use two longs that i get via SystemClock.currentThreadTimeMillis() as follows: get the starting time onCreate, and the ending time on the method i call to move to the second intent just before i startActivity. but I think because they are called from different threads, the endingpoint - startingpoint is not correct. What is the way to insure both of the methods of SystemClock.currentThreadTimeMillis() are called from the same thread, the main thread of the activity that i'm stopwatching? Is there a better way to go around this?
Thanks again.
You are doing the right to handle orientation change. Please refer to this link http://developer.android.com/guide/topics/resources/runtime-changes.html . This will help you to get it working.
Good way would be to count the time between onResume and onPause. OnCreate is not called all the time if you are resuming activity.
1) You can try adding the property android:configChanges="orientation" to your activity in the manifest file. It worked for me when my dynamic Action Bar tabs got messed up upon rotation of the screen.
You need specify orientation in android manifest for each of your activities, it will not call onCreate then. android:screenOrientation look at http://developer.android.com/guide/topics/manifest/activity-element.html
User see and interact with your activity starting since onResume and ends on onPause. Other time it does not guarantee that user actually see and can click on something in the activity. System.getCurrentMillis() is good enough.

Is Dialog.show() a non-blocking method?

I've got a button that kicks off a background thread to do some work and I am trying to use a ProgressDialog to prevent the user from double clicking that button (or any other ui elements) while that work is being done. The first thing I do in my buttons onClick code is to display the progress dialog, which takes over the screen. The problem I am seeing is that if I rapidly tap this button, sometimes two or more presses will register before the ProgressDialog is shown. This leads me to assume that ProgressDialog.show() is returning before the ProgressDialog is actually visible.
Can anybody confirm this? Also, is there a way to change this behavior, or at least get a notification of when the dialog is actually visible? I saw Dialog.onStart() but given the javadoc, this appears to be called before the Dialog is actually visible...
UPDATE:
While it appears that there is no good way of solving this problem in general, the following works for my situation where my work is done by an external thread and the amount of work to do takes longer than the time it takes for all the button clicks to be processed:
void myOnClickHandler() {
if(myButton.isEnabled()) {
myButton.setEnabled(False);
// do work here
// setEnabled(true) is invoked at the end of my spawned thread's run().
}
}
No.
The problem is you clicked many times before the click event is delivered. (i.e. it is queued before you run ProgressDialog.show().)
From what I've noticed in Android you can double click on a button rapidly and have the onClick listener fire twice (or even more) regardless of the code in the listener (even if you disable the button immediately).
I reported a bug a while ago here: http://code.google.com/p/android/issues/detail?id=20073 but of course these things tend to go "unnoticed" by Google. Feel free to star it in hopes of getting Google's attention

Android Media Player Threading/Concurrency

I am using the default Android Media Player in an Activity, trying to play back a couple of video files. However I have a problem with programming what I want. The desired program outcome would be the following:
A video file is played back
After that, a dialog is shown, asking the user something
A pause of 5 seconds occurs
The next video is shown
and so forth
How am I to program this? Currently, I use a paradigm like the following:
I have a method that sets up the player for theĀ a file, e.g. playVideo(int) So I pass it the first file.
When the player is prepared, it will be started in onPrepared(MediaPlayer).
When the video is finished, the onCompletion(MediaPlayer) listener of the media player shows the dialog to the user by calling showDialog().
The user accepts the dialog. Before calling dismiss() on the dialog, the player object is started for the next file by calling playVideo(int).
This works, but it feels a bit quirky and not clean. And it's of course very procedural. The problems are:
that I can't figure out how to insert a pause after the dialog is dismissed.
that I maybe want to change the presentation order of dialogs and videos and this ain't too easy now
Has anyone got an idea?
For the pause, you could use the AlarmManager to schedule an alarm five seconds from now. It will launch an intent, and that intent could call playVideo(int).

Categories

Resources