diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2e9efcb40..09f85b08d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -30,6 +30,7 @@
+
@@ -267,7 +268,7 @@
+ android:foregroundServiceType="dataSync|systemExempted" />
diff --git a/app/src/main/java/com/android/calendar/AllInOneActivity.java b/app/src/main/java/com/android/calendar/AllInOneActivity.java
index b113befea..aa24d3883 100644
--- a/app/src/main/java/com/android/calendar/AllInOneActivity.java
+++ b/app/src/main/java/com/android/calendar/AllInOneActivity.java
@@ -23,7 +23,6 @@
import static android.provider.CalendarContract.EXTRA_EVENT_END_TIME;
import android.Manifest;
-import android.app.AlarmManager;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
@@ -597,9 +596,8 @@ protected void onResume() {
mController.registerFirstEventHandler(HANDLER_KEY, this);
mOnSaveInstanceStateCalled = false;
- AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
- if (!alarmManager.canScheduleExactAlarms()) {
+ if (!Utils.canScheduleAlarms(this)) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
startActivity(intent);
diff --git a/app/src/main/java/com/android/calendar/Utils.java b/app/src/main/java/com/android/calendar/Utils.java
index 9045c621b..6595877c3 100644
--- a/app/src/main/java/com/android/calendar/Utils.java
+++ b/app/src/main/java/com/android/calendar/Utils.java
@@ -21,6 +21,7 @@
import android.Manifest;
import android.accounts.Account;
import android.app.Activity;
+import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.content.BroadcastReceiver;
@@ -54,6 +55,7 @@
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.SearchView;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
@@ -205,6 +207,19 @@ public class Utils {
private static boolean mAllowWeekForDetailView = false;
private static String sVersion = null;
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ public static boolean canScheduleAlarms(Context context) {
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ return alarmManager.canScheduleExactAlarms();
+ }
+
+ /**
+ * Returns whether the SDK is the UpsideDownCake release or later.
+ */
+ public static boolean isUpsideDownCakeOrLater() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+ }
+
/**
* Returns whether the SDK is the Q release or later.
*/
diff --git a/app/src/main/java/com/android/calendar/alerts/AlertReceiver.java b/app/src/main/java/com/android/calendar/alerts/AlertReceiver.java
index 780fbd00e..c01e87444 100644
--- a/app/src/main/java/com/android/calendar/alerts/AlertReceiver.java
+++ b/app/src/main/java/com/android/calendar/alerts/AlertReceiver.java
@@ -140,6 +140,9 @@ public static void beginStartingService(Context context, Intent intent) {
if (Utils.isMOrLater()) {
if (pm.isIgnoringBatteryOptimizations(context.getPackageName())) {
if (Utils.isOreoOrLater()) {
+ if (Utils.isUpsideDownCakeOrLater() && !Utils.canScheduleAlarms(context)) {
+ return;
+ }
context.startForegroundService(intent);
} else {
context.startService(intent);
diff --git a/app/src/main/java/com/android/calendar/alerts/AlertService.java b/app/src/main/java/com/android/calendar/alerts/AlertService.java
index 363a1acdc..983c48f7e 100644
--- a/app/src/main/java/com/android/calendar/alerts/AlertService.java
+++ b/app/src/main/java/com/android/calendar/alerts/AlertService.java
@@ -17,6 +17,7 @@
package com.android.calendar.alerts;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED;
import android.Manifest;
import android.annotation.TargetApi;
@@ -934,12 +935,13 @@ public int onStartCommand(Intent intent, int flags, int startId) {
.setShowWhen(false)
.build();
if (Utils.isQOrLater()) {
- ServiceCompat.startForeground(
- this,
- 1337,
- notification,
- FOREGROUND_SERVICE_TYPE_DATA_SYNC
- );
+ int serviceType;
+ if (Utils.isUpsideDownCakeOrLater()) {
+ serviceType = FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED;
+ } else {
+ serviceType = FOREGROUND_SERVICE_TYPE_DATA_SYNC;
+ }
+ ServiceCompat.startForeground(this, 1337, notification, serviceType);
} else {
startForeground(1337, notification);
}