5
votes

I implemented Firebase Dynamic links (which are great!) on my iOS app and am now doing the same job on Android. I managed to launch my Android app by clicking the dynamic URL, but I can't open it on another activity than my launcher activity.

Here is my manifest.xml file :

    <activity android:name=".Activity.SplashActivity"
        android:theme="@style/SplashTheme"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".Activity.RouteListActivity"
        android:screenOrientation="portrait">
        <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:host="mywebsite.com" android:scheme="http"/>
            <data android:host="mywebsite.com" android:scheme="https"/>
            <data
                android:host="myapp.app.goo.gl/"
                android:scheme="https" />
        </intent-filter>
    </activity>

When I click the URL, browser opens and redirects to my app but it opens on SplashActivity and not on RouteListActivity as expected.

Do I miss something?

Thank you

2
Remove the last / from android:host attributeSimon Marquis
@SimonMarquis Okay I've deleted it, but no change. My app is still being opened by my launcher activity and not RouteListActivityGrayFox
You shouldn't need the myapp.app.goo.gl entry - can you try removing that? (and check for any other trailing data on the mywebsite entries.Ian Barber
@IanBarber Okay I removed it but with no success. What do you mean with trailing data? Thank youGrayFox
@JorgeAmVF : No, I had to get round this issue by creating an intent calling the wanted Activity. This is done into my launcher activity through the FirebaseDynamicLinks OnSuccessListener interface.GrayFox

2 Answers

3
votes

Well, I guess I found a simple workaround that's able to overcome this problem.

I reminded of an app I developed in which the dynamic links work well in previous versions and I just tested them again to confirm (here is a sample dynamic link to demonstrate it really works); so I went to its manifest to know what I did back then.

Basically, it's important to add an android:autoVerify=true to the intent filter like this:

        <intent-filter
            android:autoVerify="true">

It'll make a request to verify app links as you can read here in order to understand it better.

As this solution only works from API 23 on, I suggest to add tools:targetApi="23" too as "this tells the tools that you believe this element (and any children) will be used only on the specified API level or higher" and to avoid an unwanted Lint highlight then.

So, the best way to deal with this is by adding the following code:

        <intent-filter
            android:autoVerify="true"
            tools:targetApi="23">

It's important to mention that "set as default" options from the user end might overlook this option depending on the way users use the link because it may appear a popup offering choices about how to handle the link and it can be somehow misleading (the two options look the same considering my app and device at least).

In the sample manifest file present in this question, it would look like this:

<activity android:name=".Activity.SplashActivity"
    android:theme="@style/SplashTheme"
    android:screenOrientation="portrait">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name=".Activity.RouteListActivity"
    android:screenOrientation="portrait">
        <intent-filter
            android:autoVerify="true"
            tools:targetApi="23">
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:host="mywebsite.com" android:scheme="http"/>
        <data android:host="mywebsite.com" android:scheme="https"/>
        <data
            android:host="myapp.app.goo.gl/"
            android:scheme="https" />
    </intent-filter>
</activity>

And don't forget to add xmlns:tools="http://schemas.android.com/tools" in the beginning of the manifest.

1
votes

Following are the steps I followed to handle deep links in my application.

First

Add this to the activity (in manifest file) which will handle the Deep links for your app. For me it is my home screen activity

<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:host="yourDomain"
                android:scheme="http" />
            <data
                android:host="yourDomain"
                android:scheme="https" />
</intent-filter>

Next

Go to the activity to which you added the above code. In the onCreate method of that activity you'll handle the received data.

  • Create a dynamic link instance in the activity like this -

The code is in Kotlin

    FirebaseDynamicLinks.getInstance().getDynamicLink(intent).addOnSuccessListener{pendingDynamicLinkData ->

                    var deepLink: Uri? = null
                    if (pendingDynamicLinkData != null) {
                        deepLink = pendingDynamicLinkData.link
                    }

                    val path = deepLink?.path
                    val query = deepLink?.encodedQuery

                    //You can log the path here
                    //Generally the path consists of the link extracted 
                    //from the deep link

                    val parts = path?.split("/")

                    if (parts?.get(2) == "something") {
                        val intent = Intent(this, YouActivity::class.java)
                        intent.putExtra("extra1", parts[3])
                                .putExtra("extra2", parts[1])
                        startActivity(intent)
                    } 
                }.addOnFailureListener { e -> //You can log the error here }

What have I done here?

First I created the instance of FirebaseDynamicLinks. Next, I used the fetched dynamic link data to extract the link (deepLink?.path) which is the link that opens a specific page on my website (say an article). Then, I split the link into pieces and used them as the information (the extras in the intent) to send to my activity and load the required data.

You can do this for all kinds of links. Receive the data on a receiving activity and redirect from there to any activity depending upon the data received.

I hope this helped to resolve your issue. Let me know if there is any confusion.

Thanks