Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Services: START_STICKY does not work on Kitkat

I am using services in an application to listen for how many times the user presses his/her power button. The implementation was working fine on all devices. But when I tested the app on the Android Kitkat, I noticed something wrong.

As soon as I swipe the application away from the recents apps, the application no longer listens for the power button.

Here is the code that I am working with:

public class Receiver extends Service {

    Notification notification;
    private static final int NOTIFICATION_ID = 0;
    NotificationManager manager;
    PendingIntent toOpen;
    Intent intent;
    private BroadcastReceiver POWER_BUTTON = new Powerbuttonrecceiver();

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

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

        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(POWER_BUTTON, filter);
        startNotify();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        unregisterReceiver(POWER_BUTTON);
        dismissNotification();
        super.onDestroy();
    }

    public void startNotify(){
        manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        int icon = R.drawable.ic_launcher_drop;
        CharSequence tickerText = "Service activated";
        CharSequence tickerContent = "Service is now on. You can press your power button and the app will listen to it. Tap to turn this feature off";
        intent = new Intent(Receiver.this, Options.class);
        toOpen = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);

        notification = new NotificationCompat.Builder(getApplicationContext())
        .setContentTitle(tickerText)
        .setContentText(tickerContent)
        .setSmallIcon(icon)
        .setOngoing(true)
        .setContentIntent(toOpen)
        .build();
        manager.notify(NOTIFICATION_ID, notification);
    }

    public void dismissNotification(){
        manager.cancel(NOTIFICATION_ID);
    }

}

As one can notice I am using a notification to signify that the service is active. The thing that confuses me is that after the swipe from the recents app the notification still remains, what is inactive is the BroadcastReceiver? or is that false.

In the app's onDestroy I have not called in any functions to register or unregister as well as stop the service. Once again, this problem is only seen in Android KitKat. Please if you guys know whats happening. Do help :)

UPDATE: I also noticed with the Play Music on Kitkat, when I swipe it away from the recents app the music stops. Is this a bug on Kitkat? But the sound/mediaplayer services on SoundCloud works even when swiped away from the recents app.

UPDATE: Logged as Issue 63618 on android issue tracker. Read issue comments for more details.

like image 255
Rakeeb Rajbhandari Avatar asked Dec 19 '13 04:12

Rakeeb Rajbhandari


2 Answers

Seems that this is a bug present in Android 4.4, got around it with the following:

@Override
public void onTaskRemoved(Intent rootIntent) {
    // TODO Auto-generated method stub
    Intent restartService = new Intent(getApplicationContext(),
            this.getClass());
    restartService.setPackage(getPackageName());
    PendingIntent restartServicePI = PendingIntent.getService(
            getApplicationContext(), 1, restartService,
            PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +1000, restartServicePI);

}

So this is a method that is overridden in the Service class itself. The reason that I am using the AlarmManager is so that Kitkat does not kill my service.

like image 121
Rakeeb Rajbhandari Avatar answered Oct 18 '22 22:10

Rakeeb Rajbhandari


I have this solution that works perfectly.

@Override
public void onDestroy() {
     startService(new Intent(yourcontext, YourService.class));
}
like image 34
someguy234 Avatar answered Oct 18 '22 23:10

someguy234