英文:
Deep-linking not fired from WebView
问题
I understand your request. Here is the translation of the code you provided:
我正在尝试从应用程序的 WebView 中触发我的Android应用程序中的深层链接,但是在触发 ACTION_VIEW 意图时,我收到了 `ERR_UNKNORN_URL_SCHEME` 错误,该网站试图执行 `window.location.href = app://ls.mydomain.it/?key=XXX`。
WebView 在 Fragment 中加载如下:
        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}")
我已经在清单中添加了深层链接:
        <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>
然后在 Activity 中覆盖了意图:
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        if (intent?.action == Intent.ACTION_VIEW) {
            val data: Uri? = intent.data
            newLicense(data)
        }
    }
Is there anything else you would like to know or clarify?
英文:
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)
    }
}
答案1
得分: 0
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.
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论