Rapsssito / react-native-background-actions

React Native background service library for running background tasks forever in Android & iOS.
MIT License
819 stars 117 forks source link

Linking Uri For Native App Settings? #174

Closed DanielGannage closed 1 year ago

DanielGannage commented 1 year ago

Cant seem to get Deep Linking working with the linkingUri. I am trying for android.

Otherwise, the background task works well. In the notification center on ios/android the task shows up, with the right message, icons, etc. Only issue is when when i click the notification, it doesnt bring me to the settings app at the path of this applications settings.

I've added the intent-filter under <activity>:

 <intent-filter android:label="filter_react_native">
    <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="appName" />
</intent-filter>

and the corresponding linkingUri: 'android.settings.APPLICATION_DETAILS_SETTINGS/appName' in the backgroundTaskOptions

Am I missing something? Is my path wrong?

Please let me know :)

DanielPxdel commented 1 year ago

Answering my own question here, to open settings from banner, to kill the app:

I discovered after some time that if you are using react navigation (@react-navigation/native) to handle your screens and you want to bring to a particular screen in your app (or go to native android settings) from your linkingURI in your backgroundTaskOptions, then you need to do some extra linking configuration, beyond these docs.

In my case I created a screen called RouteToSettings in my app (at the top level) to open native android settings (for my app) when the component mounts. This effectively links to my settings screen in app and opens the android native settings (to kill the app/force stop the background task), when tapping on the banner.

import {Image, Linking, View } from 'react-native';
import React, { useEffect } from 'react';
import { useNavigation } from '@react-navigation/native';

const RouteToSettings = () => {

    const navigation = useNavigation();

    // Component did mount hook for functional component (if you are using old class components, use componentDidMount instead)
    useEffect(() => {
       // open android native settings for this app
       Linking.openSettings();
    },[]);

    // component did update
    // navigate to main thereafter (if you didnt kill the app and decided to reopen it)
    useEffect(() => {
        // navigate to main
        navigation.navigate('Main');
     });

    // fluff
    const logo = require("../assets/logo.png");
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#333' }}>
            <Image source={logo} />
        </View>
    );
};

export default RouteToSettings;

More complex linking path configuration using @react-navigation/native can be found here: https://reactnavigation.org/docs/configuring-links/

Mine is a little more simple:

// THIS IS THE BIG TICKET RIGHT HERE. Add this linking config to your navigation container as shown below 
const linking = {
    prefixes: [
      // your linking prefixes 
      'appName://'
    ],
    config: {
      // configuration for matching screens with paths 
      screens: {
        Settings: 'Settings',
      }
    },
  };

const AppNavigator = () => {

    return (
        <NavigationContainer linking={linking} >
            <Stack.Navigator>
                <Stack.Screen name="Settings" component={RouteToSettings} />
                <Stack.Screen name="Main" component={MainApp} />
            </Stack.Navigator>
        </NavigationContainer>
    )
}

Then in my background tasks linkingURI - I set it like this:

const backgroundTaskOptions = {
    taskName: 'myTask',
    taskTitle: 'appName',
    taskDesc: 'appName is running',
    taskIcon: {
        name: 'ic_launcher',
        type: 'mipmap',
    },
    color: '#52B949',
    linkingURI: 'appName://Settings',               <----- This is the path we created
    parameters: {
        delay: 1000,
    },
};

And I set the intent filter in the android manifest as these docs suggest:

<intent-filter android:label="filter_react_native">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="appName" />
</intent-filter>

I hope that helps anyone trying to kill their app from running in the background.

amashabe commented 1 year ago

the code from the documentation of this library seems incomplete, can anyone assist?

sridhar-aravind commented 1 year ago

@DanielPxdel Thanks a lot for adding a detailed information on how to solve this. Worked fine.