Услуги Android: START_STICKY не работает в Kitkat

Я использую службы в приложении для прослушивания того, сколько раз пользователь нажимает свою кнопку питания. Реализация отлично работала на всех устройствах. Но когда я тестировал приложение на Android Kitkat, я заметил что-то не так.

Как только я удаляю приложение из приложений recents, приложение больше не слушает кнопку питания.

Вот код, с которым я работаю:

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);
    }

}

Как можно заметить, я использую уведомление, чтобы показать, что служба активна. Меня смущает то, что после прокрутки из приложения recents уведомление все еще остается, что неактивно - это BroadcastReceiver? или это ложь.

В приложении onDestroy я не вызывал никаких функций для регистрации или отмены регистрации, а также для остановки службы. Еще раз эта проблема наблюдается только в Android KitKat. Пожалуйста, если вы, ребята, знаете, что происходит. Помогите:)

ОБНОВЛЕНИЕ: Я также заметил с помощью Play Music в Kitkat, когда я удаляю его из приложения recents, музыка останавливается. Это ошибка в Kitkat? Но службы sound/mediaplayer на SoundCloud работают даже тогда, когда они удалены от приложения recents.

UPDATE: Записан, как Проблема 63618 в трее. Подробнее читайте в комментариях к проблеме.

Ответы

Ответ 1

Кажется, что это ошибка, присутствующая в Android 4.4, обойти ее со следующим:

@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);

}

Итак, это метод, который переопределяется в самом классе Service. Причина, по которой я использую AlarmManager, заключается в том, что Kitkat не убивает мою службу.

Ответ 2

У меня есть это решение, которое отлично работает.

@Override
public void onDestroy() {
     startService(new Intent(yourcontext, YourService.class));
}

Ответ 4

попробуйте мое решение: this

этот трюк перезапустит вашу службу каждый раз, когда пользователь закроет службу из обоих диспетчеров задач и закроет настройки, надеюсь, это тоже поможет вам.

Ответ 5

Если вы не можете перезапустить службу, обратитесь к аламу, чтобы запустить этот ресивер,

Манифест есть,

         <service
            android:name=".BackgroundService"
            android:description="@string/app_name"
            android:enabled="true"
            android:label="Notification" />
        <receiver android:name="AlarmReceiver">
            <intent-filter>
                <action android:name="REFRESH_THIS" />
            </intent-filter>
        </receiver>

IN Основной манипулятор запуска активации таким образом,

String alarm = Context.ALARM_SERVICE;
        AlarmManager am = (AlarmManager) getSystemService(alarm);

        Intent intent = new Intent("REFRESH_THIS");
        PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);

        int type = AlarmManager.RTC_WAKEUP;
        long interval = 1000 * 50;

        am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);

это вызовет reciver и reciver,

public class AlarmReceiver extends BroadcastReceiver {
    Context context;

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;

        System.out.println("Alarma Reciver Called");

        if (isMyServiceRunning(this.context, BackgroundService.class)) {
            System.out.println("alredy running no need to start again");
        } else {
            Intent background = new Intent(context, BackgroundService.class);
            context.startService(background);
        }
    }

    public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        if (services != null) {
            for (int i = 0; i < services.size(); i++) {
                if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
                    return true;
                }
            }
        }
        return false;
    }
}

И этот релаксор Alaram называет один раз, когда приложение Android открыто и когда приложение закрыто. SO служба похожа на это,

public class BackgroundService extends Service {
    private String LOG_TAG = null;

    @Override
    public void onCreate() {
        super.onCreate();
        LOG_TAG = "app_name";
        Log.i(LOG_TAG, "service created");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(LOG_TAG, "In onStartCommand");
        //ur actual code
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Wont be called as service is not bound
        Log.i(LOG_TAG, "In onBind");
        return null;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Log.i(LOG_TAG, "In onTaskRemoved");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(LOG_TAG, "In onDestroyed");
    }
}