Skip to content

Instantly share code, notes, and snippets.

@ourmaninamsterdam
Last active June 28, 2022 08:22
Show Gist options
  • Save ourmaninamsterdam/bf02b263c9a7aabca838ce21a1f9f6df to your computer and use it in GitHub Desktop.
Save ourmaninamsterdam/bf02b263c9a7aabca838ce21a1f9f6df to your computer and use it in GitHub Desktop.
expo-notifications: Patch to resolve "Error: Failed to schedule notification" issue on Expo SDK 43 with SDK version 31
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/NotificationsService.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/NotificationsService.kt
index 8e675c4..2062951 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/NotificationsService.kt
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/NotificationsService.kt
@@ -8,6 +8,7 @@ import android.content.Intent
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Bundle
+import android.os.Build
import android.os.Parcel
import android.os.Parcelable
import android.os.ResultReceiver
@@ -424,11 +425,13 @@ open class NotificationsService : BroadcastReceiver() {
intent.putExtra(IDENTIFIER_KEY, identifier)
}
+ // We're defaulting to the behaviour prior API 31 (mutable) even though Android recommends immutability
+ val mutableFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0
return PendingIntent.getBroadcast(
context,
intent.component?.className?.hashCode() ?: NotificationsService::class.java.hashCode(),
intent,
- PendingIntent.FLAG_UPDATE_CURRENT
+ PendingIntent.FLAG_UPDATE_CURRENT or mutableFlag
)
}
@@ -458,11 +461,13 @@ open class NotificationsService : BroadcastReceiver() {
intent.putExtra(NOTIFICATION_ACTION_KEY, action as Parcelable)
}
+ // We're defaulting to the behaviour prior API 31 (mutable) even though Android recommends immutability
+ val mutableFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0
return PendingIntent.getBroadcast(
context,
intent.component?.className?.hashCode() ?: NotificationsService::class.java.hashCode(),
intent,
- PendingIntent.FLAG_UPDATE_CURRENT
+ PendingIntent.FLAG_UPDATE_CURRENT or mutableFlag
)
}
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/ExpoSchedulingDelegate.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/ExpoSchedulingDelegate.kt
index 9147c5a..ca760d1 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/ExpoSchedulingDelegate.kt
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/ExpoSchedulingDelegate.kt
@@ -1,7 +1,9 @@
package expo.modules.notifications.service.delegates
import android.app.AlarmManager
+import android.app.PendingIntent
import android.content.Context
+import android.os.Build
import android.util.Log
import androidx.core.app.AlarmManagerCompat
import expo.modules.notifications.notifications.interfaces.SchedulableNotificationTrigger
@@ -57,12 +59,7 @@ class ExpoSchedulingDelegate(protected val context: Context) : SchedulingDelegat
NotificationsService.removeScheduledNotification(context, request.identifier)
} else {
store.saveNotificationRequest(request)
- AlarmManagerCompat.setExactAndAllowWhileIdle(
- alarmManager,
- AlarmManager.RTC_WAKEUP,
- nextTriggerDate.time,
- NotificationsService.createNotificationTrigger(context, request.identifier)
- )
+ setupAlarm(nextTriggerDate.time, NotificationsService.createNotificationTrigger(context, request.identifier))
}
}
}
@@ -99,4 +96,22 @@ class ExpoSchedulingDelegate(protected val context: Context) : SchedulingDelegat
alarmManager.cancel(NotificationsService.createNotificationTrigger(context, it))
}
}
+
+ private fun setupAlarm(triggerAtMillis: Long, operation: PendingIntent) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || alarmManager.canScheduleExactAlarms()) {
+ AlarmManagerCompat.setExactAndAllowWhileIdle(
+ alarmManager,
+ AlarmManager.RTC_WAKEUP,
+ triggerAtMillis,
+ operation
+ )
+ } else {
+ AlarmManagerCompat.setAndAllowWhileIdle(
+ alarmManager,
+ AlarmManager.RTC_WAKEUP,
+ triggerAtMillis,
+ operation
+ )
+ }
+ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment