Является ли служба переднего плана единственным вариантом запуска одного метода?

У меня есть приложение, которое я создал, и я хочу, чтобы оно запускало один метод, когда время достигает 00:00 (в основном на следующий день).

Для контекста мое приложение сохраняет CSV-файл за каждый день. Я исследовал, как заставить приложения работать в фоновом режиме, и я нашел именно службы переднего плана, но мне кажется, что это слишком излишество, поскольку мое приложение будет запускать только один метод один раз в день (метод в вопрос в том, что создается файл csv).

Службы переднего плана — мой единственный вариант или есть другие способы сделать это?

В Руководствах для разработчиков Android могут быть полезные идеи например WorkManager или JobScheduler возможно(?)

Markus Kauppinen 06.05.2024 14:25

Я посмотрю на это. Спасибо!

Akira 06.05.2024 15:33

Не забудьте сбросить будильник после загрузки: Developer.android.com/reference/android/content/…

dominicoder 08.05.2024 09:43
0
3
106
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Руководство по выбору обработчика фоновых задач

Обычно вы предпочитаете использовать AlarmManager.

Intent intent = new Intent(getApplicationContext(), YourBroadCastReceiver.class);
    final PendingIntent pIntent = PendingIntent.getBroadcast(this, 0,
            intent, PendingIntent.FLAG_IMMUTABLE);
    long firstMillis = System.currentTimeMillis(); // alarm is set right away
    AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
            AlarmManager.INTERVAL_DAY, pIntent); //will call your YourBroadCastReceiver class once a day

ВашBroadCastReceiver.java

public class YourBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

  //your csv logic

    }
}

Вам также необходимо прописать YourBroadCastReceiver в манифесте внутри тега <application>.

<receiver
        android:name = ".YourBroadCastReceiver"
        android:enabled = "true"
        android:exported = "true" />

Нужно ли мне поместить первую часть предоставленного вами кода в мой класс MainActivity.java? Точнее, поместите его после строки super.onCreate()?

Akira 06.05.2024 15:31

Да, логично, что это гарантирует, что код запускается только один раз, в зависимости от того, как используется приложение.

Prajjwal Srivastav 06.05.2024 15:43
Ответ принят как подходящий

Для задач такого типа, которые выполняются в определенные даты или время или выполняются периодически в зависимости от даты или времени. Рекомендуется использовать AlarmManager. Вот реализация

Котлин

  1. Создайте класс широковещательного приемника, который будет запускать определенную логику, которую вы хотите запустить в определенную дату или время.
class DailyTaskBroadcastReceiver : BroadcastReceiver() {
 
    override fun onReceive(context: Context, intent: Intent) {
      
        yourTask()
    }
}
  1. В классе Application напишите метод, который запускает сигнал тревоги только один раз, и убедитесь, что его не следует перепланировать при каждом запуске приложения.
class MyApplication: Application() {

  override fun onCreate() {
        super.onCreate()
        
        // Initiate your task
        scheduleDailyTask(this)
    }

  fun scheduleDailyTask(context: Context) {
    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val intent = Intent(context, DailyTaskBroadcastReceiver::class.java)
    val pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
            PendingIntent.FLAG_NO_CREATE or PendingIntent.FLAG_IMMUTABLE)

    // If the alarm is not already set, schedule it
    if (pendingIntent == null) {
        val calendar = Calendar.getInstance().apply {
            timeInMillis = System.currentTimeMillis()
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            add(Calendar.DAY_OF_YEAR, 1) // Set to the next day
        }

        // Set the alarm to trigger at midnight every day
        alarmManager.setRepeating(
            AlarmManager.RTC_WAKEUP,
            calendar.timeInMillis,
            AlarmManager.INTERVAL_DAY,
            PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        )
    }
}

ДЖАВА

public class DailyTaskBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        yourTask();
    }
    
}


public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        
        // Initiate your task
        scheduleDailyTask(this);
    }

    public void scheduleDailyTask(Context context) {
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, DailyTaskBroadcastReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
                PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE);

        // If the alarm is not already set, schedule it
        if (pendingIntent == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.add(Calendar.DAY_OF_YEAR, 1); // Set to the next day

            // Set the alarm to trigger at midnight every day
            alarmManager.setRepeating(
                    AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(),
                    AlarmManager.INTERVAL_DAY,
                    PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
            );
        }
    }
}
  1. Не забудьте добавить приемник Broadcast в файл Manifest.xml.
<receiver android:name = ".DailyTaskBroadcastReceiver" />

Тестирование

Чтобы проверить, вы можете просто обновлять свой scheduleDailyTask(), чтобы он срабатывал каждые 1 минуту:

    // Alarm Schedule
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.MINUTE, 1); // Set to trigger after 1 minute initially

А также установите повторение

    // Set the alarm to repeat every minute
    alarmManager.setRepeating(
            AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(),
            60 * 1000, // 60 seconds * 1000 milliseconds
            pendingIntent
    );

   // Try printing the Log in the BroadcastReceiver onCreate method to verify if it is triggering after every 1 minute.

}

Примечание. Я не компилировал этот код, не забудьте добавить импорт.

Ссылка: Проверьте больше задач, связанных с Календарем.

Большое спасибо! Я попытаюсь преобразовать ваш код в его аналог Java, поскольку я пишу код на Java. Но все равно спасибо!

Akira 06.05.2024 15:26

@Akira Спасибо, кстати, я также добавил Java-версию.

Muzammal Abdul Ghafoor 06.05.2024 15:37

Спасибо Спасибо! Однако у меня есть простой вопрос: могу ли я с помощью метода onRecieve() вызывать другие функции из разных классов Java? или это не сработает, потому что весь код должен находиться внутри onRecieve()?

Akira 06.05.2024 16:20

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

Muzammal Abdul Ghafoor 06.05.2024 16:29

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

Muzammal Abdul Ghafoor 06.05.2024 16:30

Привет! У меня есть еще один вопрос, который я разместил здесь. Речь идет о коде, который вы мне дали, потому что я получил ошибку. @Muzammal_Abdul_Ghafoor stackoverflow.com/questions/78437986/….

Akira 06.05.2024 18:41

На самом деле это плохое решение. Это будильник, и это означает, что вы увидите значок часов на панели задач, а ваше приложение будет действовать как приложение будильника. Это может сбить с толку пользователей

user1209216 08.05.2024 08:34

@user1209216 user1209216 О чем ты говоришь? Использование AlarmManager не делает ваше приложение будильником, и вы не увидите значок часов на панели задач, и ваше приложение не будет действовать как приложение будильника.

dominicoder 08.05.2024 09:39

@user1209216 user1209216 ты вообще удосужился поискать информацию об AlaramManager?

Muzammal Abdul Ghafoor 08.05.2024 12:34

Да, я ошибался. Я имел в виду Календарь, а не AlarmManager.

user1209216 08.05.2024 14:11

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