How to stop service the service when android app has been closed - android

I am developing a app where I need to updated my values every 15 min.
For that i am using services.I came across different types of services.
Like for long running services we use simple service and,
for interacting for other components we use bind service,
foreground service. etc....
My situation is like i need to run the service for every 15 min
when my app is open and stop the service when my app is closed
I have tried with bind service using
http://www.truiton.com/2014/11/bound-service-example-android/
but i am unable to do that,I am unable to run the service every 15 min can any one help me.
Thanks in advance.

To start the service when your app starts, start it in onCreate() method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
To stop the service, you can implement the code in 3 different methods namely, onPause(), onStop() and onDestroy().
Calling stopService() in onPause() will stop the service as soon as some other event happens on your device like a phone call, which is not best way to stop since the user will return back to the Activity immediately as soon as the call finishes.
Calling stopService() in onDestroy() is also not the best solution because onDestroy is not called in all the ways a user can close an Android app.
Therefore, the best way to stop the service is by calling stopService() in the onStop() method as shown below.
#Override
protected void onStop() {
super.onStop();
Intent intent = new Intent(MainActivity.this, MyService.class);
stopService(intent);
}

If you want to stop service when your activity is closing then you have to implement the code inside onDestroy().
Below is an example-
#Override
protected void onDestroy() {
super.onDestroy();
Intent intent = new Intent(MainActivity.this, MyService.class);
stopService(intent);
}
This will your stop your service.
Unless you don't call finish() in the activity or you explicitly stop the app the onDestroy() don't gets called and your service will run even your calling activity is onPause (in background).
Similarly if you want to start your service activity start you implement in onCreate.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
let me know if it help your problem .

Related

android: how to receive broadcast from service when the app is inactive

When my service is running and I can see my app on the screen, everything works fine. My service sends broadcast messages and I can see them in my "MainActivity". But as soon as I push the home button and my app is no longer in the foreground, it stops. The service is still running but the broadcasts don't arrive at my "dead" or "pausing" app. This is my code:
Main Activity:
onCreate:
Intent intent = new Intent(getApplicationContext(), MainGate_Service.class);
startService(intent);
#Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver(ServiceReceiver, new IntentFilter("MainGate_ring"));
}
#Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
}
private BroadcastReceiver ServiceReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("ServiceMessage");
if(message != null) {
if(alarmActive && message.equals("ring"))
new soundPlayer().execute();
}
setNoti(message);
}
}
Service:
#Override
protected void onHandleIntent(Intent intent) {
ring = rcv_ring();
Intent ServiceIntent = new Intent("MainGate_ring");
ServiceIntent.putExtra("ServiceMessage", ring);
LocalBroadcastManager.getInstance(this).sendBroadcast(ServiceIntent);
}
whenever you press home button onStop gets call and there you are unregister receiver so there is not broadcast receiver who can receive broadcast.
LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
Remove above line from onStop() or unregister it whenever your service stop.
onStop#LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
literally unregister receiver. So there is no receiver to receive broadcasted message from service.
The problem is here
#Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(ServiceReceiver);
}
Activity.onStart() :
Called after onCreate(Bundle) — or after onRestart() when the activity had been stopped, but is now again being displayed to the user. It will be followed by onResume().
Activity.onStop()
Called when you are no longer visible to the user. You will next receive either onRestart(), onDestroy(), or nothing, depending on later user activity.
So as soon as you leave your activity onStop() is called and you unregister your receiver.
Don't put your unregister code in onDestroy() either, because it may or may not be called and the Activity might be killed without calling it.
As suggested by #Naveen Dissanayake you might want to reconsider your logic.
You register your BroadcastReceiver inside activity, so, it will depend on Activity's lifecycle. When you press back button, activity goes into 'stopped' state - methods onPause and onStop is called. Android can also destroy this activity in it is low on resources.
Service, on the other hand, i smeant to be running inndefinetely, even when ui is not ready. If you wanat to receive notifications from Activity, there is two
possible solutions:
- Create, store and manage BroadcastReceiver in Application instance - Application class is still running until your app is destroyed. It seems like you want to play sound when service notify you about some action.
Register BroadcastReceiver in onCreate and unregister in onDestroy in notifications.
- Another solution - use another Service if you want to trigger some action or IntentService, reacting to that broadcast.
I woud consider solution - create some ResponseService, start it along with your MainGate_Service (from Application) and stop it from application too. In that Service register BroadcastReceiver or, add IntentFilter into manifest if you want it to start even when app is not running. In your Activity, bind to that service. Serive will know if some UI is attached (if Activity is bound), and, if it is, will notify activity. If it don't - will do some other things (perhaps, show notification)
If you want to receive Broadcast even if your Activity is in
Background then,
Register in onCreate(...)
#Override
protected void onCreate(Bundle sis) {
super.onCreate(sis);
setContentView(...);
LocalBroadcastManager.getInstance(this).registerReceiver(ServiceReceiver, new IntentFilter("MainGate_ring"));
}
Unregister in onDestroy()
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).registerReceiver(ServiceReceiver, new IntentFilter("MainGate_ring"));
}

