简体   繁体   English

当应用程序处于后台状态时,深度链接不起作用 React Native

[英]Deep linking not working when app is in background state React native

i am creating e-commerce app based react native.here i need open single product page from url shared.actually it will work when app is in killed state, but incase of app is in background/inactive state it won't work.我正在创建基于 React native 的电子商务应用程序。这里我需要从 url shared 打开单个产品页面。实际上,当应用程序处于终止状态时它会工作,但如果应用程序处于后台/非活动状态,它将无法工作。 the sharing url gets null when opening on background/inactive state.I have attached my code.在后台/非活动状态下打开时,共享 url 为空。我附上了我的代码。

// following code working for app killing state

componentWillMount() {

    if (Platform.OS === 'android') {
      console.log("Testing");debugger

      //Constants.OneTimeFlag == false;
          Linking.getInitialURL().then(url => {
            console.log(url);
            var str = url
            var name = str.split('/')[4]
            Constants.isLinking = true;
           this.setState({ shop_Id: name})


           if (str)
           {
            this.setState({ isFromHomeLinking:'FROM_LINK' })
            this.props.navigation.navigate('SingleProductScreen', { ListViewClickItemHolder: [this.state.shop_Id,1,this.state.isFromHomeLinking] });

           }


          });

    }

    else {
        Linking.addEventListener('url', this.handleNavigation);
      }

  }

Not working code following..



componentDidMount() {
    AppState.addEventListener('change', this._handleAppStateChange);
}

componentWillUnmount() {
    AppState.removeEventListener('change', this._handleAppStateChange);
  }

this.state.appState declared in constructor(props)

_handleAppStateChange = (nextAppState) => {
    if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
     console.log('App has come to the foreground!');debugger
 if (Platform.OS === 'android') {
          console.log("Testing");debugger

          //Constants.OneTimeFlag == false;
              Linking.getInitialURL().then(url => {
                console.log(url);
                var str = url
                var name = str.split('/')[4]
                Constants.isLinking = true;
               this.setState({ shop_Id: name})


               if (str)
               {
                this.setState({ isFromHomeLinking:'FROM_LINK' })
                this.props.navigation.navigate('SingleProductScreen', { ListViewClickItemHolder: [this.state.shop_Id,1,this.state.isFromHomeLinking] });

               }


              });

        }

        else {
            Linking.addEventListener('url', this.handleNavigation);
          }
    }
    }

when i open external link from whatsapp and app in background state Linking.getInitialURL() received as null ..当我在后台状态下从 whatsapp 和应用程序打开外部链接 Linking.getInitialURL() 接收为 null ..

Following i have in manifest file以下我在清单文件中

<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize"
        android:launchMode="singleTask">
        <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="http"
 android:host="demo1.zgroo.com" />
</intent-filter>
      </activity>

following is my sample URL..以下是我的示例网址..

http://demo1.zgroo.com/xxxx http://demo1.zgroo.com/xxxx

Kindly let me know any solutions..请让我知道任何解决方案..

thanks in advance..提前致谢..

You need to register Linking listener for this case.您需要为这种情况注册链接侦听器。

componentDidMount() {
  Linking.addEventListener('url', this._handleOpenURL);
},
componentWillUnmount() {
  Linking.removeEventListener('url', this._handleOpenURL);
},
_handleOpenURL(event) {
  console.log(event.url);
}

For more https://facebook.github.io/react-native/docs/linking更多https://facebook.github.io/react-native/docs/linking

Here's a version of Anurag's answer using hooks:这是使用钩子的 Anurag 答案的一个版本:

export function useDeepLinkURL() {
  const [linkedURL, setLinkedURL] = useState<string | null>(null);

  // 1. If the app is not already open, it is opened and the url is passed in as the initialURL
  // You can handle these events with Linking.getInitialURL(url) -- it returns a Promise that
  // resolves to the url, if there is one.
  useEffect(() => {
    const getUrlAsync = async () => {
      // Get the deep link used to open the app
      const initialUrl = await Linking.getInitialURL();
      setLinkedURL(decodeURI(initialUrl));
    };

    getUrlAsync();
  }, []);

  // 2. If the app is already open, the app is foregrounded and a Linking event is fired
  // You can handle these events with Linking.addEventListener(url, callback)
  useEffect(() => {
    const callback = ({url}: {url: string}) => setLinkedURL(decodeURI(url));
    Linking.addEventListener('url', callback);
    return () => {
      Linking.removeEventListener('url', callback);
    };
  }, []);

  const resetURL = () => setLinkedURL(null);

  return {linkedURL, resetURL};
}

You can then use it with:然后您可以将其用于:

const {linkedURL, resetURL} = useDeepLinkURL();

useEffect(() => {
    // ... handle deep link
    resetURL();
}, [linkedURL, resetURL])

I added the function resetURL because if a user shares the same file twice with the app, you would want to load it twice.我添加了函数resetURL因为如果用户与应用程序共享同一个文件两次,你会想要加载它两次。 However, because the deep link would end up being the same, so the useEffect wouldn't be triggered again.但是,由于深层链接最终会相同,因此不会再次触发useEffect You can cause it to be triggered again by setting the linkedURL to null, so the next time a file is shared, you can be sure that it will cause the useEffect to be run.您可以通过将linkedURL设置为null 来再次触发它,因此下次共享文件时,您可以确定它会导致useEffect运行。

Also, I used decodeURI to decode the passed in URL because if you use a library like react-native-fs to load the file from the specified path, it won't be able to handle files with spaces in their names unless you use decodeURI .此外,我使用decodeURI对传入的 URL 进行解码,因为如果您使用像 react-native-fs 这样的库从指定路径加载文件,它将无法处理名称中带有空格的文件,除非您使用decodeURI .

Remove listener from componentwillunmount .componentwillunmount删除侦听器。 No need to write any code in componentwillunmount because the addListener of linking will always listen, then only if you coming from background (by clicking new deeplink) to active state will trigger.无需在componentwillunmount编写任何代码,因为链接的addListener将始终侦听,只有当您从后台(通过单击新的深层链接)进入活动状态时才会触发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM