新后台

This commit is contained in:
2026-06-07 13:43:53 +08:00
parent a736e52943
commit 143b8f3b24
14 changed files with 324 additions and 28 deletions

View File

@@ -0,0 +1,202 @@
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<String>, 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) {