I start service from activity which are sending data throught socket to server. When service is started in it's onCreate() method I also set alarm with setExact() method. My problem is that when onReceive() in BroadcastReceiver is called I want to stop service, which is working corectly but it is also immedeately started again. Service is stopped with next code:
Intent i = new Intent(context, SocketService.class);
context.stopService(i);
which work correctly if it is called from Activity. When BroadcastReceiver is executed, no activity is binded to that service so it should stop without immedeately recreating.
Your service.
private Intent myservice;
Start your service on method onCreate()
myservice = new Intent(this, myservice.class);
startService(myservice);
also you can start your service with handler.
And for stop use handler.
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
stopService(myservice);
break;
default:
Log.d("STOP", msg.what + " ? ");
break;
}
}
};
for use handler on BroadcastReceiver make this
handler.sendEmptyMessage(1);
Related
I just start background service in Handler.now I want to stop Service but service not stopped from Handler and any other class.
below is My Code:-
below is handler where i try to Start And Stop Service.
mHandler = new Handler();
mRunnable = new Runnable() {
#Override
public void run() {
Log.e("mTrackStatus",String.valueOf(mTrackStatus));
if (mTrackStatus == 1) {
Log.e("BACKGROUND=", "background Service Start");
//handler will call after every 10 seconds
context.startService(new Intent(context, BackgroundService.class));
mHandler.postDelayed(mRunnable, 10000);
} else if (mTrackStatus == 2) {
Log.d("StopTracking", "StopTracking");
context.stopService(new Intent(context, BackgroundService.class));
mHandler.removeCallbacks(mRunnable);
}
}
};
// mHandler.postDelayed(mRunnable, 10000);
mRunnable.run();
I have tried Lot's Of method like
1. context.stopService(new Intent(context,BackgroundService.class)); and stopSelf(); but it will not work for me
I have Spent 2 days on this problem. Finally i Solve the Issue.Actually My BackgrounService is Stop by using :-
context.stopService(new Intent(context, BackgroundService.class));
I use onLocationChanged() method in My services class and when i Try to Stop Service, Service is Stopped but onLocationChanged() method is Continue sly running in Background. By using Stop Service Service is stop but onLocationChanged() is not Stopped because it Android Default method which we can not able stop that.
i have created one service by extending Service in android and i am sending Message to service using Messenger and Handler.
But the issue (which is a common behavior though) is whenever i have to send message to Service i have to bind it and when i go out of activity i have to unbind it which eventually destroys the service itself.
i can keep running service in background by fringing startService method but is there any way to send Messages to service without using bind as i don't want to destroy the service when i go out of activity.
LocalBroadcastManager is a great way to send messages/data,
In your service class create a private broadcastreciever and string for the intent action name:
public static String MSERVICEBROADCASTRECEIVERACTION ="whatevs";
private BroadcastReceiver mServiceBroadcastReceiver= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("foo","onReceive called");
Log.d("foo","extra = " + intent.getStringExtra("foo")); // should print out " extra = bar"
}
};
And register it in your onCreate
#Override
public void onCreate() {
// your other code...
LocalBroadcastManager.getInstance(this).registerReceiver(mServiceBroadcastReceiver, new IntentFilter(ServiceClassName.MSERVICEBROADCASTRECEIVERACTION));
}
And De-register it in onDestroy()
#Override
public void onDestroy() {
// your other code...
LocalBroadcastManager.getInstance(this).unregisterReceiver(mServiceBroadcastReceiver);
}
As for sending messages to it, from an activity or fragment:
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
Intent intent = new Intent(ServiceClassName.MSERVICEBROADCASTRECEIVERACTION);
// add some data
intent.putExtra("foo","bar");
lbm.sendBroadcast(intent);
HTHs you send data without needing to bind!
Unbind Service will not destroy the service. it will disconnect the service connection between the activity and service
Make sure you return START_STICKY to keep your service running
#Override
public int onStartCommand(Intent intent, int flag, int startId)
{
return START_STICKY;
}
Also make sure your running the service as foreground
using notification to keep running the service after the application is removed from stack.
startForeground(1000,mBuilder.build()); // mBuilder - notification builder
I have an IntentService that is started from an Activity and I would like to be able to stop the service immediately from the activity with a "cancel" button in the activity. As soon as that "cancel" button is pressed, I want the service to stop executing lines of code.
I've found a number of questions similar to this (i.e. here, here, here, here), but no good answers. Activity.stopService() and Service.stopSelf() execute the Service.onDestroy() method immediately but then let the code in onHandleIntent() finish all the way through before destroying the service.
Since there is apparently no guaranteed way to terminate the service's thread immediately, the only recommended solution I can find (here) is to have a boolean member variable in the service that can be switched in the onDestroy() method, and then have just about every line of the code in onHandleIntent() wrapped in its own "if" clause looking at that variable. That's an awful way to write code.
Does anybody know of a better way to do this in an IntentService?
Here is the trick, make use of a volatile static variable and check continue condition in some of lines in your service that service continue should be checked:
class MyService extends IntentService {
public static volatile boolean shouldContinue = true;
public MyService() {
super("My Service");
}
#Override
protected void onHandleIntent(Intent intent) {
doStuff();
}
private void doStuff() {
// do something
// check the condition
if (shouldContinue == false) {
stopSelf();
return;
}
// continue doing something
// check the condition
if (shouldContinue == false) {
stopSelf();
return;
}
// put those checks wherever you need
}
}
and in your activity do this to stop your service,
MyService.shouldContinue = false;
Stopping a thread or a process immediately is often a dirty thing. However, it should be fine if your service is stateless.
Declare the service as a separate process in the manifest:
<service
android:process=":service"
...
And when you want to stop its execution, just kill that process:
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
Iterator<RunningAppProcessInfo> iter = runningAppProcesses.iterator();
while(iter.hasNext()){
RunningAppProcessInfo next = iter.next();
String pricessName = getPackageName() + ":service";
if(next.processName.equals(pricessName)){
Process.killProcess(next.pid);
break;
}
}
I've used a BroadcastReceiver inside the service that simply puts a stop boolean to true. Example:
private boolean stop=false;
public class StopReceiver extends BroadcastReceiver {
public static final String ACTION_STOP = "stop";
#Override
public void onReceive(Context context, Intent intent) {
stop = true;
}
}
#Override
protected void onHandleIntent(Intent intent) {
IntentFilter filter = new IntentFilter(StopReceiver.ACTION_STOP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
StopReceiver receiver = new StopReceiver();
registerReceiver(receiver, filter);
// Do stuff ....
//In the work you are doing
if(stop==true){
unregisterReceiver(receiver);
stopSelf();
}
}
Then, from the activity call:
//STOP SERVICE
Intent sIntent = new Intent();
sIntent.setAction(StopReceiver.ACTION_STOP);
sendBroadcast(sIntent);
To stop the service.
PD: I use a boolean because In my case I stop the service while in a loop but you can probably call unregisterReceiver and stopSelf in onReceive.
PD2: Don't forget to call unregisterReceiver if the service finishes it's work normally or you'll get a leaked IntentReceiver error.
#Override
protected void onHandleIntent(Intent intent) {
String action = intent.getAction();
if (action.equals(Action_CANCEL)) {
stopSelf();
} else if (action.equals(Action_START)) {
//handle
}
}
Hope it works.
In case of IntentService it does not stop or takes any other request through some intent action until its onHandleIntent method completes the previous request.
If we try to start IntentService again with some other action, onHandleIntent will be called only when previous intent / task is finished.
Also stopService(intent); or stopSelf(); does not work until the onHandleIntent() method finishes its task.
So I think here better solution is to use normal Service here.
I hope it will help!
If using an IntentService, then I think you are stuck doing something like you describe, where the onHandleIntent() code has to poll for its "stop" signal.
If your background task is potentially long-running, and if you need to be able to stop it, I think you are better off using a plain Service instead. At a high level, write your Service to:
Expose a "start" Intent to start an AsyncTask to perform your background work, saving off a reference to that newly-created AsyncTask.
Expose a "cancel" Intent to invoke AsyncTask.cancel(true), or have onDestroy() invoke AsyncTask.cancel(true).
The Activity can then either send the "cancel" Intent or just call stopService().
In exchange for the ability to cancel the background work, the Service takes on the following responsibilities:
The AsyncTask doInBackground() will have to gracefully handle InterruptedException and/or periodically check for Thread.interrupted(), and return "early".
The Service will have to ensure that stopSelf() is called (maybe in AsyncTask onPostExecute/onCancelled).
As #budius already mentioned in his comment, you should set a boolean on the Service when you click that button:
// your Activity.java
public boolean onClick() {
//...
mService.performTasks = false;
mService.stopSelf();
}
And in your Intent handling, before you do the important task of committing/sending the intent information, just use that boolean:
// your Service.java
public boolean performTasks = true;
protected void onHandleIntent(Intent intent) {
Bundle intentInfo = intent.getBundle();
if (this.performTasks) {
// Then handle the intent...
}
}
Otherwise, the Service will do it's task of processing that Intent. That's how it was meant to be used,
because I can't quite see how you could solve it otherwise if you look at the core code.
Here is some sample code to start/stop Service
To start,
Intent GPSService = new Intent(context, TrackGPS.class);
context.startService(GPSService);
To stop,
context.stopService(GPSService);
context.stopService(GPSService);
i have created one intent service. Now I want to stop that service from activity how to stop that service? My code is:
MyActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
Intent intent = new Intent(this, myService.class);
intent.putExtra("myHand", new Messenger(this.myHand));
startService(intent);
}
myService.java
public class myService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
String signal = intent.getAction();
if (signal != null && signal.equals("stop")) {
stopSelf();
} else {
t.schedule(new TimerTask() {System.out.println("print")}, 0, 10000);
}
}
}
to stop service on click of button
Intent in = new Intent(this, myService.class);
in.setAction("stop");
stopService(in);
can anybody help me to stop service?
From the docs for IntentService
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
In other words, you don't have to stop an IntentService - it will terminate itself when it has no more work to do.
EDIT:
Looking back at your code, it seems you don't wan't to stop the IntentService you want to stop the TimerTask???
t.schedule(new TimerTask() {System.out.println("print")}, 0, 10000);
I don't know what t is but I'm guessing it's a Timer. If that's the case it will be running with its own Thread and attempting to terminate the IntentService is pointless - kill the Timer instead.
Also, why are you using an IntentService to create any type of object which maintains its own thread of execution?
Now I want to stop that service from activity how to stop that
service?
IntentService stops itself, you shouldn't, you can't call stopSelf().
When all requests have been handled, the IntentService stops itself.
From what I know, IntentHandler creates a separate new thread, does its work, and kills itself.
So I don't think you need to explicitly stop it from an activity.
I've built a service that uses startForeground() to stay alive, but I need to use binding to connect it to my activities.
It turns out that even if the service is running in the foreground, it's still killed when all activities unbind from it. How can I keep the service alive, even when no activities are bound to it?
I'm a bit surprised this works, but you can actually call startService() from the service you're starting. This still works if onStartCommand() is not implemented; just make sure that you call stopSelf() to clean up at some other point.
An example service:
public class ForegroundService extends Service {
public static final int START = 1;
public static final int STOP = 2;
final Messenger messenger = new Messenger( new IncomingHandler() );
#Override
public IBinder onBind( Intent intent ){
return messenger.getBinder();
}
private Notification makeNotification(){
// build your foreground notification here
}
class IncomingHandler extends Handler {
#Override
public void handleMessage( Message msg ){
switch( msg.what ){
case START:
startService( new Intent( this, ForegroundService.class ) );
startForeground( MY_NOTIFICATION, makeNotification() );
break;
case STOP:
stopForeground( true );
stopSelf();
break;
default:
super.handleMessage( msg );
}
}
}
}