I am new to Android. I am creating service for Media Player so that it can continue to play song even if i close the application. I have created activity for Media Player and it is having all the functionality like play , pause , next , previous , seekbar and also includes oncompletionlistener . All works excellent. But Now i want that all should be managed by service.
I have Created MyService Class :
public class MyService extends Service {
public static MediaPlayer mp;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
mp = new MediaPlayer();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
But in my player activity i have created ArrayList for Songlist from which i am taking currentsongIndex and through it i am maintaining all the functionality like next , previous and all.. Now in service how do i get songlist which is also required in my activity ?? Where should i create MediaPlayer object mean in service or activity ??
for MediaPlayer I have reffered http://www.androidhive.info/2012/03/android-building-audio-player-tutorial/ . For my media player code you can refer this site. Thanks.
Pleaze clear my doubt. I am so confused. Reply me soon..
You are on the right track. I have adapted from the SDK Samples; this is how I do it and it works great.
From your ArrayList (in your activity NOT from the Service) call
onListItemClick
and start an intent that starts the music service:
startService(new Intent(MusicService.ACTION_PLAY));
In your manifest you will need to add:
<intent-filter>
<action android:name="com.blah.blah.action.PLAY" />
<xxx xxx>
</intent-filter>
And of course in your Music Service you need to receive the Intent:
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
if (action.equals(ACTION_PLAY))
processPlayRequest();
}
Be sure to add Intents for skip, rewind, stop etc.
Let me know if this helps.
Getting the app to run in background should be taken care of by the 'Service' itself.
Try following this example http://www.vogella.com/articles/AndroidServices/article.html
A service is designed to work in the background.
I went through exactly the same thing! It's a long haul to develop even a really great mp3 player app. The answer is long.
Here are a few resources that really helped me. Android has a article on this very thing in their developer docs:
http://developer.android.com/guide/components/services.html
Pay attention to what it says at the bottom of this long article about bound services and running in the foreground.
Additionally, managing player state is what caused me the most headaches.
You'll also want to take a look at threading because spawning that new service will still execute everything on the Main UI Thread, sounds crazy but true. Take a look at the ExecutorService for managing thread pools. I wish I could tell you it was easier.
Unfortunately most of my formal training from all over the web but with android services comes from a paid site:
http://www.pluralsight.com/training/Courses/TableOfContents/android-services
It is a good resource for all programmers I think but has great sections about many aspects of android programming that are only covered briefly at other tutorial sites.
The resources at Vogella are good also, mentioned above.
Related
My Android app is playing audio while the app runs in the background with a service that runs as foreground, similar to many other apps such as Google Play Music, Spotify, and other music players / podcast player apps.
Most apps I checked, including Google Play Music, will leave the service running even when the app is cleared from recent. On the other hand, some will stop the audio and close the service (I only found Spotify doing that).
I am wondering what is the right way to handle this? Although most apps leave the service open, it seems that users will expect the audio to stop and the notification to disappear from the status bar together with the app.
Is there a right way here?
You can check this link to see what happens to the process when app is removed from
recents list.
Even if onTaskRemoved() is called, the app is not killed in this case. The service continues to exist. It can be proven by going to the hidden developer menu to check running processes.
You can execute some codes in this callback method, and get the desired behaviour.
Since it's a question of opinion, I'm going to give my own as a developer but also a power smartphone user (well, who isn't nowadays):
tl;dr: leave it running
===============================
longer version
The point of using your phone as a music player, is providing you with audio while you're doing other activities, like running, browsing, texting, or even playing music for others connected through a speaker, being the "dj" of your group. You would rarely use a music player as a primary task and I would expect to do that when you're doing something like trying to figure out the lyrics, or watch the videoclip (and hence, you would use YouTube). Thus, it is my belief that your music player should have a separate lifecycle than the rest of your phone activities. Imagine the nightmare of playing music for others and music suddenly stops while you're messing with unrelated stuff on your phone.
However, you have a point when mentioning that "it seems that users will expect the audio to stop and the notification to disappear from the status bar together with the app". I wouldn't get the whole statement as true, rather extract the gist: users want to stop their music app easily.
In that sense, you should make it as easy as possible to stop playback to optimize your user experience. Out of the top of my head, I would imagine the best way of doing that would be a nice "X" button in your notification extended (or even when compact) version. The user then can stop the playback right from the status bar and not have to go through bringing the app to the front.
If you do want to go a step further, you could have an option in your settings to either use a foreground or background service -to make it easier for the user to understand, you could use wording like "stop music when recent apps are cleared", hence delegating the choice to your user, according to their needs. That, of course, would add complexity and too much power to your users so it's up to you to figure out if you need it.
Leave it running, with a notification.
It's all in the name.
According to Android Developers,
"The Recents screen (also referred to as the Overview screen, recent
task list, or recent apps) is a system-level UI that lists recently
accessed activities and tasks."
Swiping the task away from this list just removes it from the list, not from execution.
Notifications (Certainly under Oreo) are where you let your user know that you still have service(s) running. Use the notification to allow them to re-open the task, and then terminate the service as they see fit.
You are making like music player application, so most of the time user expected that music will be played even if the application is closed from the recent task. Now you are using foreground service so notification will be shown, in this notification you provide STOP button, so the user can stop music from there.
But if you want that your app's background service is stopped after removing from recent task then,
public class CustomService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
//stop service
stopService(new Intent(this, CustomService.class));
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("CustomService", "Service Destroyed");
}
}
Now declare service in AndroidMenifest.xml
<service android:name=".CustomService" android:stopWithTask="false" />
android:stopWithTask="false" will give callback on onTaskRemoved(), so handle stop service over there.
leave the service running when the app is cleared from recent ,user can stop completely the audio and the service in the notification with a button just like this :
Here is a picture -> QQ Music
public class OnClearFromRecentService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("ClearFromRecentService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
//Code here
stopSelf();
}
}
Register this service in Manifest.xml like this
<service android:name="com.example.OnClearFromRecentService" android:stopWithTask="false" />
Then start this service on your activity
startService(new Intent(getBaseContext(), OnClearFromRecentService.class));
And now whenever you will clear your app from android recent Then this method onTaskRemoved() will execute.
I created a service class that should run in background.And it is working well.
The problem is when i remove task from recent panel it restarts and i loose all data stored in my service class.
I tried almost every way available on internet.
Search for a music player named Phonograph
It does just what i want, song keeps playing without any pause even after removing it from overview screen.
Service Class
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Manifest
<service
android:name=".service.MS"
android:enabled="true"
android:process="com.architjn.ms"></service>
-> Don't mark it as duplicate as i already tried previously asked similar questions, non of them worked for me.
You should use startForeground in your service
http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification)
Here is an example that maybe useful
https://github.com/imjarp/101AndroidExamples/blob/cbc64af4748f1f8876138ac077216fd8ab19840d/15-ParallelExecution/app/src/main/java/com/example/jarp/parallelexecution/MediaTranscoder.java
I would like to develop a media player for Android on my own but I have a conception issue : should I use a Service or an Activity just for the player?
I have Fragments in my App and I would like to play a song when I click on one of the items within my music lists but I don't really know which of those 2 technologies I should use to allow music to keep playing even during navigation or outside the app.
Does it better to start a new Activity when a song is played and then keep the Activity running or launch a Service waiting for some events?
Thanks in advance.
The best solution for your app may be
i) Visualize your app with frontend ( like selecting music to play, pause, forward and other features )
ii) start service that runs in background which continues the activity process in background even if the activity is closed ..
You can accomplish this by implementing following ->
public class MyService extends Service implements MediaPlayer.OnPreparedListener {
private static final String ACTION_PLAY = "com.example.action.PLAY";
MediaPlayer mMediaPlayer = null;
public int onStartCommand(Intent intent, int flags, int startId) {
...
if (intent.getAction().equals(ACTION_PLAY)) {
mMediaPlayer = ... // initialize it here
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync(); // prepare async to not block main thread
}
}
/** Called when MediaPlayer is ready */
public void onPrepared(MediaPlayer player) {
player.start();
}
}
I think this is somehow helpful to you ..
If you want music playing in background, you should definitely use Service. Use activity only for UI-related operations. Since playing music is not UI-related operation, it should be done in Service. Please take a look here: http://developer.android.com/guide/topics/media/mediaplayer.html
I am new to android and stuck up at some point in the app i am currently developing. In my onCreate method I have two independent tasks : First is playing sounds in an array using for loop and Second is an onClickListener to an image that makes it animate on click. The sound starts perfectly as soon as I start the app, My problem is when I click the image, it animates as required but it stops the sound. How can I play sound and animation independent of each other? Any help/idea would be appreciated.
Use AsyncTask in android it will update the ui too in method updateProgress in android
You can use service for playing music.Services are designed to continually running in the background.
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
MediaPlayer player = MediaPlayer.create(this, R.raw.audio);
player.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
player.setVolume(1f, 1f);
player.start();
I have a VOIP Application, I need to login the application in background on device bootup.
Currently the init to my application is done on UI Active(onCreate()).
I have the following things in my mind, can anyone help and clear my doubts.
The service design is must to achieve this task??
Which Service Remote(AIDL) or Local Service and why?
How does the UI and Service interaction happens?
After UI is active who gets the Call- Backs? UI or Service?
Should i make Service as my Controller i.e Service to UI data Pass Vice-versa?
Sample App: Skype.
So there are many ways to achieve what you want, it is a matter of what fits your style and design better. Hopefully you will find this information useful.
For the application to login in the background on startup there are a few option. The first thing you will need is a BroadcastReceiver which is defined as a receiver in the manifest. Have the BroadcastReceiver catch the ACTION_BOOT_COMPLETED intent. From here you can launch your Service. This leads to #2.
If all you are doing are RESTful calls then really an IntentService would be ideal. The difference between an IntentService and a Service is simple: An IntentService runs off of the main thread, executes it's 'code' and dies. A Service, however runs on the main thread (this is an important fact) and is long running so it has to be told to stopSelf(). To take matters further, a Service is also less likely to be killed compared to an Activity (application components are killed to make room in memory for newly launched apps), ie. it takes higher precedence. The service can also be declared a foreground service which requires a notification but give even higher precedence. I think in your case a Service would be perfect.
Once your UI (Activity) is opened the best way to connect to the Service would be the Binder. This will allow multiple interfaces to the Service from different applications / components if need be. AIDL is pretty cool stuff but from my experience much harder to manage since all parameters must be primitive or Parcables. AIDL is also slower an less efficient because it is really a form of IPC. When a Service is started with an intent the onStartCommand() method is called. If the service is started by an application trying to bind to it then the onBind() method is called. But you can start the Service with and Intent and then bind to it. If you prefer the RESTful approach where you just have quick calls for data you can use an IntentService with a ResultReceiver. This is a great article written about Google I/O examples and just overall well implemented if you are interested in the IntentService and ResultReceiver.
This is up to you. Using the Binder or AIDL your Activity can call the Service methods just like object method where the 'callback' would just be the method return. If you use a ResultReceiver the Activity interfacing the Receiver would be the callback. You could also just pass Intents back and forth but this could get messy. Again for your case the Binder approach would be good as well as a Receiver.
Think of the Service as a model in the MVVM system - use it as a helper to get data from, not as something that controls the logic of the application.
Sorry if this seems messy there are so many ways to achieve what you are looking for. Its just a matter of what fits your situation best what you 'feel' is better. Not to mention the Android SDK is pretty large. I tried to hit on all the topics that could help you out. Good luck!
Try a service with a boot reciever. Here is an example I found after a quick google search. Then make sure to store in the login info somewhere for when the app starts. Not sure what callbacks you might have, so really hard to answer that part. I would say that if the callbacks should affect the UI then let the activity take them over when it starts up. If you need a UI when only the service is running, probably best to throw up a notification and have it call the appropriate activity with the callback data.
you can authanticate user login by background services
package com.javaorigin.android.sample.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
String tag="TestService";
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();
Log.i(tag, "Service created...");
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(tag, "Service started...");
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
public class SampleAction extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView view = new TextView(this);
view.setText("Service Test");
Intent i = new Intent();
i.setClassName( "com.javaorigin.android.sample.service",
"com.javaorigin.android.sample.service.MyService" );
bindService( i, null, Context.BIND_AUTO_CREATE);
this.startService(i);
setContentView(view);
}
}
If you login is takes so long use [AccountManager][1] and do it only once.
The idea behind the AccountManager a token or whatever credentials you need to use in your Service.
In your particular case I think the best way of communicating your Activity with the Service is binding to it.
Best source of knowledge about basic Service usage is SDK. Long story short AIDL is used for IPC communications and as long as you run the service in the same process you don't need it. I suppose you have two options:
If the only thing you need is just login, you can start a service on boot up, login and then i.e. send a sticky broadcast with bundled login data which will be then received in application. See this question for a good set of ways to start a service on boot up.
#Override
public void onCreate() {
Data data = performLogin();
Intent i = new Intent(ACTION_VOIP_LOGIN);
i.putExtra(EXTRA_LOGIN_DATA, data);
mContext.sendStickyBroadcast(i);
}
...
private final class LoginReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// You may use a Bundle instead
Data data = intent.getParcelableExtra();
processLoginData(data)
}
}
protected void onCreate(Bundle savedInstanceState) {
...
IntentFilter filter = new IntentFilter(ACTION_VOIP_LOGIN);
mContext.registerReceiver(new LoginReceiver(), filter);
}
In second case you might want to move all your logic to the service. Here you'll extend the Binder class. See this SDK article for details.