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);
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().
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.
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.
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.
You have two separate issues, I would think:
How to stop the current download
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With