Implementation of Android App Links in Open Event Organizer App
Android App Links are HTTP URLs that bring users directly to specific content in an Android app. They allow the website URLs to immediately open the corresponding content in the related Android app.
Whenever such a URL is clicked, a dialog is opened allowing the user to select a particular app which can handle the given URL.
In this blog post, we will be discussing the implementation of Android App Links for password reset in Open Event Organizer App, the Android app developed for event organizers using the Eventyay platform.
What is the purpose of using App Links?
App Links are used to open the corresponding app when a link is clicked.
- If the app is installed, then it will open on clicking the link.
- If app is not installed, then the link will open in the browser.
The first steps involve:
- Creating intent filters in the manifest.
- Adding code to the app’s activities to handle incoming links.
- Associating the app and the website with Digital Asset Links.
Adding Android App Links
First step is to add an intent-filter for the AuthActivity.
<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="https"
android:host="@string/FRONTEND_HOST"
android:pathPrefix="/reset-password" />
</intent-filter>
Here, FRONTEND_HOST is the URL for the web frontend of the Eventyay platform.
This needs to be handled in AuthActivity:
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); handleIntent(intent); }
private void handleIntent(Intent intent) { String appLinkAction = intent.getAction(); Uri appLinkData = intent.getData(); if (Intent.ACTION_VIEW.equals(appLinkAction) && appLinkData != null) { LinkHandler.Destination destination = LinkHandler.getDestinationAndToken(appLinkData.toString()).getDestination(); String token = LinkHandler.getDestinationAndToken(appLinkData.toString()).getToken(); if (destination.equals(LinkHandler.Destination.RESET_PASSWORD)) { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, ResetPasswordFragment.newInstance(token)) .commit(); } } }
Call the handleIntent() method in onCreate():
handleIntent(getIntent());
Get the token in onCreate() method of ResetPasswordFragment:
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) token = getArguments().getString(TOKEN_KEY); }
Set the token in ViewModel:
if (token != null)
resetPasswordViewModel.setToken(token);
The setToken() method in ViewModel:
if (token != null)
resetPasswordViewModel.setToken(token);
LinkHandler class for handling the links:
package com.eventyay.organizer.utils; public class LinkHandler { public Destination destination; public String token; public LinkHandler(Destination destination, String token) { this.destination = destination; this.token = token; } public static LinkHandler getDestinationAndToken(String url) { if (url.contains("reset-password")) { String token = url.substring(url.indexOf('=') + 1); return new LinkHandler(Destination.RESET_PASSWORD, token); } else if (url.contains("verify")) { String token = url.substring(url.indexOf('=') + 1); return new LinkHandler(Destination.VERIFY_EMAIL, token); } else return null; } public Destination getDestination() { return destination; } public String getToken() { return token; } public enum Destination { VERIFY_EMAIL, RESET_PASSWORD } }
enum is used to handle links for both, password reset as well as email verification.
Finally, the unit tests for LinkHandler:
package com.eventyay.organizer.utils; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import static org.junit.Assert.assertEquals; @RunWith(JUnit4.class) public class LinkHandlerTest { private String resetPassUrl = "https://eventyay.com/reset-password?token=12345678"; private String verifyEmailUrl = "https://eventyay.com/verify?token=12345678"; @Test public void shouldHaveCorrectDestination() { assertEquals(LinkHandler.Destination.RESET_PASSWORD, LinkHandler.getDestinationAndToken(resetPassUrl).getDestination()); assertEquals(LinkHandler.Destination.VERIFY_EMAIL, LinkHandler.getDestinationAndToken(verifyEmailUrl).getDestination()); } @Test public void shouldGetPasswordResetToken() { assertEquals(LinkHandler.Destination.RESET_PASSWORD, LinkHandler.getDestinationAndToken(resetPassUrl).getDestination()); assertEquals("12345678", LinkHandler.getDestinationAndToken(resetPassUrl).getToken()); } @Test public void shouldGetEmailVerificationToken() { assertEquals(LinkHandler.Destination.VERIFY_EMAIL, LinkHandler.getDestinationAndToken(verifyEmailUrl).getDestination()); assertEquals("12345678", LinkHandler.getDestinationAndToken(verifyEmailUrl).getToken()); } }
Resources:
Documentation: Link
Further reading: Android App Linking
Pull Request: feat: Add app link for password reset
Open Event Organizer App: Project repo, Play Store, F-Droid