diff --git a/onebusaway-android/src/main/AndroidManifest.xml b/onebusaway-android/src/main/AndroidManifest.xml
index 594a251c2..98ace5da4 100644
--- a/onebusaway-android/src/main/AndroidManifest.xml
+++ b/onebusaway-android/src/main/AndroidManifest.xml
@@ -45,6 +45,8 @@
+
+
= Build.VERSION_CODES.M) {
+ alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, alarmIntent);
+ }
+ }
+
+ private static PendingIntent createAlarmIntent(Context context, Uri alertUri) {
+ Intent intent = new Intent(TripService.ACTION_POLL, alertUri, context, AlarmReceiver.class);
+
int flags;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
flags = PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE;
} else {
flags = PendingIntent.FLAG_ONE_SHOT;
}
- PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0,
- intent, flags);
- AlarmManager alarm =
- (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- // Try to cut through Doze so alarm still triggers - See #558
- // Note that we intentionally do NOT use alarm.setAlarmClock() because this creates
- // an alarm in the user's status bar and notification drawer which can be annoying - see
- // https://stackoverflow.com/questions/34699662/how-does-alarmmanager-alarmclockinfos-pendingintent-work
- alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, alarmIntent);
- } else {
- alarm.set(AlarmManager.RTC_WAKEUP, triggerTime, alarmIntent);
- }
+ return PendingIntent.getBroadcast(context, 0, intent, flags);
}
public static void notifyTrip(Context context, Uri alertUri, String notifyTitle, String notifyText) {
diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/ui/TripInfoActivity.java b/onebusaway-android/src/main/java/org/onebusaway/android/ui/TripInfoActivity.java
index c19655209..19e6a7fe7 100644
--- a/onebusaway-android/src/main/java/org/onebusaway/android/ui/TripInfoActivity.java
+++ b/onebusaway-android/src/main/java/org/onebusaway/android/ui/TripInfoActivity.java
@@ -15,6 +15,8 @@
*/
package org.onebusaway.android.ui;
+import android.Manifest;
+import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentResolver;
@@ -25,7 +27,9 @@
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
+import android.provider.Settings;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
@@ -50,6 +54,7 @@
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@@ -57,6 +62,8 @@
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
+import static org.onebusaway.android.util.PermissionUtils.NOTIFICATION_PERMISSION_REQUEST;
+
public class TripInfoActivity extends AppCompatActivity {
private static final String TAG = "TripInfoActivity";
@@ -415,6 +422,19 @@ public void saveTrip() {
// Reminder time
// Repeats
//
+
+ // Make sure that the user has granted permission for notifications
+ // and exact alarms.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (!TripService.canScheduleExactAlarms(getActivity())) {
+ showRequestAlarmsPermissionDialog(getActivity());
+ return;
+ }
+ ActivityCompat.requestPermissions(this.getActivity(),
+ new String[] {Manifest.permission.POST_NOTIFICATIONS},
+ NOTIFICATION_PERMISSION_REQUEST);
+ }
+
View view = getView();
final Spinner reminderView = (Spinner) view.findViewById(R.id.trip_info_reminder_time);
final TextView nameView = (TextView) view.findViewById(R.id.name);
@@ -455,6 +475,27 @@ public void saveTrip() {
finish();
}
+ private void showRequestAlarmsPermissionDialog(Context context) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context)
+ .setTitle(R.string.trip_info_grant_exact_alarms_permission_title)
+ .setCancelable(true)
+ .setMessage(R.string.trip_info_grant_exact_alarms_permission_message)
+ .setPositiveButton(
+ R.string.trip_info_grant_exact_alarms_permission_positive_button,
+ (dialog, which) -> {
+ TripService.requestScheduleExactAlarmsPermission(context);
+ dialog.dismiss();
+ }
+ )
+ .setNegativeButton(
+ R.string.trip_info_grant_exact_alarms_permission_negative_button,
+ (dialog, which) -> {
+ dialog.dismiss();
+ });
+ AlertDialog alertDialog = builder.create();
+ alertDialog.show();
+ }
+
void showReminderDaysDialog() {
final boolean[] checks = ObaContract.Trips.daysToArray(mReminderDays);
Bundle args = new Bundle();
diff --git a/onebusaway-android/src/main/java/org/onebusaway/android/util/PermissionUtils.java b/onebusaway-android/src/main/java/org/onebusaway/android/util/PermissionUtils.java
index 2e4fc5182..b7a809cd7 100644
--- a/onebusaway-android/src/main/java/org/onebusaway/android/util/PermissionUtils.java
+++ b/onebusaway-android/src/main/java/org/onebusaway/android/util/PermissionUtils.java
@@ -30,6 +30,7 @@ public class PermissionUtils {
public static final int SAVE_BACKUP_PERMISSION_REQUEST = 2;
public static final int RESTORE_BACKUP_PERMISSION_REQUEST = 3;
public static final int BACKGROUND_LOCATION_PERMISSION_REQUEST = 4;
+ public static final int NOTIFICATION_PERMISSION_REQUEST = 5;
public static final String[] LOCATION_PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
diff --git a/onebusaway-android/src/main/res/values-es/strings.xml b/onebusaway-android/src/main/res/values-es/strings.xml
index 06cabef9d..70ed0cda6 100644
--- a/onebusaway-android/src/main/res/values-es/strings.xml
+++ b/onebusaway-android/src/main/res/values-es/strings.xml
@@ -1047,4 +1047,8 @@
Bicicleta Compartida
Toca para reservar una bicicleta
Toca para reservar esta bicicleta
+ Se requiere permiso
+ Debes otorgar permiso a la aplicación para programar un recordatorio.
+ Otorgar permiso
+ Cancelar
diff --git a/onebusaway-android/src/main/res/values-fi/strings.xml b/onebusaway-android/src/main/res/values-fi/strings.xml
index a3a2e1820..3280a3483 100644
--- a/onebusaway-android/src/main/res/values-fi/strings.xml
+++ b/onebusaway-android/src/main/res/values-fi/strings.xml
@@ -631,4 +631,8 @@
(https://github.com/google/material-design-icons), "
"licensed under Apache v2.0 (https://www.apache.org/licenses/LICENSE-2.0).\n\n"
+ Lupa tarvitaan
+ Sinun täytyy antaa sovellukselle lupa muistutuksen asettamiseen.
+ Myönnä lupa
+ Peruuta
diff --git a/onebusaway-android/src/main/res/values-it/strings.xml b/onebusaway-android/src/main/res/values-it/strings.xml
index 9035d4119..3eaeda59c 100644
--- a/onebusaway-android/src/main/res/values-it/strings.xml
+++ b/onebusaway-android/src/main/res/values-it/strings.xml
@@ -909,4 +909,8 @@
Rifiutare partecipazione alla ricerca?
Se scegli di non partecipare alla ricerca non riceveremo più informazioni riguardo alle tue abitudini di viaggio per migliorare il servizio di trasporto pubblico.
Annulla
+ Permesso necessario
+ Devi concedere all\'app il permesso di pianificare un promemoria.
+ Concedi il permesso
+ Annulla
\ No newline at end of file
diff --git a/onebusaway-android/src/main/res/values/strings.xml b/onebusaway-android/src/main/res/values/strings.xml
index e688d0d99..183fda956 100644
--- a/onebusaway-android/src/main/res/values/strings.xml
+++ b/onebusaway-android/src/main/res/values/strings.xml
@@ -450,6 +450,10 @@
Show Route
Show Stop
-
+ Permission Needed
+ You must grant the app permission to schedule a reminder.
+ Grant Permission
+ Cancel
Historically full