MediaPlayer State

by westmeadboy » Wed, 29 Apr 2009 01:07:59 GMT


Sponsored Links
 Is it possible to retrieve the current State of a MediaPlayer?

--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by westmeadboy » Wed, 29 Apr 2009 02:07:04 GMT


 How can I get the current State of a MediaPlayer instance?
--~--~---------~--~----~------------~-------~--~----~


Sponsored Links


MediaPlayer State

by Marco Nelissen » Wed, 29 Apr 2009 03:01:09 GMT


 What do you mean by that? If you want to know if it's playing, call
MediaPlayer.isPlaying(). If you want to know how far along it is, call
MediaPlayer.getCurrentPosition(). Are those kinds of things you're looking
for, or something else?






--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by westmeadboy » Wed, 29 Apr 2009 09:23:04 GMT


 No, I mean the states described in the documentation: IDLE,
INITIALIZED, PREPARED etc

At the moment, I do not know whether I can call prepare without
getting an exception. prepare() can only be called in certain Valid
states.




--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by Marco Nelissen » Wed, 29 Apr 2009 11:29:35 GMT


 You can't get that state directly, but you can infer what state the
MediaPlayer is in by whether or not you have successfully called the methods
you need to call to get into a state. For example, if you call
MediaPlayer.setDataSource(), and it succeeds, then you will be in the
correct state for calling prepare(), and if you then call prepare(), and it
succeeds, you will be in the PREPARED state.








--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by westmeadboy » Wed, 29 Apr 2009 13:57:15 GMT


 That's ok in a situation where you have very tight control over the
method calls to a MediaPlayer instance. However, in my case I have a
pool of MediaPlayer instances and so I need to know what the current
state of each one is before I can call any of those state-dependent
methods on it.

Of course, I can work around this by using the decorator (?) pattern,
working out what the state *should* be based on which methods were
called and what exceptions were thrown and whether the error handler
was called. But this is all messy and bound to result in my calculated
state getting out of line with the real internal state.

Is there any reason not to expose the underlying state?




--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by Marco Nelissen » Wed, 29 Apr 2009 22:52:28 GMT


 But you do have very tight control over the method calls to those
MediaPlayers, since they're in your code.
You didn't say what exactly you're trying to do, but it in general, you
should just call setDataSource() immediately followed by prepare(), and then
you're ready to play. If you ever need to change the sound, you call
reset(), setDataSource() and prepare() again, and you're again ready to
play. Is there a specific reason that you might want to leave a MediaPlayer
in some half-initialized state?







--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by westmeadboy » Wed, 29 Apr 2009 23:22:45 GMT


 The documentation lists 10 different states and while I could probably
reduce the number relevant to me to about 4 or 5, that doesn't help
enough.

One example of where this is important is knowing whether the player
is in PAUSED or STOPPED mode. pause() cannot be called in STOPPED
mode.

Of course, like I said, I can use the decorator pattern to do this
"tight control" to monitor the State but I feel like it makes way more
sense for the player's State to be exposed.

Do you know why the State is not exposed? If there is no good reason,
then what are the steps to request that it is exposed in some future
SDK release?




--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by Marco Nelissen » Thu, 30 Apr 2009 01:07:50 GMT


 




But shouldn't your app know whether it is paused or stopped, based on
whether it paused or stopped the mediaplayer prior to this?

Of course, like I said, I can use the decorator pattern to do this


One reason not to rely on these, and not to expose them so that people don't
try to rely on them, is that the states are inherently transient, because
they ultimately come from the media engine, which runs in its own thread(s).
Suppose for example that there was a method to ask for the current state,
and that that method told you that the current state is 'started'. That only
tells you that that was the state at the specific point in time where you
sampled it. There is no guarantee that the state is still the same by the
time your code looks at this returned state or acts on it. For example,
playback might have reached the end by then, so you're now in the 'playback
complete' state. Or an error might have been encountered since then, so
you're now in an 'error' state.

--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by westmeadboy » Thu, 30 Apr 2009 14:18:18 GMT


 > > Do you know why the State is not exposed? If there is no good reason,

I don't understand this. Are you saying that if the application keeps
track of the State then this is more accurate than if it had access to
the underlying State?

Before I call pause() I potentially need to check that the player is
not in one of these modes:

Idle, Initialized, Prepared, Stopped, PlaybackCompleted, Error

otherwise the errorListener is triggered.

Idle, Initialized and Stopped are completely in my control (and so is
Preparing, once the MediaPlayer has been Prepared) so the only ones I
really need to check for are PlaybackCompleted and Error.

So, as in your example, any call to pause() may result in the
errorListener being triggered because the MediaPlayer can suddenly
enter PlaybackCompleted State just before onCompletionListener has had
a chance to be triggered.

So, it seems to me that the MediaPlayer API is broken because there is
no clear contract for the client code. It details the valid states
under which the various methods can be called but does not allow this
State to be known, only guessed. If you are concerned about the State
changing from one client code statement (testing State) to the next
(invoking a method such as pause()) then isn't this what
synchronization is for?

Furthermore, if you don't want client code relying on the State then
why is isPlaying() provided? Doesn't this just test if the State is
Started?

