ForegroundService на Android Oreo убит

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

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

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

public class MyForegroundService extends Service {

    private static String TAG = MyForegroundService.class.getSimpleName();

    private static final String CHANNEL_ID = "channel_01";
    private static final int NOTIFICATION_ID = 12345678;

    private NotificationManager mNotificationManager;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public MyForegroundService() {
        super();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");

        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        // Android O requires a Notification Channel.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.app_name);

            // Create the channel for the notification
            NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);

            // Set the Notification Channel for the Notification Manager.
            mNotificationManager.createNotificationChannel(mChannel);
        }

        startForeground(NOTIFICATION_ID, getNotification());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");

        stopForeground(true);
    }

    private Notification getNotification() {

        // Get the application name from the Settings
        String appName = PrefApp.getSettings(getApplicationContext()).getAppConfigs().getAppName();
        String applicationKey = PrefApp.getSettings(getApplicationContext()).getAppConfigs().getAppKey();

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setContentTitle(appName)
                .setContentText("Services are running")
                .setOngoing(true)
                .setPriority(Notification.PRIORITY_HIGH)
                .setSmallIcon(R.mipmap.ic_notification)
                .setWhen(System.currentTimeMillis());

        // Set the Channel ID for Android O.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(CHANNEL_ID); // Channel ID
        }

        return builder.build();
    }
}

Я запускаю и останавливаю указанную выше службу, используя указанные ниже функции.

public void startMyForegroundService() {
    Log.d(TAG, "Start Foreground Service");

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(new Intent(getApplicationContext(), MyForegroundService.class));
    } else {
        startService(new Intent(getApplicationContext(), MyForegroundService.class));
    }
}

public void stopMyForegroundService() {
    Log.d(TAG, "Stop Foreground Service");
    stopService(new Intent(getApplicationContext(), MyForegroundService.class));
}

Я тестирую вышеуказанный сервис, и по какой-то причине он прекращается примерно через 30 минут после запуска. Может ли кто-нибудь сказать мне, что я делаю что-то не так, или, возможно, помочь мне найти решение, которое может сработать для меня?

Примечание: я следил за этим руководство и также тестировал их приложение, но оно все еще не работает. Сервис убивается через какое-то время.

В основном моя цель - реализовать службу, которая может работать в фоновом режиме (даже когда приложение закрыто) и получать обновления местоположения каждую минуту.

Его убивают, только если вы не использую устройство в течение 30 минут? Возможно, Дремать мешает работе вашей службы и вызывает неожиданный сбой. Есть ли соответствующий логарифм с момента смерти приложения?

greeble31 10.10.2018 05:45

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

Tonio Galea 10.10.2018 08:36

«... logcat очищается автоматически ...» Сначала я решил бы эту проблему. logcat нужен, чтобы помочь вам понять, что произошло, а не уничтожать информацию, когда она вам больше всего нужна. Рассмотрите возможность настройки фильтров на панели logcat Android Studio, чтобы вы могли видеть все журналы.

greeble31 10.10.2018 15:55
0
3
815
1

Ответы 1

Вы можете использовать диспетчер заданий firebase для фоновой службы.

Код: Добавьте эти зависимости:

implementation 'com.firebase:firebase-jobdispatcher:0.8.5'

public class MyJobService extends JobService
{
    private static final String TAG = MyJobService.class.getSimpleName();

    @Override
    public boolean onStartJob(JobParameters job)
    {
        Log.e(TAG, "onStartJob: my job service class is called.");
        // enter the task you want to perform.
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters job)
    {
        return false;
    }
}

Создайте задание в действии, вы делаете это так же, как раньше для фоновых служб.

/**
 * 2018 September 27 - Thursday - 06:36 PM
 * create job method
 *
 * this method will create job
**/
private static Job createJob(FirebaseJobDispatcher dispatcher)
{
    return dispatcher.newJobBuilder()
            //persist the task across boots
            .setLifetime(Lifetime.FOREVER)
            //.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
            //call this service when the criteria are met.
            .setService(MyJobService.class)
            //unique id of the task
            .setTag("TAGOFTHEJOB")
            //don't overwrite an existing job with the same tag
            .setReplaceCurrent(false)
            // We are mentioning that the job is periodic.
            .setRecurring(true)
            // Run every 30 min from now. You can modify it to your use.
            .setTrigger(Trigger.executionWindow(1800, 1800))
            // retry with exponential backoff
            .setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
            //.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
            //Run this job only when the network is available.
            .setConstraints(Constraint.ON_ANY_NETWORK)
            .build();
}

/**
 * 2018 September 27 - Thursday - 06:42 PM
 * cancel job method
 *
 * this method will cancel the job USE THIS WHEN YOU DON'T WANT TO USE THE SERVICE ANYMORE.
**/
private void cancelJob(Context context)
{
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    //Cancel all the jobs for this package
    dispatcher.cancelAll();
    // Cancel the job for this tag
    dispatcher.cancel("TAGOFTHEJOB");
}

это также сработает на телефонах Android любого SDK в режиме ожидания?

Phil 12.04.2020 16:38

Другие вопросы по теме