how to stop a service/thread when the application exits or from a different activity

now i have a server class that i run on a thread from an activity(i.e servActivity).now when i am not interacting with my app in anyway possible (like i have removed it from recent apps etc) the thread should stop which currently is not stopping. So i researched and i found that i should use a bound service. now a bound service i will have to bind it to servActivity and when servActivity is destroyed i have to unbind and stop service but i dont want to do that. i want to stop service when i am not interacting with the app. i also found that maybe i have to extend application class but cannot find the solution to achieve this?Is it advisable to extend the application class?
i want to be able to create a service running on independent thread from a particular activity(ie servActivity) and then be able to interact with the service from any activity and service should be active (even if the activity in which i started the service i.e-servActivity is destroyed by going to previous activity etc) through button or whatever until i am not interacting with the app(i have a notification controller which also needs to be closed to stop the interaction)
i have a client class on one device whose object i create again and again if i have to make request but i want to make only one object for server class because it has a while(true) loop so it keeps running so i want to be able to interact with the server from all activities and stop it when i am not interacting with the application
i also found a way in which i can make an abstract class which extends activity and extend that derived class to all the other activities in my app.But how to i bind the service to all the other activities in the class so that i can interact with the service from all the other activities?And how would i know that if all activities and notification controller have been stopped and there is no interaction with user?something like this how to know our app has gone to background in android
If there is there any other method please suggest
Please help
thanks in advance
You can create a BroadcastReceiver in your Service Class to interact/start/close your Service from any Activity or even from any App.
Your Activities can broadcast custom Action Strings which can be picked up by any BroadcastReceivers (even ones set up in Services) and thereby invoking their onReceive() methods allow communication.
1) I suggest you don't bind your Service to any Activity and instead use Intent to initiate it in your Activity like this....
//In your Activity
Intent i = new Intent(this, /*MyServiceClassName.class*/);
startService(i);
Or else your Service may still be active until you unbind it.
2) Create a BroadcastReceiver in your Service Class to listen for certain Action Strings broadcasted by your Activities....
//In your Service
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(/*"Action String to stop Service"*/)){
stopSelf();
}else if(action.equals(/*"Action string to interact with Service"*/)){
//Do what you want
};
3) Now set what Action Strings the Broadcast Receiver will listen for and also register it in your Service onCreate() method....
//In your Service onCreate() method
IntentFilter filter = new IntentFilter();
filter.addAction(/*"Action String to stop Service"*/);
filter.addAction(/*"Action String to do something"*/);
registerReceiver(receiver, filter);
4) And also unregister your receiver when Service onDestroy() is invoked as housekeeping....
//Service onDestroy()
#Override
public void onDestroy(){
super.onDestroy();
unregisterReceiver(receiver);
}
5) Finally broadcasting Action Strings from your Activities through Intent....
//From any Activity
Intent intent = new Intent(/*"your custom Action String that should match
up with whats set up with the BroadcastReceiver in Service"*/);
sendBroadcast(intent);
6) So once the broadcast is sent your receiver should pick it up then its onReceive() method will be invoked. Therefore you now have a medium for your Activities and Service to communicate through and also the Service will persist even after you close your app until you stop it explicitly with....
//From any Activity
Intent i = new Intent(this, /*MyServiceClassName.class*/);
stopService(i);
7) Stop service when app is stopped....
//In all your activities
#Override
protected void onDestroy() {
Intent i = new Intent(this, /*MyServiceClassName.class*/);
stopService(i);
super.onDestroy();
}
8) First you'd need to put a killcode intent action String in your Service as demonstrated in points 2 and 3 then put this code in your app's Activity onPause() methods....
#Override
protected void onPause() {
PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent(/*"Action String to stop Service"*/), 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
// set alarm to fire 10mins (1000*60*10) from now (SystemClock.elapsedRealtime())
manager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*60*10, pintent );
super.onPause();
}
And this in your app's Activity onResume() methods....
#Override
protected void onResume() {
PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent(/*"Action String to stop Service"*/), 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
manager.cancel(pintent);
super.onResume();
}

