Search code examples
androidkotlinandroid-webviewdeep-linking

Deep-linking not fired from WebView


I'm trying to fire the deep-linking in my Android application from the application WebView but instead of firing the ACTION_VIEW intent i get ERR_UNKNORN_URL_SCHEME, the website tries to make a window.location.href = app://ls.mydomain.it/?key=XXX.

The WebView is load in a Fragment like this:

    binding.webview.settings.javaScriptEnabled = true
    binding.webview.settings.loadWithOverviewMode = true
    binding.webview.webViewClient = object : WebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView?,request: WebResourceRequest?): Boolean {
            return false
        }
    }
    binding.webview.settings.domStorageEnabled = true
    binding.webview.loadUrl("https://ls.mydomain.it/?deviceId=${deviceId}")

I have added the deep-linking in the Manifest:

    <activity
        android:name=".ui.components.home.HomeActivity"
        android:exported="true"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.App.Starting"
        android:windowSoftInputMode="adjustPan"
        android:launchMode="singleTask"
        tools:ignore="LockedOrientationActivity">
        <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.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data android:scheme="app" android:host="ls.mydomain.it" />
        </intent-filter>
    </activity>

And then override the intent in the Activity:

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)

    if (intent?.action == Intent.ACTION_VIEW) {
        val data: Uri? = intent.data
        newLicense(data)
    }
}

Solution

  • I've solved the issue by calling the startActivity with ACTION_VIEW intent which contains the deep-link URI by overriding the shouldOverrideUrlLoading

    The WebViewClient looks like this now:

        binding.webview.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?,request: WebResourceRequest?): Boolean {
                val url = request?.url.toString()
                if (url.startsWith("app://")) {
                    try {
                        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply {
                            addCategory(Intent.CATEGORY_BROWSABLE)
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER or
                                        Intent.FLAG_ACTIVITY_REQUIRE_DEFAULT
                            }
                        }
                        startActivity(intent)
                    } catch (e: ActivityNotFoundException) {
                        showToast("Non è stato possibile attivare la licenza, contattare l'assistenza")
                    }
                    return true
                }
    
                return false
            }
        }
    

    With FLAG_ACTIVITY_REQUIRE_NON_BROWSER and FLAG_ACTIVITY_REQUIRE_DEFAULT flags the intent will match only the URI that matches the application deep-linking.

    Source