zoontek / react-native-bootsplash

🚀 Show a splash screen during app startup. Hide it when you are ready.
MIT License
3.75k stars 259 forks source link

Deep Linking #36

Closed MoKhajavi75 closed 4 years ago

MoKhajavi75 commented 4 years ago

💻 My environment

🕵️‍♂️ Reproducing the issue

I want to set up deep linking with react-navigation as described here. I finally made it but the problem is when i open the app using the deep link, I get my props as undefined but if i reload the app, i see it! It's somehow weird!

AndroidManifest.xml

<application
  android:name=".MainApplication"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:roundIcon="@mipmap/ic_launcher_round"
  android:allowBackup="false"
  android:theme="@style/AppTheme">

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

    <!-- Deep Linking -->
    <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="aramesh" />
    </intent-filter>
  </activity>

  <!-- Splash Screen -->
  <activity
    android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
    android:theme="@style/BootTheme">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
  </activity>

  <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>

Router.js

_Landing: {
  screen: Landing,
  path: 'agent/:personID'
},

Code

componentDidMount() {
  alert(this.props.navigation.getParam('personID'));
}

🤞Solution

I guess it's somehow related to #24 which has been solved via #11. But i can't understand why i get this as undefined for the first time :neutral_face:

zoontek commented 4 years ago

When your app the first time, it open with RNBootSplashActivity then MainActivity. The RNBootSplashActivity will pass all extras intents to your MainActivity, and starts it. When you reload your app, the active Activity is already MainActivity, which can receive aramesh links according to your manifest.

Try adding the intent-filter to the splash screen activity too.

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

    <!-- Deep Linking -->
    <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="aramesh" />
    </intent-filter>
  </activity>

  <!-- Splash Screen -->
  <activity
    android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
    android:theme="@style/BootTheme">
    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <!-- Deep Linking -->
    <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="aramesh" />
    </intent-filter>
  </activity>
MoKhajavi75 commented 4 years ago

Tnx for your reply.

Unfortunately, the problem exist :neutral_face:

I edited manifest and rebuild. Now when i click on the button with link of aramesh://agent/2 android gives me two options (Both are my app with same package name) and both of them don't load the Landing page. (As you can see, i added the path: 'agent/:personID' to my router!

Now i don't get data even after reload! So i guess i should put the filter only in splash... But how can i pass data to the main activity? I even can't route to any screen! (Maybe it is React-Navigation's bug)

I followed this doc so, am i missing something? Or is this a bug?

zoontek commented 4 years ago

@MohamadKh75 I just published a release with the fix (1.1.0).

To handle deep linking, you have to:

For you, it will be:

<application
  android:name=".MainApplication"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:roundIcon="@mipmap/ic_launcher_round"
  android:allowBackup="false"
  android:theme="@style/AppTheme">

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

  <!-- Splash Screen -->
  <activity
    android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
    android:theme="@style/BootTheme"
    android:launchMode="singleTask">

    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <!-- Deep Linking -->
    <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <category android:name="android.intent.category.DEFAULT" />
      <data android:scheme="aramesh" />
    </intent-filter>

  </activity>

  <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>

Can you try and confirm that everything is OK? Thanks!

MoKhajavi75 commented 4 years ago

Yep! Everything is OK :tada:

Tnx :heart:

I'll create a PR to add this to readme :grin:

paolospag commented 4 years ago

I had the same problem in the recent days and this annotation seems to have solved it, but what about usage with notifications' modules? E.g., integrating RN Firebase Notifications (v5.6.0) and following the documentation for Android, it requires singleTop instead of singleTask launch mode.

So what needs to be done in these cases?

zoontek commented 4 years ago

If I refer to https://inthecheesefactory.com/blog/understand-android-activity-launchmode/en, singleTop could be used as well (on both Activity). But I would recommend keeping singleTask on the BootSplash one

paolospag commented 4 years ago

So, the code should be:

<application
  android:name=".MainApplication"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:roundIcon="@mipmap/ic_launcher_round"
  android:allowBackup="false"
  android:theme="@style/AppTheme">

  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="adjustPan"
    android:exported="true"
    android:launchMode="singleTop" /> <!-- change this for Notifications support -->

  <!-- Splash Screen -->
  <activity
    android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
    android:theme="@style/BootTheme"
    android:launchMode="singleTask"> <!-- maintain on singleTask for Bootsplash -->

    <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.BROWSABLE" />
      <category android:name="android.intent.category.DEFAULT" />
      <data android:scheme="aramesh" />
    </intent-filter>

  </activity>

  <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>

Is it correct?

zoontek commented 4 years ago

@paolospag Yes! Android has some debug tools to test deeplinks, give it a try

enverkoselertr commented 2 years ago

@MohamadKh75 I just published a release with the fix (1.1.0). @zoontek

Hello, I am getting an error like this, where am I going wrong

<application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">

      </activity>
       <!-- Splash Screen -->
      <activity
        android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
        android:theme="@style/BootTheme"
        android:launchMode="singleTask">

        <intent-filter android:autoVerify="true"> 
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="---" />
            <data android:scheme="https" android:host="---" />
        </intent-filter>

      </activity>
    </application>

Error Message

* What went wrong:
Execution failed for task ':app:processDebugMainManifest'.
> Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.

my build gradle


buildscript {
    ext {
        buildToolsVersion = "30.0.2"
        minSdkVersion = 23
        compileSdkVersion = 31
        targetSdkVersion = 31
        ndkVersion = "21.4.7075529"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:4.2.2")
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenCentral()
        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }

        google()
        maven { url 'https://www.jitpack.io' }
    }
}
zoontek commented 2 years ago

@enverkoselertr Just follow the error message…This is not a library issue.

<activity
  android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
  android:theme="@style/BootTheme"
  android:launchMode="singleTask"
  android:exported="true"><!-- add this line -->

Please consider a one time sponsorship, because by mentioning me explicitly you bothered me in my personal life. Open source is not free products by folks working for you, willing to help at any time.

And if you don't want to support a free library and the people behind it, next time ask for help elsewhere.

enverkoselertr commented 2 years ago

@zoontek

Thank you very much for your answer. I've never thought of it this way. I am so sorry for my thoughtlessness. I will do what is necessary, have a nice day