Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force stop Intent Service in progress?

I have an intent service which downloads several gigabytes of videos. I have a "Stop" button, to stop the download if accidentally hit "Start" or whatever. I know this has been asked a couple of times but with no working answer for me.

I try to call stopService(), doesn't work. That just calls IntentService.OnDestroy(). I tried to call stopSelf() inside onDestroy, doesn't work either.

I tried to have something like a flag, but onHandleIntent doesn't get called if its already running, it waits till current work is finished and executes then. And even if this would have worked, I would have to have something like a giant if statement, that sucks

Is my only option really to rewrite it to a regular Service?

//Answer

public class SyncService extends IntentService {

    boolean isCanceled;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent.hasExtra("action")) {

            // Set the canceling flag
            isCanceled= intent.getStringExtra("action").equals("cancel");

        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        // Clean up the possible queue
        if (intent.hasExtra ("action")) {
            boolean cancel = intent.getStringExtra ("action"). Equals ("cancel");
            if (cancel) {
                return;
            }
        }

        ...

        Get your inputStream from HttpUrlConnection or whatever

        ...

        while ((bytesRead = in.read(buffer)) > 0) {
            if (isCanceled) {
                isCanceled = false;
                break;
            }

            ...
        }

    }
}

And trigger it with

Intent intent = new Intent(context, SyncService.class);
intent.putExtra("action", "cancel");
context.startService(intent);
like image 812
urSus Avatar asked Apr 18 '13 22:04

urSus


People also ask

How do you stop an intent Service?

Intent Service is going to do background operation asynchronously. When user call startService() from activity, it doesn't create the instance for each request and it going to stop service after done some action in service class or else we need to stop service manually by using stopSelf().

Does intent service run in background?

IntentService. The IntentService class used to be the way for running an operation on a single background thread. IntentService runs outside the application in a background process, so the process would run even if your application is closed.

What is intent Service in Android?

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.

Why is intent Service deprecated?

Provided since Android API 3, the purpose of IntentService was to allow asynchronous tasks to be performed without blocking the main thread. The deprecation is one of a number of steps introduced starting with Android 8.0 (API 26) to limit the actions that can be performed while an app is in the background.


1 Answers

You have two separate issues, I would think:

  1. How to stop the current download

  2. How to stop queued up downloads, that should execute after the current one completes

The first one is going to have to be "something like a flag", that you check as you download the data. Otherwise, nothing is going to stop your download operation. If you are using a typical HttpUrlConnection recipe, you check that flag in your loop where you read from the HTTP InputStream and write to your FileOutputStream. You set that flag via a call to startService() with a particular Intent structure, identifying it as a "cancel" operation. You would need to override onStartCommand() in your IntentService, look at the Intent, use it to set the flag if it is the cancel Intent, or chain to the superclass for any other sort of Intent.

If you also may have other commands queued up (scenario #2), you would need to check that flag at the top of onHandleIntent() as well.

like image 199
CommonsWare Avatar answered Sep 23 '22 23:09

CommonsWare