Приложение закрывается при выключенном экране при наличии службы переднего плана

Это сложная проблема. У меня есть приложение, которое собирает данные GPS в фоновом режиме (с помощью службы переднего плана). Кроме того, я установил 3 будильника, которые должны работать в течение нескольких часов. Все это делается при наличии установленного MDM в устройстве (SOTI, если это поможет).

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

Устройство определенно не нуждается в ресурсах, так как это единственное приложение, которое разрешено MDM, и ошибки нет, так как я внедрил крашлитику, и она ничего не дает.

Для справки, поскольку я не могу публиковать много кода, я запускаю службу переднего плана, как и предполагалось (с startForegroundService), и вызываю startForeground в методе onCreate() службы. Так же у меня есть вейклок в сервисе, но это совсем не помогло.

Будильники устанавливаются с помощью alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, startDate, period, pendingIntent), но когда приложение находится в фоновом режиме, они не срабатывают. Когда я снова запускаю приложение, они сбрасываются и срабатывают.

Любая подсказка, почему мое приложение убито? Устройство, которое я использую, это Huawei Y6, если оно чем-то поможет. Я уже проверил эту ссылку и сделал все возможное, чтобы не убить мое приложение, но я неуспешный. Кроме того, я проверил, что служба переднего плана сбрасывает информацию о телефоне, и служба помечена как служба переднего плана, как и должно быть, с номером приоритета 4 (время, когда я проверял), поэтому ее не следует убивать...

Спасибо в плюс!


person misterpresid    schedule 11.09.2019    source источник


Ответы (2)


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

Постоянный сервис

person Dimitris KOutsos    schedule 11.09.2019
comment
Привет! Спасибо за ваш ответ, я уже пробовал это, но безуспешно :( Приложение все равно убивается... - person misterpresid; 11.09.2019

Вот сервис, который я использую для отслеживания GPS. Чтобы служба продолжала работать, важно, чтобы к ней было привязано уведомление. Из того, что я знаю об уведомлении, пользователь должен знать о службе, работающей в фоновом режиме.

В команде запуска создайте липкое уведомление с наивысшим приоритетом.

Надеюсь, код Kotlin в порядке:

class TrackService : Service(), LocationListener {

    private val tag = TrackService::class.java.simpleName

    companion object {
        private const val ONGOING_NOTIFICATION_ID = 3947
        const val FLAG_TICKET_RUNNING = 1
    }

    private var locationManager: LocationManager? = null
    private lateinit var notificationBuilder: NotificationCompat.Builder


    /**
     * Start command of service. Contains all starting commands needed to start the tracking
     *
     * @param intent used to call startService
     * @param flags flags used for service
     * @param startId id of service
     * @return type of service, in our case STICKY
     */
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        event = intent!!.getParcelableExtra("event")
        course = intent.getParcelableExtra("course")

        notificationBuilder = createNotificationBuilder()
        showNotification()

        return START_REDELIVER_INTENT
    }


    /**
     * Called when service is being stopped. This is where we stop all listeners and set the status
     * to "offline"
     */
    override fun onDestroy() {
        dismissNotification()

        super.onDestroy()
    }


    /**
     * Not needed for our use case
     * @param intent Intent
     * @return null
     */
    override fun onBind(intent: Intent): IBinder? = null


    /**
     * Shows the notification that makes the service more STICKY
     */
    private fun showNotification() {
        if (App.showNotificationContent())
            notificationBuilder.setContentText("Time: - | Distance: -")
        startForeground(ONGOING_NOTIFICATION_ID, notificationBuilder.build())
    }


    /**
     * Generates the notification to be shown
     *
     * @return NotificationCompat.Builder
     */

    private fun createNotificationBuilder(): NotificationCompat.Builder {
        if (pendingIntent == null) {
            val notificationIntent = Intent(this, DashboardActivity::class.java)
            notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
            notificationIntent.putExtra("ticket_flag", FLAG_TICKET_RUNNING)
            pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)

            @SuppressLint("NewApi")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val notificationChannel = NotificationChannel("channel-4", "Tracking Channel 4", NotificationManager.IMPORTANCE_LOW)
                val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                notificationManager.createNotificationChannel(notificationChannel)
                notificationChannel.setSound(null, null)
            }
        }

        return NotificationCompat.Builder(this, "channel-4")
                .setSmallIcon(R.drawable.ic_notification_orienteering)
                .setColor(ContextCompat.getColor(this, R.color.colorPrimaryDark))
                .setContentTitle(event.name + " - " + course.name)
                .setAutoCancel(false)
                .setSound(null)
                .setOngoing(true)
                .setOnlyAlertOnce(true)
                .setContentIntent(pendingIntent)
                .setPriority(NotificationCompat.PRIORITY_MAX)
    }


    /**
     * This is the method that can be called to update the Notification
     */
    private fun updateNotification(time: String, distance: String) {
        if (App.showNotificationContent()) {
            notificationBuilder.setContentText("Time: $time | Distance: $distance")
            val mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notificationBuilder.build())
        }
    }


    /**
     * Dismisses the notification
     */
    private fun dismissNotification() {
        stopForeground(true)
    }
}
person just_user    schedule 11.09.2019
comment
Привет! Спасибо за код, у меня он более-менее как у вас, но я изменил приоритет своего канала уведомлений и добавил setongoing, посмотрю, так ли это работает... Еще раз спасибо! - person misterpresid; 11.09.2019
comment
@misterpresid есть положительный результат? - person KingBryan; 25.09.2019