Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Allow for repeat to specify amount of the given repeat type (Android) #2030

Merged
merged 6 commits into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ PushNotification.localNotificationSchedule({
message: "My Notification Message", // (required)
date: new Date(Date.now() + 60 * 1000), // in 60 secs
allowWhileIdle: false, // (optional) set notification to work while on doze, default: false

/* Android Only Properties */
repeatTime: 1, // (optional) Increment of configured repeateType. Check 'Repeating Notifications' section for more info.
});
```

Expand Down Expand Up @@ -409,7 +412,7 @@ import PushNotification, {Importance} from 'react-native-push-notification';

**NOTE: Without channel, notifications don't work**

In the notifications options, you must provide a channel id with `channelId: "your-channel-id"`, if the channel doesn't exist the notification might not e triggered. Once the channel is created, the channel cannot be update. Make sure your `channelId` is different if you change these options. If you have created a channel in another way, it will apply options of the channel.
In the notifications options, you must provide a channel id with `channelId: "your-channel-id"`, if the channel doesn't exist the notification might not be triggered. Once the channel is created, the channel cannot be updated. Make sure your `channelId` is different if you change these options. If you have created a channel in another way, it will apply options of the channel.

If you want to use a different default channel for remote notification, refer to the documentation of Firebase:

Expand Down Expand Up @@ -641,7 +644,18 @@ https://developer.android.com/training/monitoring-device-state/doze-standby
Property `repeatType` can only be `day`.

### Android
Property `repeatType` could be one of `month`, `week`, `day`, `hour`, `minute`, `time`. If specified as time, it should be accompanied by one more parameter `repeatTime` which should the number of milliseconds between each interval.
Property `repeatType` could be one of `month`, `week`, `day`, `hour`, `minute`, `time`.

The interval used can be configured to a different interval using `repeatTime`. If `repeatType` is `time`, `repeatTime` must be specified as the number of milliseconds between each interval.
For example, to configure a notification every other day
```javascript
PushNotification.localNotificationSchedule({
...
repeatType: 'day',
repeatTime: 2,
...
});
```

## Notification Actions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;

Expand All @@ -56,9 +54,6 @@ public class RNPushNotificationHelper {
private Context context;
private RNPushNotificationConfig config;
private final SharedPreferences scheduledNotificationsPersistence;
private static final int ONE_MINUTE = 60 * 1000;
private static final long ONE_HOUR = 60 * ONE_MINUTE;
private static final long ONE_DAY = 24 * ONE_HOUR;

public RNPushNotificationHelper(Application context) {
this.context = context;
Expand Down Expand Up @@ -623,44 +618,19 @@ private void scheduleNextNotificationIfRepeating(Bundle bundle) {
return;
}

long newFireDate = 0;

switch (repeatType) {
case "time":
newFireDate = fireDate + repeatTime;
break;
case "month":
final Calendar fireDateCalendar = new GregorianCalendar();
fireDateCalendar.setTime(new Date(fireDate));
final int fireDay = fireDateCalendar.get(Calendar.DAY_OF_MONTH);
final int fireMinute = fireDateCalendar.get(Calendar.MINUTE);
final int fireHour = fireDateCalendar.get(Calendar.HOUR_OF_DAY);

final Calendar nextEvent = new GregorianCalendar();
nextEvent.setTime(new Date());
final int currentMonth = nextEvent.get(Calendar.MONTH);
int nextMonth = currentMonth < 11 ? (currentMonth + 1) : 0;
nextEvent.set(Calendar.YEAR, nextEvent.get(Calendar.YEAR) + (nextMonth == 0 ? 1 : 0));
nextEvent.set(Calendar.MONTH, nextMonth);
final int maxDay = nextEvent.getActualMaximum(Calendar.DAY_OF_MONTH);
nextEvent.set(Calendar.DAY_OF_MONTH, Math.min(fireDay, maxDay));
nextEvent.set(Calendar.HOUR_OF_DAY, fireHour);
nextEvent.set(Calendar.MINUTE, fireMinute);
nextEvent.set(Calendar.SECOND, 0);
newFireDate = nextEvent.getTimeInMillis();
break;
case "week":
newFireDate = fireDate + 7 * ONE_DAY;
break;
case "day":
newFireDate = fireDate + ONE_DAY;
break;
case "hour":
newFireDate = fireDate + ONE_HOUR;
break;
case "minute":
newFireDate = fireDate + ONE_MINUTE;
break;
long newFireDate;
if ("time".equals(repeatType)) {
newFireDate = fireDate + repeatTime;
} else {
int repeatField = getRepeatField(repeatType);

final Calendar nextEvent = Calendar.getInstance();
nextEvent.setTimeInMillis(fireDate);
// Limits repeat time increment to int instead of long
int increment = repeatTime > 0 ? (int) repeatTime : 1;
nextEvent.add(repeatField, increment);

newFireDate = nextEvent.getTimeInMillis();
}

// Sanity check, should never happen
Expand All @@ -673,6 +643,22 @@ private void scheduleNextNotificationIfRepeating(Bundle bundle) {
}
}

private int getRepeatField(String repeatType) {
switch (repeatType) {
case "month":
return Calendar.MONTH;
case "week":
return Calendar.WEEK_OF_YEAR;
case "hour":
return Calendar.HOUR;
case "minute":
return Calendar.MINUTE;
case "day":
default:
return Calendar.DATE;
}
}

private Uri getSoundUri(String soundName) {
if (soundName == null || "default".equalsIgnoreCase(soundName)) {
return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Expand Down