Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StartForeground for IntentService

I have an IntentService and I want to make it sticky with an ongoing notification. The problem is that the notification appears and then disappears immediately. The service continues to run. How should I use startForeground() in an IntentService?

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    Notification notification = new Notification(R.drawable.marker, "Notification service is running",
            System.currentTimeMillis());
    Intent notificationIntent = new Intent(this, DashboardActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
        Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.setLatestEventInfo(this, "App",
            "Notification service is running", pendingIntent);
    notification.flags|=Notification.FLAG_NO_CLEAR;
    startForeground(1337, notification);
    return START_STICKY;
}

@Override
protected void onHandleIntent(Intent intent) {

    String id = intent.getStringExtra(ID);
    WebSocketConnectConfig config = new WebSocketConnectConfig();
    try {
        config.setUrl(new URI("ws://" + App.NET_ADDRESS
                + "/App/socket?id="+id));
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    ws = SimpleSocketFactory.create(config, this);
    ws.open();
}

Thanks

like image 229
Matroska Avatar asked Mar 29 '12 17:03

Matroska


1 Answers

As documentation for IntentService states:

...the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

So, I suppose the problem, is that your service is out of work after onHandleIntent() is finished. Hence, service stops itself and notification is dissmissed. So, concept of IntentService is probably not the best case for your task.


As question's title is "StartForeground for IntentService", I would like to clarify some things:

It's really simple to make your IntentService to run in foreground (see code below), but for sure you need to consider several things:

  • Don't run service in foreground if it takes a few seconds only - that might bug your users. Imagine you run short tasks periodically - that will cause notification to appear and disappear - uhhhh*

  • You might need to make your service capable to keep device awake (but that's another story, which is covered pretty well on stackoverflow)*

  • If you queued up multiple Intents to your IntentService the below code will end up showing/hiding notification. (So there might be better solution for your case - as @CommonsWare suggests to extend Service and do everything yourself, however would like to mention - there is nothing in javadoc for IntentService saying that it works only a few seconds - it works as long as it has to do something.)


public class ForegroundService extends IntentService {

    private static final String TAG = "FrgrndSrv";

    public ForegroundService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        Notification.Builder builder = new Notification.Builder(getBaseContext())
                .setSmallIcon(R.drawable.ic_foreground_service)
                .setTicker("Your Ticker") // use something from something from R.string
                .setContentTitle("Your content title") // use something from something from
                .setContentText("Your content text") // use something from something from
                .setProgress(0, 0, true); // display indeterminate progress

        startForeground(1, builder.build());
        try {
            doIntesiveWork();
        } finally {
            stopForeground(true);
        }
    }

    protected void doIntesiveWork() {
        // Below should be your logic that takes lots of time
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
like image 97
GregoryK Avatar answered Nov 13 '22 21:11

GregoryK