简体   繁体   English

如何通过深度链接重启 React Native App

[英]How to restart react native app through deep linking

I am trying to implement deeplinking in my react native Android application.我正在尝试在我的 React Native Android 应用程序中实现深层链接。 Link is sent through and SMS and when the link is clicked it opens the app and based on the url I am navigating to a perticular screen using android:launchMode="singleTop" .链接通过 SMS 发送,单击链接时它会打开应用程序,并基于 url 我正在使用android:launchMode="singleTop"导航到特定屏幕。 The issue I was facing is when the link is clicked, a new instance of the app is opened and I did not want that so I changed to android:launchMode="singleTask" to my activity in AndroidManifest.xml and now there is only one instance.我面临的问题是单击链接时,打开了一个应用程序的新实例,但我不希望这样,所以我将android:launchMode="singleTask"更改为我在AndroidManifest.xml中的activity ,现在只有一个实例。 But now when the link from the SMS is clicked it resumes the existing page and I cannot get the url clicked.但是现在,当单击 SMS 中的链接时,它会恢复现有页面,我无法单击 url。

I implemented 'AppState' to know when a screen is resumed but that does not give me the url too.我实现了“AppState”以了解屏幕何时恢复,但这也没有给我 url。

What I want to be able to achieve is either我希望能够实现的是

  • App to completely restart from the beginning Splash activity and I know I can get the URL and navigate from there on based on the URL. ( android:launchMode="singleTop" does not restart the app but opens a new instance)应用程序从开始的Splash activity完全重启,我知道我可以获得 URL 并基于 URL 从那里导航。( android:launchMode="singleTop"不会重启应用程序但会打开一个新实例)
  • Or when the user clicks on the URL link, Even if it resumes the existing screen, I want to get the URL and navigate to a perticular screen.或者当用户单击 URL 链接时,即使它恢复现有屏幕,我也想获取 URL 并导航到特定屏幕。

Manifest显现

   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.abcdabcdapp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        //This is what is required to open from the link
        <intent-filter android:label="ABCD App">
          <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="abcd"
            android:pathPrefix="/createpassword" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>
</manifest>

Link that is sent through as SMS - http://abcd/createpassword通过短信发送的链接 - http://abcd/createpassword

Splash screen - Initial screen.初始屏幕 - 初始屏幕。

componentDidMount() {
        setTimeout(() => {
            this.whereShoulINavigateTo();
        }, 2500);        
    }

whereShoulINavigateTo = async () => {
    if (Platform.OS === 'android') {
        Linking.getInitialURL().then( async (url) => {
          //this.navigate(url);
          if(url === 'http://abcd/createpassword')
          { 
            this.props.navigation.navigate('CreatePasswordScreen');
          }else{
            //do something
          }
        });
      } else {
          alert('ios url -' + url );
          //Linking.addEventListener('url', this.handleOpenURL);
    }       
}

Above setup works fine with android:launchMode="singleTop" but only issue is I donot want a new instance of the app.以上设置适用于android:launchMode="singleTop"但唯一的问题是我不想要应用程序的新实例。

So I tried the following changes所以我尝试了以下更改

Manifest显现

android:launchMode="singleTask"

With this there is only one instance and when the URL is clicked, app resumes.这样只有一个实例,当单击 URL 时,应用程序恢复。

So I added AppState to the page which resumes and tried to get the URL but that did not work.因此,我将 AppState 添加到恢复页面并尝试获取 URL 但这没有用。

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

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

  _handleAppStateChange = (nextAppState) => {
    if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
      console.log('App has come to the foreground!')
      this.whereShoulINavigateTo();   
    }
    this.setState({appState: nextAppState});
  }

  whereShoulINavigateTo = async () => {
    if (Platform.OS === 'android') {
        Linking.getInitialURL().then( async (url) => {
          alert('url - ' + url)
          if(url === 'http://abcd/createpassword')
          { 
            this.props.navigation.navigate('CreatePasswordScreen');
          }
        });
      } else {
          alert('ios url -' + url );
          //Linking.addEventListener('url', this.handleOpenURL);
    }       
  }

Please suggest.请建议。

Thanks R感谢 R

Here is the solution that works for me. 这是对我有用的解决方案。

launch mode I have set it to singleTask Manifest.xml 启动模式,我将其设置为singleTask Manifest.xml

       <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:windowSoftInputMode="adjustResize">

The initial screen that opens in my app is Splash screen. 在我的应用中打开的初始屏幕是启动屏幕。 Lets say you received the SMS and your app is closed we will reopen the app so it will always open the initial screen in my case splash screen. 假设您收到了短信,并且您的应用程序已关闭,我们将重新打开该应用程序,因此它将始终在我的案例启动屏幕中打开初始屏幕。

Here is my splash screen code. 这是我的启动画面代码。

    componentDidMount() {
        setTimeout(() => {
            this.whereShoulINavigateTo();
        }, 2500);        
    }

    whereShoulINavigateTo = async () => {
        encryptString('abcd');
        decryptString('abcd');
        if (Platform.OS === 'android') {
            Linking.getInitialURL().then( async (url) => {               
                if(url === 'http://abcd/1234')
                { 
                    //if the url is right do something
                }else{

                }
            });
          } else {
              alert('ios url -' + url );
              //Linking.addEventListener('url', this.handleOpenURL);
              //Not implemented for iOS yet
        }       
    }

And on the other screens when the app is open and a message is received. 并在其他屏幕上打开应用程序并收到消息。 you click on the link and it open the same screen. 您单击链接,它将打开相同的屏幕。 So following logic is required on that screen. 因此,在该屏幕上需要遵循以下逻辑。

    componentDidMount(){
        Linking.addEventListener('url', this.handleOpenURL);
      }  

      componentWillUnmount() {
        Linking.removeEventListener('url', this.handleOpenURL);
      }

       handleOpenURL = async (event) => { 
        consoleLog('url - ' + event.url);      
          if(event.url === 'http://abcd/1234')
          { 
              //if the url is right do something
          }

      }

Hope it helps. 希望能帮助到你。

let me know if you need any further info 让我知道您是否需要其他信息

Thanks R 谢谢R

Delete the /android folder and expo删除/android文件夹和expo

run "expo prebuild" command and build it.运行“expo prebuild”命令并构建它。

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

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