Dynami c менеджер тревог в полночь - PullRequest
1 голос
/ 10 июля 2020

моя средняя цель - периодически запускать задачу в полночь (00:00:00)

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

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

Я использую этот код для активации тревоги:

 public static void setTheTimeToStartBackup(Context context,String periode) {

    int DATA_FETCHER_RC = 123;
    AlarmManager mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    
    Calendar calendar = Calendar.getInstance();


    Intent intent = new Intent(context, BackUpAlarmRecevier.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, DATA_FETCHER_RC,intent, PendingIntent.FLAG_UPDATE_CURRENT);


    long interval = 0;
    switch (periode){
        case "never":
            return;
        case "daily":
            alarmStartTime.set(Calendar.HOUR_OF_DAY, 0);
            interval = AlarmManager.INTERVAL_DAY;
            break;
        case "weekly":
            alarmStartTime.set(Calendar.DAY_OF_WEEK, 1);
            interval = AlarmManager.INTERVAL_DAY*7;
            break;

        case "monthly":
            alarmStartTime.set(Calendar.WEEK_OF_MONTH, 1);
            interval = AlarmManager.INTERVAL_DAY*30;
            break;
    }

    alarmStartTime.set(Calendar.HOUR_OF_DAY, 0);
    alarmStartTime.set(Calendar.MINUTE, 0);
    alarmStartTime.set(Calendar.SECOND, 0);

    mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),interval, pendingIntent);

    Log.e("Alarm","Set for midnight");

}

это мой приемник:

public class BackUpAlarmRecevier extends BroadcastReceiver {

SharedPreferences preferences;
@Override
public void onReceive(Context context, Intent intent) {
    Log.e("BackUpAlarmReciver","Triggred");

    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG:APP");
    wl.acquire();

    sendNotification(context);// simple notification...
    Toast.makeText(context, "Alarm !!", Toast.LENGTH_LONG).show(); 
    startBackupProcess();

    wl.release();

}}

проблема в том, что задача не запускается.

, поэтому я пошел протестировать его с меньшим интервалом времени (15 минут как минимум, как я читал), поэтому я меняю свою первую функцию setTheTimeToStartBackup на это:

public static void setTheTimeToStartBackup(Context context,String periode) {

    int DATA_FETCHER_RC = 123;
    AlarmManager mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.SECOND, 55);

    Intent intent = new Intent(context, BackUpAlarmRecevier.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, DATA_FETCHER_RC,intent, PendingIntent.FLAG_UPDATE_CURRENT);

    mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);

    Log.e("Alarm","Set for midnight");

}

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

и я уже установил Receiver в своем манифесте со всеми такими разрешениями:

        <receiver android:name=".job.BackUpAlarmRecevier"
        android:enabled="true"
        android:process=":remote"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

что я делаю не так в обоих случаях? и если он сработает, этот код будет сохраняться навсегда, или мне нужно каждый раз устанавливать его снова?

спасибо :)

РЕДАКТИРОВАТЬ: я вызываю свою функцию setTheTimeToStartBackup в MainActivity.

Ответы [ 2 ]

0 голосов
/ 20 июля 2020

Я бы посоветовал немного изменить проблему. Создайте три темы на Firebase (ежедневно, еженедельно, ежемесячно). Подписывайте пользователей на соответствующие темы. Имейте функцию Firebase, которая запускается заданием CRON, которое отправляет уведомление о данных на устройство, это уведомление о данных должно планировать одноразовое задание WorkManager для обновления. Таким образом, вы можете контролировать все со стороны сервера, если телефон выключен, он все равно будет выполняться, как только он включится, и вам не нужно вручную заботиться о загрузке, завершенной с помощью диспетчера аварийных сигналов et c.

0 голосов
/ 18 июля 2020

Вы можете установить это в полночь, если вы выполнили соответствующие расчеты времени. Динамически получайте текущее время и дату, рассчитывайте, когда регистрировать трансляцию для диспетчера тревог. Настройте метод onReceive, чтобы снова установить другой будильник в 12:00.

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

Класс широковещательного приемника:

public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    System.out.println("Alarm received!! ");
    // Register alarm again here.
    }
}

Код для регистрации получателя с настраиваемым фильтром намерений.

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    AlarmManager mAlarmManager = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);


    getApplicationContext().registerReceiver(new AlarmReceiver(), new IntentFilter("AlarmAction"));
    PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, new Intent("AlarmAction"), 0);

   // Add dynamic time calculations. For testing just +100 milli.
   mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 100, broadcast);
    ;

}

Вы можете достичь желаемого с помощью фоновой службы.

...