Foreground Service не работает постоянно
В моем приложении я использую сервис переднего плана, который должен работать постоянно. Иногда служба переднего плана останавливается. При каких обстоятельствах ОС может убить мой сервис (это происходит, даже если памяти достаточно, батарея полностью заряжена, телефон заряжается)?
Вот как мой код выглядит до сих пор:
public class ServiceTest extends Service {
public static Thread serverThread = null;
public Context context = this;
public ServiceTest(Context context) {
super();
this.context = context;
}
public ServiceTest() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (this.serverThread == null) {
this.serverThread = new Thread(new ThreadTest());
this.serverThread.start();
}
return START_STICKY;
}
private class ThreadTest implements Runnable {
@Override
public void run() {
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle("Notification title")
.setContentText("Notification text")
.setContentIntent(pendingIntent)
.setAutoCancel(false)
.setSmallIcon(R.drawable.android)
.setOngoing(true).build();
startForeground(101, notification);
while(true){
//work to do
}
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2 ответа
Там нет ни одного...
Many problems
в вашем коде... Вы можете получить "0 ошибок", так как это синтаксически правильно, но этоandroidicaly
неправильно, твойbasics
бедные, чтениеandroid documentation
а такжеimplementation
очень плохой Android никогда не запускает очень плохие вещи...
Проблема: 1
Знаете ли вы, что за услугу обычно следует override
onCreate
, onStartCommand
, onBind
, onDestroy
методы....?
Я не вижу на Дестрой там....!!
Проблема: 2
Вы знаете, как уведомить...? Ваш onStartCommand
реализация снова не имеет смысла.
ОСТАВАЙТЕСЬ ПУСТОЙ, ТОЛЬКО ВЕРНУТЬСЯ
Проблема: 3
Как вы ожидаете, чтобы запустить это в фоновом режиме выполнения...? Уведомить Android первым, сделав уведомление в oncreate
только и с startforeground
если нужно...
Я не вижу этого там.... вы пытаетесь сделать это в
onstartcommand
и опять это очень плохо...
Хорошо... взгляните на рабочий код ниже:
public class RunnerService extends Service
{
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "1";
public RunnerService() { }
@Override
public void onCreate()
{
super.onCreate();
Log.d("RUNNER : ", "OnCreate... \n");
Bitmap IconLg = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground);
mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this, null);
mBuilder.setContentTitle("My App")
.setContentText("Always running...")
.setTicker("Always running...")
.setSmallIcon(R.drawable.ic_menu_slideshow)
.setLargeIcon(IconLg)
.setPriority(Notification.PRIORITY_HIGH)
.setVibrate(new long[] {1000})
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.setAutoCancel(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{1000});
notificationChannel.enableVibration(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
mNotifyManager.createNotificationChannel(notificationChannel);
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
startForeground(1, mBuilder.build());
}
else
{
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
mNotifyManager.notify(1, mBuilder.build());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("RUNNER : ", "\nPERFORMING....");
return START_STICKY;
}
@Override
public void onDestroy()
{
Log.d("RUNNER : ", "\nDestroyed....");
Log.d("RUNNER : ", "\nWill be created again automaticcaly....");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("NOT_YET_IMPLEMENTED");
}
}
Как проверить....???
Удалите приложение из списка последних, и вы должны увидеть в своих журналах "Performing
сообщение в logcat
...
В каких условиях он останавливается...?
Он никогда не останавливается (до следующей загрузки..!!)... Да, он останавливается, когда пользователь принудительно останавливает приложение. И редко, если система обнаруживает, что у нее очень мало ресурсов.... это очень редкое условие, кажется, происходит, так как Android значительно улучшился с течением времени....
Как это начать....?????
Где бы это ни было mainactivity
или из receiver
или из любого class
:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
context.startForegroundService(new Intent(context, RunnerService.class));
}
else
{
context.startService(new Intent(context, RunnerService.class));
}
Как проверить запущен сервис или нет....?
Просто не..... Даже если вы запускаете службу, сколько раз вы хотите.... Если она уже запущена... тогда она не будет запускаться снова.... Если не работает, то... начну...!!
Критика, высказанная в выбранном ответе, неразумна, если службе необходимо намерение работать.
В более поздних версиях Android система приостанавливает любую службу переднего плана, пока устройство заблокировано, чтобы минимизировать энергопотребление , даже если она возвращает START_STICKY. Итак, чтобы сделать задачу переднего плана постоянно, требуется wakelock.
Вот что описывает документация по Android:
Чтобы не разрядить аккумулятор, Android-устройство, которое не используется, быстро засыпает. Однако бывают случаи, когда приложению необходимо разбудить экран или ЦП и поддерживать его в активном состоянии, чтобы выполнить некоторую работу.
Чтобы служба переднего плана работала постоянно, приобретите
wakeLock
изнутри
onCreate()
.
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyApp::MyWakelockTag");
wakeLock.acquire();
Для получения дополнительной информации ознакомьтесь с официальной документацией Android .