Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal Exception: java.lang.RuntimeException want to use foregroundServiceType="connectedDevice" #240

Open
Faizan-Hurekatek opened this issue Sep 13, 2024 · 5 comments

Comments

@Faizan-Hurekatek
Copy link

App crashes we want to use foregroundServiceType="connectedDevice"

Unable to start service com.asterinet.react.bgactions.RNBackgroundActionsTask@243c415 with Intent { cmp=com.iwelhealth.cgmpal/com.asterinet.react.bgactions.RNBackgroundActionsTask (has extras) mCallingUid=10388 }: android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false: service com.iwelhealth.cgmpal/com.asterinet.react.bgactions.RNBackgroundActionsTask
android.app.ActivityThread.handleServiceArgs

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"


<meta-data
  android:name="com.auth0.client.android.scheme"
  android:value="https://iwell.page.link?utm_campaign=banner&amp;apn=com.iwell&amp;ibi=com.clovahealth.clova&amp;isi=6448808039&amp;link=https%3A%2F%2Finvertase.io%2Fterralogin" />
<activity
  android:name=".MainActivity"
  android:label="@string/app_name"
  android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
  android:launchMode="singleTask"
  android:windowSoftInputMode="adjustResize"
  android:screenOrientation="portrait"
  android:exported="true">
  <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="https" android:host="app.clovahealth.com"
      android:pathPrefix="/cgm/callback" />
    <data android:scheme="https" android:host="iwell.page.link" />
    <data android:scheme="https" android:host="iwell.page.link" />
  </intent-filter>
</activity>
package com.iwelhealth.cgmpal

import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import android.os.Bundle // here

class MainActivity : ReactActivity() {

/**

  • Returns the name of the main component registered from JavaScript. This is used to schedule
  • rendering of the component.
    */
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(null)
    }
    override fun getMainComponentName(): String = "iWelCGMPal"

/**

  • Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
  • which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
    */
    override fun createReactActivityDelegate(): ReactActivityDelegate =
    DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
    }
    import React, {useEffect, useState} from 'react';
    import {
    StyleSheet,
    SafeAreaView,
    KeyboardAvoidingView,
    Platform,
    Alert,
    Linking,
    PermissionsAndroid,
    } from 'react-native';
    import {Navigation} from './navigation/Navigation';
    import {StatusBar} from 'expo-status-bar';
    import {NavigationContainer} from '@react-navigation/native';
    import BackgroundService from 'react-native-background-actions';
    import CGMDataService from './services/cgmService';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    import {PERMISSIONS, requestMultiple} from 'react-native-permissions';
    import DeviceInfo from 'react-native-device-info';

// Define your background task function
const veryIntensiveTask = async () => {
const {getCGMData} = CGMDataService();

// While the background service is running
while (BackgroundService.isRunning()) {
console.log('Running background task!');

// Call the CGM data fetching function
await getCGMData();

// Simulate delay for continuous task running

}
};

// Options for the background service
const options = {
taskName: 'iWelCGMPal',
taskTitle: 'iWelCGMPal',
taskDesc: 'CGM Glucose Data description',
taskIcon: {
name: 'ic_launcher_notification',
type: 'mipmap',
},
linkingURI: 'yourSchemeHere://chat/jane',
parameters: {
delay: 60000,
},
};

