I wanted to know how to pass a MediaPlayer object between activities so that I can maintain a constant sound play through out the application.
You don't "pass a MediaPlayer object between activities".
You need to access MediaPlayer from a custom Service to play sound in the background, and have your activities interact with this service.
For interaction my personal preference is binding using AIDL. Whenever I tried to use simple intents and onStartCommand() it revealed insufficient for activity/service interaction (I work with audio too). But it could work for you.
With AIDL and binding, you could expose custom functions such as play(uri), pause(), rewind(), etc.... The MediaPlayer instance would be created in play(uri) if it isn't already instantiated, and released in your service's onDestroy().
You can even register a listener with a RemoteCallbackList to get notified about position changes or some other events. See the examples on the AIDL documentation. What's nice about this is that your service can detect when a listener unregisters. This way you can have a small timeout in the service before you call stopSelf(), if another listener (activity) doesn't register quickly. That's useful because you don't necessarily know if an activity pauses because the user pressed the home button, or because he's cycling from one activity to the other.
Yeah, it needs a little work ;)
Note: you still need to call startService() before binding, otherwise the service will stop whenever an activity unbinds.
Check below link
http://developer.android.com/guide/appendix/faq/framework.html#3
Related
While creating android Auto media App MusicService class gets created extending MediaBrowserService which two methods gets auto implemented onGetRoot and onLoadChildren.
Can any one give detail explanation how every thing works.
Life cycle of MediaBrowserService looks like life cycle of simple Service which it extends.
From documentation:
The lifecycle of the MediaBrowserService is controlled by the way it
is created, the number of clients that have are to it, and the calls
it receives from media session callbacks. To summarize:
The service is created when it is started in response to a media button or when an activity binds to it (after connecting via its
MediaBrowser).
The media session onPlay() callback should include code that calls startService(). This ensures that the service starts and continues to
run, even when all UI MediaBrowser activities that are bound to it
unbind.
The onStop() callback should call stopSelf(). If the service was started, this stops it. In addition, the service is destroyed if there
are no activities bound to it. Otherwise, the service remains bound
until all its activities unbind. (If a subsequent startService() call
is received before the service is destroyed, the pending stop is
cancelled.)
The following flowchart demonstrates how the lifecycle of a service is
managed. The variable counter tracks the number of bound clients:
onGetRoot and onLoadChildren used to manage client connections.
But to use MediaBrowserService this is not enough, so you should read this documentation (follow nested links).
Taken from MusicPlayer.java:
This class provides a MediaBrowser through a service. It exposes the
media library to a browsing client, through the onGetRoot and
onLoadChildren methods
onGetRoot(..): Returns the root id if the client package has permission to access media information (Returns null if the client is not allowed). Source
onLoadChildren: Returns a list of children of a media item. Source
To get a idea of the implementation of both check the implementation in MusicPlayer.java
I initialize a MediaPlayer object in my main activity to play music. I would like my app to keep playing music when the user closes the app. I guess when the user closes the app, the MediaPlayer object goes out of scope. How can I keep keep the music playing after the app is closed?
How extend life cycle of an activity object
You can't.
If you want to run code when your app is in the background, you have to use a Service
You're looking at this wrong. Extending the life cycle means opening the door to leaks. There's also a considerable amount of things to keep track of.
The recommended way is via a Foreground Service. Your activity ideally binds to your service and controls the music playback via the provided Binder interface.
You can also allow the service to be controlled directly through your service's Ongoing Notification.
An example of the the above is Google Play Music.
Good luck.
I want to achieve following goals:
Record Audio
Send Audio to Server
Play Audio
I know that First 2 tasks are possible by Using Service as I've done that in one of the previous apps but when it comes to playing an audio file, it needs to be triggered from an Activity.
Because accessing Activity from Service can be achieved by using BroadcastReceiver but what about accessing method of a Service from an Activity?
So, now comes the question: Whether to go for Service itself for Playing the audio also(triggered from activity) OR to use IntentService.
Documentation says,
No easy or direct way to interact with user interface directly from IntentService.
and
Any tasks started using IntentService cannot be interrupted
I may want to stop recording ant time and play it any time.
Which would suit t he requirement best --> Service OR IntentService ??
Any suggestions will be highly appreciated.
I would use a Service rather than an IntentService for what you need.
In particular, use a bound Service which allows two-way communication between the Activity which binds to it and from the Service to the Activity.
The IntentService class is designed for one-shot operations using its own worker thread, once the work on the thread is complete, the thread terminates and the IntentService calls stopSelf() to terminate itself. This means any user interaction between the user (via an Activity) and an IntentService is problematic.
A bound Service on the other hand will exist until it is either explicitly stopped or untill the last bound component unbinds. This allows for longer term interaction.
For playback, the fact a Service runs on the UI thread isn't an issue if you use something like MediaPlayerwhich handles its own thread for playback purposes.
Further to this, if you use a bound Service, MediaPlayer and MediaController, you can control play, stop, pause, seek etc from the Activity.
EDIT: For further information see... Bound Services
I have a series of activities, one of which is called UserActivity. What I'd like to do is have an object ListenerObject, that listens specifically for when UserActivity starts or stops. That is, I want UserActivity.onStart() to call ListenerObject.onActivityStart() (or some method named similarly).
I know that I can create an observer pattern set of classes to do this, but I'm wondering if there already exists such a framework within the Android API, and, more importantly, an accepted set of use patterns.
You could do this through Broadcasts:
http://developer.android.com/reference/android/content/BroadcastReceiver.html
http://developer.android.com/guide/components/intents-filters.html
In a few ways...
1) Have both activities receive and start from the same intent.
2) have activity 1 launch a broadcast to activity 2.
If ListenerObject makes sense as a static singleton you can just call the method on it during onStart() and onStop():
MySingleton.getSharedInstance().onActivityStart();
which would save you some overhead of the other valid methods mentioned.
The Android devs mention static singletons in the context of lazy creation for speed and reduced memory usage quite a bit it seems so it seems like an accepted pattern.
Depends on the required life cycle of the ListenerObject.
Seems like you want it to be around when the UserActivity isn't, but what about when you have none of your Activities on screen?
You could start a Service and then bind / unbind to it in your UserActivity's onStart / onStop. The service would likely stay alive whilst your app was in the background.
You could (un)bind to a service in all your Activities' onStart/Stop and provide an IBinder interface which asks would allow the service to ask the Activity if it is the UserAnctivity. The service would live whilst you navigate the app, but die once you put it in the background or go to another activity that doesn't bind to it (probably not what you want if you're doing something with G+ authentication / in app purchases etc).
You could (like others suggest) create a singleton, which won't die until the Application does, but won't keep it alive either.
You could have an Event Bus where the Listener subscribes to a known event published by the UserActivity.
shrug just some ideas
Ok, so I have this problem. I have a service that plays a mp3 file. I can also pause and stop the mp3 by AIDL functions. That works perfect. I can press the homebutton an then restart the activity and I have still control over the service.
However, if I press the back key and then opens the activity I can't control the service anymore.
I think it should be possible to rebind to the control when restarting the activiy. But what's happening is that new instance of the service is started and I can't stop the mp3 that is playing. I can play a new mp3 however. What am I doing wrong?
I think I understand what you want to do. After starting the activity and starting the mp3 playback, you exit from the activity. Then next time you open it you want to bind to the existing service and not start another instance of the service.
To achieve this, you have to use a started activity, and then bind to it. That is, use startActivity(Intent) on press of button, then in the next line, do bindService(Intent, connection, Context.FLAG_AUTO_CREATE);. This binds the service, then you can unbind in onDestroy (recommended) or onPause. Also, as this is a started service, it does not get destroyed when unbind. You have to explicitly call stopService(Intent) or stopSelf() to stop this service.
In the onResume of your activity, you should check if service is running, and then bind to it again using the code: bindService(Intent, connection, 0);
The connection object is a registered ServiceConnection that is fired everytime you bind or unbind to the service.
private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
}
public void onServiceDisconnected(ComponentName className) {
}
};
Also, you can send and receive messages from the activity, in your case the time of mp3 song play, using Messenger Service.
Refer to this link to learn more about using Messenger.
Hope this helps.
I think is should be possible to rebind to the control when restarting the activiy.
I am sincerely hoping you unbound from the service, since you should not go through onDestroy() of an activity without unbinding.
But what's happening is that new instance of the service is started and I can't stop the mp3 that is playing.
This suggests that you did indeed unbind from the service, but the service did not stop the music playback when it was destroyed.
What am I doing wrong?
Most music players are designed to allow playback after the user exits the activity. Hence, music players should not be using the binding pattern, because the binding pattern does not support the service continuing to run after the user exits the activity.
Instead, use the command pattern: call startService() to start up music playback, perhaps with Intent extras to control what gets played. Call stopService() to stop music playback. Here is a sample project that demonstrates this, with the actual music playback stubbed out (as I cover that in a different book).
This is quite an old question but I'm currently working with a related problem. What I've found is that Binding to a service is meant so other applications can also bind to your service and make use of its functionality.
That is an alright pattern, it might work for your application.
What I think you should do, since I cannot find a way to rebind to a service; is to check if the service is running (which could be accomplished easily through a static boolean in the service class that is changed to true when running and changed back to false when destroyed) and use that boolean to prevent the onCreate of your application to reinitiate a new service intent. You can then bind to it again and use its functions.
Also, if there's only a possibility of using 1 song at the time, you might want to change all these variables to statics so any bound application can influence its variables (think volume, etc.) and read from its variables as well (think time playing, title, etc.)
Hope this helps a bit!