Make deep links play well with the rest of your app

Michael Münzer
EGYM Software Development
4 min readApr 20, 2017

--

During the last year we touched the code of our deep linking implementation a couple of times. Changing requirements in eGym’s Fitness-app required us to allow deep linking for a variety of use-cases. The main objective was making the app’s download and user experience as smooth as possible.

We started off with our first use-case about a year ago, when developers from partner applications demanded the functionality to open or download our product from within their Android application. Starting with a very simple solution, partner applications were routing to us via a code-snippet like the following:

This worked fine for us and did not even require uploading a new APK to the Play Store.

Soon after providing this code-snippet to partners, requirements changed and we decided to extend our deep-linking functionality. For more granular routing we wanted to offer screen specific linking as well. Partner applications are then, for example, able to redirect the user to the ranking screen within our application as well. To allow this, we implemented our own application schema, which can be used by other applications.

During that time, there was an increasing demand from the marketing department to open specific screens from email marketing campaigns as well. We first tried to use the schema links we already got in MailChimp. This did not work as MailChimp just allows https-links from within their mail templates. This lead us to use https links for screen specific redirects. Another benefit of using https links is that we can use the same link for the web-page and our Android application.

While supporting our own schema and https, we came up with the following code in our AndroidManifest.xml.

The RankingActivity can then be opened with the following links:

Note that using two <data/> tags in the same <intent-filter/> block does not seem to be supported by the framework. Therefore we needed to use the more extensive approach with two almost identical intent filters.

So far everything looks good, BUT as always in software development we ran into a couple of problems:

  • Redirection does not yet work for screens which require user credentials. In our application almost any screen needs user-specific data that is fetched from an API. Therefore we need to authenticate the user before redirecting him to another screen.
  • When the user enters a screen via deep link, pressing back leads to the source of the link. It might be unintended behaviour. Instead keeping the user within the application was the goal for us.

Authenticate the user before redirection

Very often we need to authenticate the user before screen redirection can take place. To solve this obstacle we decided to include a login-check in our BaseDeepLinkActivity.java. This activity is meant to deal with every incoming deep link and do a proper redirection to the LoginActivity.java if the user is not logged in. Every activity which wants to handle deep-links (e.g. RankingActivity.java) has to inherit from BaseDeepLinkActivity.java in our application.

So what exactly do we want to achieve when the user calls a specific deep link (e.g. https://www.webpage.com/ranking)?

  • Logged-in users get redirected to the deep link activity (RankingActivity.java which inherits from BaseDeepLinkActivity.java) because the RankingActivity.java is associated to the schema in the AndroidManifest.xml.
  • Not logged-in users get redirected to the LoginActivity.java. After a successful login, the user gets redirected to the previously intended activity, which has not been shown yet (RankingActivity.java).

We handle these cases in the onCreate() and onNewIntent() of our BaseDeepLinkActivity.java. We include it twice to make sure that singleInstance activities are handled as well.

The LoginActivity.java essentially just stores the redirectionDeepLink until the user logs-in successfully. When he does so, we pass the link as data within the next intent. This intent eventually ends up in the BaseDeepLinkActivity.java and is handled there.

On Samsung devices we experienced a problem when passing https links from one activity to another. When opening the https-link after it has been passed to the second activity, the browser is opened instead of the activity. We came around that issue by setting the application id as the package for the intent:

intent.setPackage(BuildConfig.APPLICATION_ID);

Building a back-stack after deep linking

When opening a screen via deep link, the back button automatically brings the user to where the link originated. In our application, some screens (when used without deep links) do not offer any other possibility to navigate inside the application besides the back button (action-bar and navigation button).

Without a custom back-stack implementation we will end-up losing the user even when he wants to continue using our application. Therefore we decided to override the default Android behaviour and create a back-stack on our own.

Therefore we override onBackPressed() within the BaseDeepLinkActivity.java and create a back-stack based on parent activities defined in the AndroidManifest.xml.

To associate the back press with the fact that the activity has been opened with a deep-link we use mStartedFromDeepLink which gets set in isDeepLinkDataPresent().

Thanks for reading. I hope you found our first experiences using deep-links interesting. Stay tuned as we will continue writing about Firebase dynamic links soon.

If you found it helpful, please click ❤ to recommend this article to others.

--

--