Почему Android Alarm Manager не работает, если время запуска установлено с помощью объекта Date? - PullRequest
0 голосов
/ 24 февраля 2019

Я сталкиваюсь с этой проблемой уже несколько дней и не могу найти объяснения:

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

Поэтому я использую диспетчер тревог, передавая время срабатывания с setExact().Дело в том, что если я устанавливаю время «вручную», что означает использование calendar.set(2019 ,1 ,24 ,15 , 30), то все работает нормально.

Теперь, когда я пытаюсь установить время запуска, используя объект даты, например, calendar.setTime(myDate), уведомление не отправляется в указанное время, а отправляется, когда приложение снова открывается и время уже прошло.

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

Вот мой код:

public void sendNotification() {
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    setProgramFavorites();
    Calendar triggerTime = Calendar.getInstance();
    for (IProgram program : mFavoriteProgramItems) {
        triggerTime.setTime(program.getProgramStart());
        //triggerTime.set(2019, 1, 24, 15, 20); -> this is working just fine
            Intent intent = new Intent(this, NotificationReceiver.class);
            intent.putExtra("Program", program.getProgramName());
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime.getTimeInMillis(), pendingIntent);
        }
    }
}

Вот как форматируется дата:

 public static Date parseDateTimeFromString(String value, String pattern) {
    Date date = null;
    //Convert string with given pattern into LocalDate
    try {
        date = new SimpleDateFormat(pattern).parse(value);
    } catch (ParseException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return date;
}

, который используется в другом классе, как этот:

@Override
public Date getProgramStart() {
     return DateFormatter.parseDateTimeFromString(programStartDate, "yyyy-MM-dd HH:mm:ss");
}

это мой IntentService:

public class NotificationService extends IntentService {

private NotificationManager mNotificationManager;
private NotificationCompat.Builder mBuilder;


public NotificationService() {
    super("NotificationService");
}

/**
 * this method creates the notification which is send if one of the favorite program items is about to start
 * @param intent
 */
@Override
protected void onHandleIntent(Intent intent) {

    String programTitle = intent.getStringExtra("Program");
    Intent notificationIntent = new Intent(this, ABaseActivity.class);
    //tracking stuff
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    stackBuilder.addParentStack(MainActivity.class);
    stackBuilder.addNextIntent(notificationIntent);

    PendingIntent pendingIntent = stackBuilder.getPendingIntent(100, PendingIntent.FLAG_UPDATE_CURRENT);
    createNotificationChannel(this);

    mBuilder = new NotificationCompat.Builder(this, "reminder_ID");

    //configure the notification appearance
    mBuilder.setContentTitle("Deine favorisierte Veranstaltung beginnt in Kürze")
            .setContentText(programTitle)
            .setSmallIcon(R.drawable.ic_menu_my_program)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build();
    mNotificationManager.notify(0, mBuilder.build());
}

/**
 * create a notification channel for devices with api level 28 or higher
 */
private void createNotificationChannel(Context context) {
    mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = "reminder_ID";

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Reminder Notifications", NotificationManager.IMPORTANCE_DEFAULT);
        // Configure the notification channel
        notificationChannel.setDescription("Reminder for favorite program items");
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.GREEN);
        notificationChannel.setVibrationPattern(new long[]{0, 500, 500});
        notificationChannel.enableVibration(true);
        mNotificationManager.createNotificationChannel(notificationChannel);
    }
}
}

мой BroadcastReciever:

public class NotificationReceiver extends BroadcastReceiver {

public NotificationReceiver() {}

@Override
public void onReceive(Context context, Intent intent) {
    //pass the program title to the notification service
    String title = intent.getStringExtra("Program");
    Intent serviceIntent = new Intent(context, NotificationService.class);
    serviceIntent.putExtra("Program", title);
    context.startService(serviceIntent);
}
}

и манифест Android:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.swtp.ak18c.eventapp">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".ui.activity.MainActivity"
        android:configChanges="orientation|screenSize|keyboardHidden">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ui.activity.EventActivity"
        android:configChanges="orientation|screenSize|keyboardHidden"
        android:parentActivityName=".ui.activity.MainActivity">

    </activity>
    <receiver android:name=".logic.receiver.NotificationReceiver"
        android:exported="false"
        android:enabled="true">
    </receiver>
    <service android:name=".logic.service.NotificationService"
        android:enabled="true">
    </service>

</application>

Я напечатал значения год, месяц, день, час и минуты объекта даты, который я использовал, и они были точно такими, как ожидалось.Что я делаю не так?

...