react-native-background-actions icon indicating copy to clipboard operation
react-native-background-actions copied to clipboard

Android 14 (Samsung A14) : service stop after backgrounded it

Open danchiche opened this issue 1 year ago • 14 comments

Hi, For testing I start a counter when I click to a button on the app. When I close the app (put it in background), the counter freeze. When I switch off the screen, and switch back on, the counter continue when expected.

This problem is constated on Samsung A14, but I think is due to Android 14+. I have a samsung s9 on android 10 and no problem, when I close the app, counter continue normally.

I tested this on expo 49 with react-native-background-actions 3.0.1 and with expo 51 with react-native-background-actions 4.0.0, and both the same experience.

Do anyone know what can I do ?

Thanks

danchiche avatar Jun 17 '24 14:06 danchiche

Hi, The version 4.0.0 has just been released with support for Android 14 / SDK 34 :)

j-jonathan avatar Jun 17 '24 15:06 j-jonathan

Yes but like I said before, it's not a problem of react-native-background-actions 4.0.0 I tested with expo 49 with react-native-background-actions 3.0.1, and the same problem

danchiche avatar Jun 17 '24 15:06 danchiche

Are notifications allowed in the Android app settings?

j-jonathan avatar Jun 17 '24 15:06 j-jonathan

It's impossible to enable notification in my app on the samsung A14, other apps have the ability to enable it. I try to find on the internet how to enable notifications on my app, but I don't have the restricted setting option. On my samsung s9 notification is allowed, and I see the notification when there is a task in background.

danchiche avatar Jun 17 '24 18:06 danchiche

New update : I ask for notification permission (programmaticaly) at app startup, and now I am able to allow the permission on the A14. I make a new test and it's the same bug : the counter stop 5 seconds after I close the app, and continue when I open it again (or I switch off and on the screen)

danchiche avatar Jun 18 '24 08:06 danchiche

Help, same issue! Furthermore, after an uncertain time the app shows "the app is not responding" whit two choices "close app" or "wait".

This is my AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />

  <uses-feature android:name="android.hardware.camera" />
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.VIBRATE"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <queries>
    <intent>
      <action android:name="android.intent.action.VIEW"/>
      <category android:name="android.intent.category.BROWSABLE"/>
      <data android:scheme="https"/>
    </intent>
  </queries>
  <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme">
    <meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
    <activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="com.anonymous.ssensemobileapp"/>
      </intent-filter>
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
    <service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="shortService"/>
    <service android:name=".MyService" android:foregroundServiceType="location" android:exported="false" android:enabled="true" android:stopWithTask="false"/>
  </application>
</manifest>

and this my snippet:

import BackgroundService from 'react-native-background-actions';

const sleep = (time) =>
	new Promise((resolve) => setTimeout(() => resolve(), time));

const printer = async (taskDataArguments) => {
	// Esempio di un task in loop infinito
	const { delay } = taskDataArguments;
	await new Promise(async (resolve) => {
		for (let i = 0; BackgroundService.isRunning(); i++) {
			console.log(i);
			await sleep(delay);
		}
	});
};

const options = {
	taskName: 'Example',
	taskTitle: 'ExampleTask title',
	taskDesc: 'ExampleTask description',
	taskIcon: {
		name: 'ic_launcher',
		type: 'mipmap',
	},
	color: '#ff00ff',
	linkingURI: 'yourSchemeHere://chat/jane', // See Deep Linking for more info
	parameters: {
		delay: 2000,
	},
};

BackgroundService.start(printer, options);

jacopo-ferroni avatar Jun 19 '24 08:06 jacopo-ferroni

There are some observation:

  • foregroundServiceType=shortService working on Android 14 only 15 minutes according to developer.android.com
  • When I tried change to location it works fine on Android 14, but on Android 10 this service has unexpected behavior (e.g. it can work as 15 minutes or 8 hours) P.S. Maybe it just problem with Xiaomi

vzkharov avatar Jun 26 '24 16:06 vzkharov

Maybe there are some assumptions how to manage stable work of this background-task?

vzkharov avatar Jun 26 '24 16:06 vzkharov

Maybe there are some assumptions how to manage stable work of this background-task?

If you look at the official docs fgservicestypes

shortService only runs for 3 minutes. I think it has something to do with that it's not supposed to run longer than that thus causing errors.

Dwikavindra avatar Aug 13 '24 14:08 Dwikavindra

@Dwikavindra I believe you are onto something! I wonder if foregroundServiceType=specialUse would work for longer tasks?

tmaly1980 avatar Dec 05 '24 15:12 tmaly1980

I tired to run in on Android 14 with specialUse. It has the same issue as for other foreground service types. In my case it seems to work well if app is closed or in a foreground, but if I leave it in the background or lock the screen the task pauses in less then 10 seconds, if I go back to the app it resumes. If anyone has a solution for that please share it here.

wojciechbilka avatar Jan 13 '25 20:01 wojciechbilka

Same problem

JeronimoGarciaBielsa avatar Mar 31 '25 11:03 JeronimoGarciaBielsa

In androidmenifest.xml Use

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING" />
<service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="remoteMessaging" android:exported="false"/>

pankuweb avatar Sep 26 '25 10:09 pankuweb

There is actually alot of problem with the package, but I don't blame the guy since android/ ios is not built to run these continuous process for a long time. I can only touch on the android part, since the company I used to work for only had an android package. If you wish to see my fork you can see it here upsell-background-actions.

If you use BackgroundService.isRunning to keep a while loop or for loop going, at some point the boolean value will be picked up by GC, so it would just return undefined . As such you have to store it in a db. In my experience you need to store it inside SharedPreference and create a js function to call it. I stored it inside SharedPreference because I find that you can't have the process in an indefinite/always running state, it's just not possible. At some point android will kill it. So another way to combat it is by implementing periodic restarts, which includes turning the value of the SharedPreference to false and then restarting the headless js. It also involves locks/semaphores as in some cases there might be 2 or more calls, if the restart period is too fast i.e like every 2 min or 10 min (in my experience every 1 hour or 2 hour is fine) which the lock helps in controlling and limiting the restart process to only one. However at the end of the day, with all of those mechanism, the system would still shut it down after a month or so running. I believe there is a way around it but I haven't tried it, it basically involves SSE (Server Sent Events). This way we can monitor if the process shuts down by communicating with a server, and the server can remind user to restart the process if such thing were to happen.

I could also think of another way by bypassing like a spotify player , but I don't know if it will get passed playstore that way hahaha. More here Background-playback

If you ever need functionality like this tell your PM or boss about these caveats first, and the systems around it you have to design.

Dwikavindra avatar Sep 28 '25 05:09 Dwikavindra