const AppEntry = () => {
// State for token
const [token, setToken] = useState(null);
const [userid, setUserid] = useState(null);

// Function to check AsyncStorage for token regularly
const checkHexArray = async () => {
const savedToken = await AsyncStorage.getItem('token');
const savedUserid = await AsyncStorage.getItem('userid');
if (savedToken !== token && savedUserid !== userid) {
setToken(savedToken);
setUserid(savedUserid); // Update state only if it has changed
console.log('Device ID (token) updated:', savedToken, savedUserid);
}
};

useEffect(() => {
// Fetch token on mount
checkHexArray();

// Start a polling interval to check AsyncStorage for updates
const intervalId = setInterval(() => {
  checkHexArray();
}, 5000); // Poll every 5 seconds (adjust as necessary)

// Cleanup interval on component unmount
return () => clearInterval(intervalId);

}, []);

const requestPermissions = async () => {
try {
if (Platform.OS === 'android') {
const apiLevel = await DeviceInfo.getApiLevel();

    if (apiLevel < 31) {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          title: 'Location Permission',
          message: 'Bluetooth Low Energy requires Location',
          buttonNeutral: 'Ask Later',
          buttonNegative: 'Cancel',
          buttonPositive: 'OK',
        },
      );

      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        return true;
      } else if (granted === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) {
        Alert.alert(
          'Permission Denied',
          'Please go to settings and enable Location And Nearby Devices permissions.',
          [
            {
              text: 'Go to Settings',
              onPress: () => Linking.openSettings(),
            },
            {text: 'Cancel', style: 'cancel'},
          ],
        );
      }
      return false;
    } else {
      const result = await requestMultiple([
        PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
        PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
        PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
      ]);

      const isGranted =
        result['android.permission.BLUETOOTH_CONNECT'] ===
          PermissionsAndroid.RESULTS.GRANTED &&
        result['android.permission.BLUETOOTH_SCAN'] ===
          PermissionsAndroid.RESULTS.GRANTED &&
        result['android.permission.ACCESS_FINE_LOCATION'] ===
          PermissionsAndroid.RESULTS.GRANTED;

      if (isGranted) {
        return true;
      } else {
        const neverAskAgain =
          result['android.permission.BLUETOOTH_CONNECT'] ===
            PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN ||
          result['android.permission.BLUETOOTH_SCAN'] ===
            PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN ||
          result['android.permission.ACCESS_FINE_LOCATION'] ===
            PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN;

        if (neverAskAgain) {
          Alert.alert(
            'Permission Denied',
            'Please go to settings and enable Bluetooth and location permissions.',
            [
              {
                text: 'Go to Settings',
                onPress: () => Linking.openSettings(),
              },
              {text: 'Cancel', style: 'cancel'},
            ],
          );
        }
        return false;
      }
    }
  } else {
    return true;
  }
} catch (err) {
  console.error(err);
  return false;
}

};

useEffect(() => {
if (token) {
// Start background service when token is available
const startBackgroundService = async () => {
try {
const isGrant = await requestPermissions();
if (isGrant) {
if (!BackgroundService.isRunning()) {
await BackgroundService.start(veryIntensiveTask, options);
console.log('Background service started');
}
} else {
console.log('no permission granted ');
}
} catch (e) {
console.error('Error starting background service:', e);
}
};

  startBackgroundService();
} else {
  // Stop background service when token is not available
  if (BackgroundService.isRunning()) {
    BackgroundService.stop();
    console.log('Background service stopped due to missing token');
  }
}

}, [token, userid]); // Re-run when token changes

return (


<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
style={styles.root}>





);
};

export default AppEntry;

const styles = StyleSheet.create({
root: {
flex: 1,
},
});
"react": "18.2.0",
"react-native": "0.73.6",
"react-native-background-actions": "^4.0.1",

@rakshitbharat
Copy link

I can confirm this is a bug,
it ended my prod build

@FaizyQadri
Copy link

It's fixed it was just we have to allow permission at the beginning only

@smitha-2020
Copy link

smitha-2020 commented Nov 30, 2024

@FaizyQadri @Faizan-Hurekatek @rakshitbharat How did you solve this? What are the additional permissions needed in the beginning? App Crashes for me.

@FaizanAventior
Copy link

@FaizyQadri @Faizan-Hurekatek @rakshitbharat How did you solve this? What are the additional permissions needed in the beginning? App Crashes for me.

U suggest have to add permission in service tag as well

@FaizanAventior
Copy link

@FaizyQadri @Faizan-Hurekatek @rakshitbharat How did you solve this? What are the additional permissions needed in the beginning? App Crashes for me.

<manifest ... >
...
<application ... >
...

...

...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants