После закрытия приложения перестает работать Service
Я создал сервис и он отлично отрабатывает как при запущенном так и при выключенном приложении. Но потом я узнал что он блокирует activity, так как отрабатывает в основном потоке. После запуска его в новом потоке он перестал работать после закрытия приложения. Вот код моего сервиса:
public class InetConnectionService extends Service {
final String channelId = "CHANNEL_ID";
final int id = 1;
NotificationManager notificationManager;
Intent intent;
PendingIntent pendingIntent;
public InetConnectionService() {
}
@Override
public void onCreate() {
super.onCreate();
notificationManager =
(NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
intent = new Intent(getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (hasConnection(getApplicationContext())) {
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(getApplicationContext(), channelId)
.setAutoCancel(false)
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent)
.setContentTitle("title")
.setContentText("text")
.setPriority(PRIORITY_HIGH);
createChannelIfNeeded(notificationManager);
notificationManager.notify(id, notificationBuilder.build());
break;
}
}
stopSelf();
}
}).start();
super.onStartCommand(intent, flags, startId);
return Service.START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
public boolean hasConnection(final Context context) {//проверяет подключение к интернету
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
networkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
public void createChannelIfNeeded(NotificationManager manager) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, channelId, NotificationManager.IMPORTANCE_DEFAULT);
manager.createNotificationChannel(channel);
}
}
Ответы (1 шт):
Автор решения: Olmicron
→ Ссылка
- Сервис может работать в том же потоке что и активность - и это в большинстве случаев лучший вариант, особенно если нужен доступ к данным в/из активности. Если запустить в фоне - придётся делать свой транспорт. Но в любом случае сервис остановится при завершении активности (об этом далее).
- Сервис не зависит от работы активности. Есть только одно большое НО. Сервис не может работать (при отсутствии активности) в фоне, без вывода уведомления. Т.е. если активность закрыта, у вас есть 5-10 секунд, чтобы показать пользователю уведомление о работающем сервисе. И такое уведомление будет висеть постоянно, пока работает сервис. Т.к. "пользователь должен знать, что в фоне работает сервис".
- Есть возможность запросить работу в фоне у пользователя и попробовать запускать сервис без уведомления - но эта штука не везде работает и надеяться не стоит. А если и сработает - то уведомление всё равно будет показано, но уже в качестве оповещения системы о работающем приложении в фоне.
- Системные приложения могут использовать сервисы никак не уведомляя пользователя об этом. Но это уже другой случай...
Собственно для привязки сервиса к уведомлению нужно сделать примерно следующее:
/**
* Набросал быстро код, он может да же и не работать, но смысл будет понятен
*/
NotificationManager notificationManager = (NotificationManager) service.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(service, MainActivity.class);
// Тут устанавливаем флаги в интент, добавляем какие нужно данные и т.п.
PendingIntent pendingIntent = PendingIntent.getActivity(service, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder notificationBuilder = new Notification.Builder(service);
notificationBuilder.setSmallIcon(R.drawable.status_bar_icon);
notificationBuilder.setContentIntent(pendingIntent);
// Далее тут ещё нужно настроить вид уведомления (ну там текст, картинки и т.п.)
// Теперь показываем пользователю уведомление привязанное к сервису:
service.startForeground(NOTIFICATION_ID, notificationBuilder.build());
// После всего этого сервис будет спокойно работать в не зависимости от активности