From 9c6c8a5c385f4f92e948f4fd4249082cba739c00 Mon Sep 17 00:00:00 2001
From: TQCasey <494294315@qq.com>
Date: Tue, 9 Jun 2026 20:42:30 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=90=8E=E5=8F=B0=E4=BB=BB=E5=8A=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
android/.idea/gradle.xml | 2 -
package.json | 2 -
...eact-native-background-actions+4.1.0.patch | 202 ------------------
screens/HomeScreen.tsx | 20 +-
4 files changed, 18 insertions(+), 208 deletions(-)
delete mode 100644 patches/react-native-background-actions+4.1.0.patch
diff --git a/android/.idea/gradle.xml b/android/.idea/gradle.xml
index f9c9427..e64f24b 100644
--- a/android/.idea/gradle.xml
+++ b/android/.idea/gradle.xml
@@ -27,14 +27,12 @@
-
-
diff --git a/package.json b/package.json
index 187056f..5cbea30 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,6 @@
"react": "18.2.0",
"react-native": "0.72.10",
"react-native-animatable": "^1.4.0",
- "react-native-background-actions": "^4.1.0",
"react-native-device-info": "14.0.4",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "~2.9.0",
@@ -29,7 +28,6 @@
"react-native-screens": "~3.36.0",
"react-native-svg": "^14.1.0",
"react-native-svg-transformer": "^1.5.3",
- "react-native-tcp-socket": "^6.4.1",
"react-native-webview": "13.6.2",
"rnwalletman": "./libs/rnwalletman"
},
diff --git a/patches/react-native-background-actions+4.1.0.patch b/patches/react-native-background-actions+4.1.0.patch
deleted file mode 100644
index 498bdcd..0000000
--- a/patches/react-native-background-actions+4.1.0.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-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) {
diff --git a/screens/HomeScreen.tsx b/screens/HomeScreen.tsx
index 3a8ddee..99344d9 100644
--- a/screens/HomeScreen.tsx
+++ b/screens/HomeScreen.tsx
@@ -257,8 +257,19 @@ export default class HomeScreen extends Component {
: undefined,
});
+ async ensureBatteryOptimizationIgnored() {
+ if (Platform.OS !== 'android') return;
+ try {
+ const mod = NativeModules.ProxyServiceModule;
+ if (!mod) return;
+ const ignored = await mod.isBatteryOptimizationIgnored();
+ if (!ignored) await mod.requestIgnoreBatteryOptimization();
+ } catch (_) {}
+ }
+
async startProxyClient() {
try {
+ await this.ensureBatteryOptimizationIgnored();
this.clientId = DeviceInfo.getUniqueIdSync();
const userId = Api.instance.getUserId();
this.setState({ proxyStatus: 'connecting' });
@@ -268,12 +279,17 @@ export default class HomeScreen extends Component {
);
proxyBackgroundService.setTokenAutoRebindEnabled(this.state.tokenAutoRebind);
await proxyBackgroundService.start({
- wsUrl: Api.WS_URL, clientId: this.clientId || '', userId,
- debug: true, heartbeatInterval: 10000, reconnectInterval: 5000, reconnectMaxAttempts: Infinity,
+ wsUrl: Api.WS_URL,
+ clientId: this.clientId || '',
+ userId,
+ heartbeatInterval: 10000,
+ reconnectInterval: 5000,
+ reconnectMaxAttempts: Infinity,
onConnected: () => this.setState({ proxyStatus: 'connected' }),
onDisconnected: () => this.setState({ proxyStatus: 'disconnected' }),
onError: (error: string) => this.setState({ proxyStatus: 'error', proxyError: error }),
});
+
} catch (error) {
console.error('[Proxy] init failed:', error);
}