diff --git a/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java b/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java index 35d8f87..175cab1 100644 --- a/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java +++ b/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java @@ -24,25 +24,21 @@ public final class BackgroundTaskOptions { } public BackgroundTaskOptions(@NonNull final ReactContext reactContext, @NonNull final ReadableMap options) { - // Create extras extras = Arguments.toBundle(options); if (extras == null) throw new IllegalArgumentException("Could not convert arguments to bundle"); - // Get taskTitle try { if (options.getString("taskTitle") == null) throw new IllegalArgumentException(); } catch (Exception e) { throw new IllegalArgumentException("Task title cannot be null"); } - // Get taskDesc try { if (options.getString("taskDesc") == null) throw new IllegalArgumentException(); } catch (Exception e) { throw new IllegalArgumentException("Task description cannot be null"); } - // Get iconInt try { final ReadableMap iconMap = options.getMap("taskIcon"); if (iconMap == null) @@ -55,7 +51,6 @@ public final class BackgroundTaskOptions { if (iconPackage == null) throw new IllegalArgumentException(); } catch (Exception e) { - // Get the current package as default iconPackage = reactContext.getPackageName(); } final int iconInt = reactContext.getResources().getIdentifier(iconName, iconType, iconPackage); @@ -65,7 +60,6 @@ public final class BackgroundTaskOptions { } catch (Exception e) { throw new IllegalArgumentException("Task icon not found"); } - // Get color try { final String color = options.getString("color"); extras.putInt("color", Color.parseColor(color)); @@ -114,7 +108,6 @@ public final class BackgroundTaskOptions { try { types = extras.getStringArrayList("foregroundServiceType"); } catch (ClassCastException e) { - // If the stored value is not an ArrayList, treat it as no types. return 0; } if (types == null) { @@ -156,31 +149,6 @@ public final class BackgroundTaskOptions { return ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; } return 0; - case "health": - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - return ServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH; - } - return 0; - case "remoteMessaging": - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - return ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING; - } - return 0; - case "systemExempted": - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - return ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED; - } - return 0; - case "shortService": - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - return ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; - } - return 0; - case "specialUse": - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - return ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE; - } - return 0; default: return 0; } diff --git a/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java b/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java index 963b788..b75c098 100644 --- a/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java +++ b/node_modules/react-native-background-actions/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java @@ -5,6 +5,7 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.Service; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -14,21 +15,22 @@ import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; -import androidx.core.app.ServiceCompat; import com.facebook.react.HeadlessJsTaskService; import com.facebook.react.bridge.Arguments; import com.facebook.react.jstasks.HeadlessJsTaskConfig; +import java.lang.reflect.Method; + final public class RNBackgroundActionsTask extends HeadlessJsTaskService { public static final int SERVICE_NOTIFICATION_ID = 92901; private static final String CHANNEL_ID = "RN_BACKGROUND_ACTIONS_CHANNEL"; + private static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; @SuppressLint("UnspecifiedImmutableFlag") @NonNull public static Notification buildNotification(@NonNull Context context, @NonNull final BackgroundTaskOptions bgOptions) { - // Get info final String taskTitle = bgOptions.getTaskTitle(); final String taskDesc = bgOptions.getTaskDesc(); final int iconInt = bgOptions.getIconInt(); @@ -38,7 +40,6 @@ final public class RNBackgroundActionsTask extends HeadlessJsTaskService { if (linkingURI != null) { notificationIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkingURI)); } else { - //as RN works on single activity architecture - we don't need to find current activity on behalf of react context notificationIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()); if (notificationIntent == null) { notificationIntent = new Intent(Intent.ACTION_MAIN) @@ -46,13 +47,11 @@ final public class RNBackgroundActionsTask extends HeadlessJsTaskService { .setPackage(context.getPackageName()); } } - final PendingIntent contentIntent; int pendingIntentFlags = PendingIntent.FLAG_UPDATE_CURRENT; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // IMMUTABLE is available and recommended from API 23+ pendingIntentFlags |= PendingIntent.FLAG_IMMUTABLE; } - contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, pendingIntentFlags); + final PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, pendingIntentFlags); final NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID) .setContentTitle(taskTitle) .setContentText(taskDesc) @@ -93,21 +92,22 @@ final public class RNBackgroundActionsTask extends HeadlessJsTaskService { throw new IllegalArgumentException("Extras cannot be null"); } final BackgroundTaskOptions bgOptions = new BackgroundTaskOptions(extras); - createNotificationChannel(bgOptions.getTaskTitle(), bgOptions.getTaskDesc()); // Necessary creating channel for API 26+ - // Create the notification + createNotificationChannel(bgOptions.getTaskTitle(), bgOptions.getTaskDesc()); final Notification notification = buildNotification(this, bgOptions); try { - ServiceCompat.startForeground( - this, - SERVICE_NOTIFICATION_ID, - notification, - bgOptions.getForegroundServiceType() - ); + int fgType = bgOptions.getForegroundServiceType(); + if (fgType == 0) { + fgType = FOREGROUND_SERVICE_TYPE_DATA_SYNC; + } + if (Build.VERSION.SDK_INT >= 34) { + startForegroundWithType(SERVICE_NOTIFICATION_ID, notification, fgType); + } else { + startForeground(SERVICE_NOTIFICATION_ID, notification); + } } catch (RuntimeException e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof android.app.ForegroundServiceStartNotAllowedException) { - // Android 12+: not allowed to start foreground service from background stopSelf(startId); return START_NOT_STICKY; } @@ -116,16 +116,13 @@ final public class RNBackgroundActionsTask extends HeadlessJsTaskService { return super.onStartCommand(intent, flags, startId); } - @Override - public void onTimeout(int startId) { - super.onTimeout(startId); - stopSelf(startId); - } - - @Override - public void onTimeout(int startId, int fgsType) { - super.onTimeout(startId, fgsType); - stopSelf(startId); + private void startForegroundWithType(int id, Notification notification, int fgType) { + try { + Method method = Service.class.getMethod("startForeground", int.class, Notification.class, int.class); + method.invoke(this, id, notification, fgType); + } catch (Exception e) { + throw new RuntimeException("Failed to start foreground service with type", e); + } } private void createNotificationChannel(@NonNull final String taskTitle, @NonNull final String taskDesc) {