How to unbind a Service when the Activity Stops?

I'm trying to make a music player. To do that I'm creating a service that manages a MediaPlayer object and plays the songs. But every time I reopen my music application it starts a new Service and keeps playing two songs simultaneously. How can I make my Activity bind to the already running service?
I noticed that when I don't call unbindService (...) in the OnStop() method my application runs OK. But I don't know if its right to not unbind when the activity stops.
I'm binding like that:
#Override
protected void onStart() {
super.onStart();
Intent service = new Intent(this,MyService.class);
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if(mBound) {
unbindService(mConnection);
mBound = false;
}
}
You need to check on onStart() that is service running or not. If service is already running, then you need to just bind it. But in your current code you creating service everytime.
You should try to use Service.START_STICKY for checking that service is already running or not. You can see :
Service
, start Sticky or start not sticky
I think it will help you to update your service class.
I could fix it add startService(...) to the OnStart( ) method. I didnt understand why this fixed, but seems that I need to do that. If anyone knows why please add. Thanks for everyone help.
this is how OnStart got:
#Override
protected void onStart() {
super.onStart();
Intent service = new Intent(this,MyService.class);
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
startService(service);
}

How pause a service when the activity go in pause after the "home" button?

I have a service that look gps coordinate. I want that when the user click on the home button the gps stop to work (battery saving).
The strategy i am using is this:
#Override
public void onPause() {
super.onPause();
doUnbindService();
}
#Override
public void onResume() {
super.onResume();
doBindService();
}
on each Activity that use the service. The problem is that each time i switch activity it stop and resume. Is there a strategy that let me have the service always up until my app is in foregroung?
I have an app with 3 activities that use a service to deal with the GPS. In each activity's onStart() I have code of the form
bindService(new Intent(..., ..., Context.BIND_AUTO_CREATE);
and in each onStop() I have
unbindService(..);
You should find that activity 2's onStart() will execute before activity 1's onStop(). Thus only when no activities are running will the service stop.

killing a service in android?

In my app I am trying to use a Service to redirect my app to another Application.
I am starting this Service in onPause method and I am trying to stop this Service in onResume method, but the Service still keeps running and it redirects automatically.
protected void onPause() {
Intent in = new Intent(HelloappActivity.this,SimpleService.class);
in.putExtra("qwe", k);
startService(in);
super.onPause();
}
protected void onResume() {
stopService(new Intent(HelloappActivity.this,SimpleService.class));
}
so how should I stop this service?

Categories

Resources