I would have expected something like onStateChangedListener and using
synchronization to avoid the problem you mentioned.
--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by Marco Nelissen » Thu, 30 Apr 2009 23:44:01 GMT


 




No, synchronization won't help. To make your hypothetical getState() method
work reliably, you would have to essentially lock the MediaPlayer and
prevent further state changes to ensure that the state doesn't change again
while you process the result of getState(). But that would mean blocking the
underlying media playback engine as well (since that is ultimately the
source of the state changes), and you can't just go and block the media
engine because it could cause glitches.

Furthermore, if you don't want client code relying on the State then


isPlaying() is mainly a convenience for applications that want to implement
a play/pause toggle, so they can do something like:
if (mp.isPlaying())
   mp.pause();
else
   mp.start();
We should probably deprecate isPlaying() and provide a better way of doing
this.

I would have expected something like onStateChangedListener and using


Again, synchronization is not going to help. The best you can do is keep
track of errors and other events, and catch the exceptions that can be
thrown when calling MediaPlayer methods.

--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by westmeadboy » Thu, 30 Apr 2009 23:55:44 GMT


 OK, so you said one reason the State is not exposed is because you
don't want client code relying on these States because they are
"inherently transient".

However, the alternative is for the client code to keep track of this
State, which is no better in this regard.

Is there another reason not to expose the State?
--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by Marco Nelissen » Fri, 01 May 2009 00:29:26 GMT


 




No, the fact that a "getState()" method would be unreliable is reason enough
not to have one.

--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by Tom Gibara » Fri, 01 May 2009 00:33:31 GMT


 I have to agree with this. The MediaPlayer API is extremely hard work for
precisely the reason that it expects client-code to maintain state that it
can't reasonably be expected to know.

At the crux of the problem is the fact that the API is strict about the
valid transitions by throwing exceptions when invalid state changes are
attempted. This is fundamentally the wrong design for this API for the
reasons given above: that the MediaPlayer transitions can be asynchronous to
application flow.

In my opinion a much better approach would be to model the API properly
around a state engine, eg. with a setState() method which doesn't throw
exceptions but returns the new state so that failure to transition can be
detected. Combined with a state listener mechanism and a setStateAsync()
method, I feel I'd have all the 'tools' I needed to produce much more robust
media applications.

Perhaps something like this could be retrofitted in the future.

Tom




I don't understand this. Are you saying that if the application keeps
track of the State then this is more accurate than if it had access to
the underlying State?

Before I call pause() I potentially need to check that the player is
not in one of these modes:

Idle, Initialized, Prepared, Stopped, PlaybackCompleted, Error

otherwise the errorListener is triggered.

Idle, Initialized and Stopped are completely in my control (and so is
Preparing, once the MediaPlayer has been Prepared) so the only ones I
really need to check for are PlaybackCompleted and Error.

So, as in your example, any call to pause() may result in the
errorListener being triggered because the MediaPlayer can suddenly
enter PlaybackCompleted State just before onCompletionListener has had
a chance to be triggered.

So, it seems to me that the MediaPlayer API is broken because there is
no clear contract for the client code. It details the valid states
under which the various methods can be called but does not allow this
State to be known, only guessed. If you are concerned about the State
changing from one client code statement (testing State) to the next
(invoking a method such as pause()) then isn't this what
synchronization is for?

Furthermore, if you don't want client code relying on the State then
why is isPlaying() provided? Doesn't this just test if the State is
Started?

I would have expected something like onStateChangedListener and using
synchronization to avoid the problem you mentioned.

--~--~---------~--~----~------------~-------~--~----~ You received this
message because you are subs...

--~--~---------~--~----~------------~-------~--~----~



MediaPlayer State

by westmeadboy » Fri, 01 May 2009 00:46:41 GMT


 


Its no less reliable then any other call to any non-synchronized
getter method and there are plenty of those in the Android SDK.

An onStateChangedListener method would definitely be helpful.

I think Tom's post puts it all very well.
--~--~---------~--~----~------------~-------~--~----~



Other Threads

1. Selected state of WebView in a ListView does not show selection

We built an app at some point that was made of a ListView of WebViews.
I haven't tried this in a while though.








-- 
Romain Guy
Android framework engineer
romain...@android.com

Note: please don't send private questions to me, as I don't have time
to provide private support.  All such questions should be posted on
public forums, where I and others can see and answer them

--~--~---------~--~----~------------~-------~--~----~

2. Selected state of WebView in a ListView does not show selection

Question, is there a way to show that a WebView item contained as a
item in a ListView is selected?  Right now the WebView does not seem
to display its contents transparently like every other control so it
takes up the entire view and does not show its state as selected.

Also, when the content of the WebView is selected, scrolling down with
the track back does not seem to cause the WebView to loose focus.  If
I continue to scroll down with the track ball, all of a sudden an item
in the middle of the ListView gets selected.  This seems kind of odd
to me...


thanks,
Mark
--~--~---------~--~----~------------~-------~--~----~

3. how to pass object as a parameter when starting a service

4. Some Activities never display UIs?

5. Starting multiple services sequentially

6. MMS ( Messaging App ) ACTION_SEND "text/plain"

7. android DNS fail to resolve website IP adddres