web-dev-qa-db-ja.com

アプリがバックグラウンド状態のときにディープリンクが機能しないReactネイティブ

私はeコマースアプリベースの反応ネイティブを作成しています。ここで、共有されたURLから単一の製品ページを開く必要があります。実際には、アプリが強制終了状態にあるときに機能しますが、アプリがバックグラウンド/非アクティブ状態にある場合は機能しません。バックグラウンド/非アクティブ状態で開くと、共有URLがnullになります。コードを添付しました。

// 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);
          }
    }
    }

whatsappとアプリからバックグラウンド状態で外部リンクを開くと、Linking.getInitialURL()がnullとして受信されました。

以下はマニフェストファイルにあります

<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>

以下は私のサンプルURLです。

http://demo1.zgroo.com/xxxx

解決策を教えてください。

前もって感謝します..

6
abdul sathar

フックを使用した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};
}

その後、次のもので使用できます。

const {linkedURL, resetURL} = useDeepLinkURL();

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

関数resetURLを追加しました。ユーザーが同じファイルをアプリと2回共有する場合、2回ロードする必要があるためです。ただし、ディープリンクが同じになるため、useEffectは再度トリガーされません。 linkedURLをnullに設定することで、再度トリガーすることができます。これにより、次回ファイルが共有されたときに、useEffectが実行されることが確実になります。

また、decodeURIを使用して、渡されたURLをデコードしました。react-native-fsなどのライブラリを使用して、指定されたパスからファイルをロードすると、スペースが含まれているファイルを処理できないためです。 decodeURIを使用する場合を除き、名前。

0
Eric Wiener