Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android IntentService update loop

My intention is to have download service created when the app first runs and checks for update every 24 hours. I originally had everything running my main activity but it seems to much to run everything on one thread and one class. So this is my attempt to move it to another class and into service. It suppose to run and check for an update ever 24 hours and if there is no internet try again in 4 hours. I specifically want to involve any recursive problems, having two or three same services checking update, just one every 24 hours. But having problem with integrating my code into service, what am I doing wrong?

public class DownloadService extends IntentService {

// TODO 0 - Define your Download Service as Android component in
// AndroidManifest.xml
private int result = Activity.RESULT_CANCELED;

public DownloadService() {
    super("DownloadService");
}

// Will be called asynchronously be Android
@Override
protected void onHandleIntent(Intent intent) {

    private final Runnable mUpdateUi = new Runnable(){
        public void run(){
            check();
        }

    };

    private void start(){
       new Thread(
            new Runnable(){
                public void run(){
                    Log.d(TAG, "inside start");
                    Looper.prepare();
                    mHandler = new Handler();
                    check();
                    Looper.loop();
                }
            }
        ).run();
    }


    private void check(){
        if (isNetworkAvailable()== true){
            try {
                new checkupdate().execute();
                delayTime = 86400000;
                Toast.makeText(DownloadService.this, "Daily update check!", Toast.LENGTH_SHORT).show();
            } 
            catch (IOException e) {
                e.printStackTrace();
                delayTime = 21600000;
            }
        }else{
            delayTime = 21600000;
            Toast.makeText(DownloadService.this, "No internet for Daily update check, try again in little!", Toast.LENGTH_SHORT).show();
        }
        reCheck();
    }

    private void reCheck(){
        mHandler.postDelayed(mUpdateUi, delayTime);
    }

}
like image 785
MAXGEN Avatar asked Jun 28 '26 02:06

MAXGEN


1 Answers

IntentService already handles setting up a worker thread and queue, and termination when the queue is empty. Which makes it a very good candidate for something like a download service to manage the actual work of downloading data, but not really a great candidate for a time scheduler.

I'd suggest using an AlarmManager to schedule your work instead. What you want is to trigger an Intent to start your DownloadService, by sending it intent with an Action indicating what to do.

Note also that if you want to cancel an IntentService with an Action, you will need to implement onStartCommand in addition to the usual onHandleIntent, so that you can respond to the action immediately -- you cannot do this from onHandleIntent, since the intent won't be sent to that until the current task in the queue is completed. Here's a quick example:

public class DownloadService extends IntentService {

    private static final String TAG = "DownloadService";

    ////////////////////////////////////////////////////////////////////////
    // Actions

    public static final String ACTION_CANCEL   = "package.name.DownloadService.action.CANCEL";
    public static final String ACTION_DOWNLOAD = "package.name.DownloadService.action.DOWNLOAD";

    ////////////////////////////////////////////////////////////////////////
    // Broadcasts

    public static final String BROADCAST_DOWNLOADED = "package.name.DownloadService.broadcast.DOWNLOADED";
    public static final String BROADCAST_ERROR      = "package.name.DownloadService.broadcast.ERROR";

    ////////////////////////////////////////////////////////////////////////
    // Extras

    public static final String MESSAGE = "package.name.DownloadService.extra.MESSAGE";
    // etc.

    private boolean isCancelled;

    // usual stuff omitted

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent != null) {
            String action = intent.getAction();
            Log.v(TAG, "onStartCommand() - action: "+action);
            if(ACTION_CANCEL.equals(action)) {

                isCancelled = true;

                // insert code here to signal any objects to cancel
                // their work, etc.

                stopSelf();
            }
        }

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

    @Override
    protected void onHandleIntent(Intent intent) {

        if(intent != null) {
            final String action = intent.getAction();
            Log.v(TAG, "onHandleIntent() - action: "+action);
            if(ACTION_DOWNLOAD.equals(action)) {
                handleDownloading(intent);
            }
            else if(ACTION_CANCEL.equals(action)) {
                // nothing to do here, handled in onStartCommand
            }
        }
    }

    ////////////////////////////////////////////////////////////////////

    private void handleDownloading(Intent intent) {

        // get stuff you need from the intent using intent.getStringExtra(), etc.

        if(!isCancelled) {
            // do downloading, call broadcastDownloaded() when done
        }
        else {
            // stop work, send broadcast to report cancellation, etc.
        }
    }

    // send a broadcast to a BroadcastReceiver (e.g. in your activity)
    // to report that the download completed
    private void broadcastDownloaded() {
        Log.v(TAG, "broadcastDownloaded()");
        Intent broadcastIntent = new Intent();
        if (broadcastIntent != null) {
            broadcastIntent.setAction(BROADCAST_DOWNLOADED);
            broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
            sendBroadcast(broadcastIntent);
        }
    }

    private void broadcastError(String message) {
        Log.v(TAG, "broadcastError(), message: "+message);
        Intent broadcastIntent = new Intent();
        if (broadcastIntent != null) {
            broadcastIntent.setAction(BROADCAST_ERROR);
            broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
            if(message != null) {
                broadcastIntent.putExtra(MESSAGE, message);
            }
            sendBroadcast(broadcastIntent);
        }
    }
}
like image 70
Lorne Laliberte Avatar answered Jun 30 '26 16:06

Lorne Laliberte



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!