blob: 08b38bbb50a708f8c30c2eae54863760b04c848a [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.support.v4.app;
import android.app.Notification;
import android.app.Service;
import android.support.annotation.IntDef;
import android.support.v4.os.BuildCompat;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Helper for accessing features in {@link android.app.Service}
* introduced after API level 9 in a backwards compatible fashion.
*/
public final class ServiceCompat {
private ServiceCompat() {
/* Hide constructor */
}
/**
* Constant to return from {@link android.app.Service#onStartCommand}: if this
* service's process is killed while it is started (after returning from
* {@link android.app.Service#onStartCommand}), then leave it in the started
* state but don't retain this delivered intent. Later the system will try to
* re-create the service. Because it is in the started state, it will
* guarantee to call {@link android.app.Service#onStartCommand} after creating
* the new service instance; if there are not any pending start commands to be
* delivered to the service, it will be called with a null intent
* object, so you must take care to check for this.
*
* <p>This mode makes sense for things that will be explicitly started
* and stopped to run for arbitrary periods of time, such as a service
* performing background music playback.
*/
public static final int START_STICKY = 1;
/**
* Flag for {@link #stopForeground(Service, int)}: if set, the notification previously provided
* to {@link Service#startForeground(int, Notification)} will be removed. Otherwise it
* will remain until a later call (to {@link Service#startForeground(int, Notification)} or
* {@link #stopForeground(Service, int)} removes it, or the service is destroyed.
*/
public static final int STOP_FOREGROUND_REMOVE = 1<<0;
/**
* Flag for {@link #stopForeground(Service, int)}: if set, the notification previously provided
* to {@link Service#startForeground(int, Notification)} will be detached from the service.
* Only makes sense when {@link #STOP_FOREGROUND_REMOVE} is <b>not</b> set -- in this case, the
* notification will remain shown, but be completely detached from the service and so no longer
* changed except through direct calls to the
* notification manager.
* <p>
* This flag will only work on
* {@link android.os.Build.VERSION_CODES#N} and later. It doesn't have any effect on earlier
* platform versions.
*/
public static final int STOP_FOREGROUND_DETACH = 1<<1;
/** @hide */
@IntDef(flag = true,
value = {
STOP_FOREGROUND_REMOVE,
STOP_FOREGROUND_DETACH
})
@Retention(RetentionPolicy.SOURCE)
public @interface StopForegroundFlags {}
interface ServiceCompatImpl {
void stopForeground(Service service, @ServiceCompat.StopForegroundFlags int flags);
}
static class BaseServiceCompatImpl implements ServiceCompat.ServiceCompatImpl {
public void stopForeground(Service service, @ServiceCompat.StopForegroundFlags int flags) {
service.stopForeground((flags & Service.STOP_FOREGROUND_REMOVE) != 0);
}
}
static class Api24ServiceCompatImpl implements ServiceCompat.ServiceCompatImpl {
public void stopForeground(Service service, @ServiceCompat.StopForegroundFlags int flags) {
ServiceCompatApi24.stopForeground(service, flags);
}
}
static final ServiceCompatImpl IMPL;
static {
if (BuildCompat.isAtLeastN()) {
IMPL = new Api24ServiceCompatImpl();
} else {
IMPL = new BaseServiceCompatImpl();
}
}
/**
* Remove the passed service from foreground state, allowing it to be killed if
* more memory is needed.
* @param flags Additional behavior options: {@link #STOP_FOREGROUND_REMOVE},
* {@link #STOP_FOREGROUND_DETACH}.
* @see Service#startForeground(int, Notification)
*/
public static void stopForeground(Service service,
@ServiceCompat.StopForegroundFlags int flags) {
IMPL.stopForeground(service, flags);
}
}