Deep Linking In Flutter - Part 2

Deep Linking In Flutter - Part 2

In the previous article we went through how to setup and handle deep links for a flutter app. In this article we'll be covering android app links and iOS universal links. But we'll only be setting up app links.

App links and Universal links are special types of deep linking that allows users to tap on a website URL and get redirected to your installed app without any dialog from the device OS. And in a situation the app isn't installed it then opens the link through the device browser.

To enable these features the device OS must be able to verify that you own both your app and the website URLs. If the system successfully verifies that you own the URLs, the system automatically routes those URL intents to your app.

On android, app links are supported from Android 6.0 and higher. while regular deep links are supported on all android version. And for iOS versions earlier than 9.0, tapping a universal link opens the link in Safari.

Advantages

Android app links and iOS universal links offer the following advantages over regular deep links and custom URL schemes:

  • It is unique: Unlike deep links and custom URL schemes, app links and universal links can’t be claimed by other apps, because they use standard HTTP or HTTPS links to your website. So you cant have multiple apps on the device that handle the same deep link.
  • It is secure: When users install your app, the device OS verifies the link specified by a JSON file on your web server to make sure that your website allows your app to open URLs on its behalf. Only you can create and upload this file, so the association of your website with your app is secure.
  • It has a better user experience: No dialog, your app opens to handle your website links. When your app isn’t installed, tapping a link to your website opens it on the browser.

To verify ownership of both your app and your website, the following steps are required:

Step One

Request automatic app link verification in your manifest. This signals to the Android system that it should verify your app belongs to the URL domain used in your intent filters. The only change in the manifest file from when we implemented regular deep links would be the android:autoVerify="true" in the 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="https"
                  android:host="ifeanyi.web.app" />
</intent-filter>

Step Two

Declare the relationship between your website and your intent filters by publishing a Digital Asset Links JSON file to indicate the Android app(s) that are associated with the website. The JSON contains the following fields which it uses to identify associated apps:

  • package_name: This can be found in your AndroidManifest.xml file. For example
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.deeplink">
  • sha256_cert_fingerprints: The SHA256 fingerprints of your app’s signing certificate. This can be generated via the Java keytool. For this you should have the java jdk already installed. Navigate to bin folder where the jdk is stored. for me this was C:\Program Files\Java\jdk-14.0.1\bin . Once you're at this folder click on the folder path above, type in CMD and press enter. This should open the path on your command prompt. From CMD run the following command, replacing "C:\Users\ifeanyi" with the path to your user directory.

For windows

keytool -list -v -alias androiddebugkey -keystore C:\Users\ifeanyi\.android\debug.keystore

For Mac/Linux

keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore

This command prompts you to enter a password for the keystore. The default password for the debug keystore is android. So type in android and press enter.

As you type the password it doesn't actually get displayed on the console so don't stress about it like me. Just type it and press enter

This then prints out information about the key store on the console, among these would be the sha256 certificate which looks like this

SHA256: DA:39:A3:EE:5E:6B:4B:0D:32:55:BF:EF:95:60:18:90:AF:D8:07:09:C9:E8:33:7E:64:64:C9:01:7C:45:0E:29

Now that we have our package name and sha256 fingerprints this is what the content of the assetlinks.json file would look like

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.deeplink",
    "sha256_cert_fingerprints":
    ["DA:39:A3:EE:5E:6B:4B:0D:32:55:BF:EF:95:60:18:90:AF:D8:07:09:C9:E8:33:7E:64:64:C9:01:7C:45:0E:29"]
  }
}]

Step Three

Publish your Digital Asset Links JSON verification file at the following location / subdomain. .well-known/assetlinks.json

https://domain.name/.well-known/assetlinks.json

When implementing the app linking feature, you should test the linking functionality to make sure the system can associate your app with your websites, and handle URL requests, as you expect.

There are multiple ways to test that everything worked out fine

  • To test that the file was uploaded to the right subdomain and can be accessed by your app for verification, you can use the Google Digital Asset Link Tester tool. This can also be used to generate the json file by providing it with the required information.

  • Once you have confirmed that the hosted JSON file is valid, install the app on your device. Wait at least 20 seconds for the asynchronous verification process to complete. Then check whether the device OS verified your app and set the correct link handling policies. To do this you can navigate through the file manager to where you stored the android SDK on your system and open platform tools. For me it looked like this C:\Users\ifeanyi\AppData\Local\Android\Sdk\platform-tools . Then select the path tab above, type in CMD and press enter. The command prompt should then open with the platform-tools directory. Then run the command with the domain name used and an optional port while your emulator/device is connected.

adb shell am start -a android.intent.action.VIEW –c android.intent.category.BROWSABLE -d "http://<domain.name>:<optional_port>"
  • As part of your testing process, you can check the current system settings for link handling. Use the following command to get a listing of existing link-handling policies for all apps on your connected device. While still in the platform-tools directory used above, run the following command
adb shell dumpsys package domain-preferred-apps

This command prints out a list of apps on the device, with the links they handle and the link handling status. For an app that passed verification the status would be "always". For example

Package: com.example.deeplink
Domains: ifeanyi.web.app
Status: always : 200000002

Conclusion

On the flutter side the implementation used to handle the incoming links in the previous article doesn't have to change. And the only thing that changed in the manifest was just a single line.

With App Links what we really do is enable the device verify an association between our app and the website URL.

For now I haven't actually implemented this feature on iOS but lookin through the Docs it follows a similar process. So you can expect an article from me once I do.

Thanks for reading

The Full Code for the previous article is available on GitHub

For more info on android App Links you can visit the Android developer guide

For more info on Uni Link package you can check it out on pub dev.