# iot-android-h5-demo **Repository Path**: Mihok/iot-android-h5-demo ## Basic Information - **Project Name**: iot-android-h5-demo - **Description**: 安卓APP中,H5 支付和唤端 demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2025-05-09 - **Last Updated**: 2025-05-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # IOT H5 Demo > 本项目为【安卓APP webview 接入喜马拉雅内容 H5 页面】提供配置参考,包括 scheme 唤端、喜马支付、H5 样式等问题。 ## scheme 唤端 + 支付 如果要拉起微信或支付宝支付,需要 APP 支持 scheme 唤端。拉起微信支付还需要配置 webview 的 Referer 头 ```kt @Composable fun WebViewContent(url: String, modifier: Modifier = Modifier) { val context = LocalContext.current AndroidView( factory = { ctx -> WebView(ctx).apply { webViewClient = object : WebViewClient() { @Deprecated("Deprecated in Java") override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return handleUrl(url) } @RequiresApi(Build.VERSION_CODES.N) override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { return handleUrl(request?.url?.toString()) } private fun handleUrl(url: String?): Boolean { url?.let { if (it.startsWith("http://") || it.startsWith("https://")) { if (it.startsWith("https://wx.tenpay.com")) { loadUrl(it, mapOf("Referer" to "https://m.ximalaya.com")) return true } return false } try { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(it)) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) } catch (e: Exception) { e.printStackTrace() // 可以在这里添加错误处理,比如显示一个提示信息 } return true } return false } override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) { handler?.proceed() } } webChromeClient = WebChromeClient() settings.apply { javaScriptEnabled = true domStorageEnabled = true databaseEnabled = true useWideViewPort = true loadWithOverviewMode = true if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW } } loadUrl(url) } }, modifier = modifier.fillMaxSize() ) } ``` 主要的变更点如下: 1. 在 `WebViewContent` 函数中,我们添加了 `val context = LocalContext.current` 来获取当前的 Context。 2. 我们创建了一个新的私有方法 `handleUrl`,它处理所有的 URL 加载请求。 3. 在 `handleUrl` 方法中: - 如果 URL 是普通的 http 或 https 链接,我们检查它是否是 "",如果是,我们添加 Referer 头并加载 URL。 - 对于其他 http 或 https 链接,我们返回 false,让 WebView 正常加载。 - 对于非 http(s) 链接(可能是自定义 scheme),我们尝试创建一个 Intent 来打开它。这将尝试启动能够处理这个 scheme 的应用。 4. 我们在 `shouldOverrideUrlLoading` 方法中调用 `handleUrl` 方法。 5. 如果没有应用能够处理这个 scheme,将会抛出异常。我们在 catch 块中处理这个异常,您可以在这里添加一些错误处理逻辑,比如显示一个提示信息。 这个实现会尝试打开任何非 http(s) 的 URL,同时保持了对 "" 的特殊处理。 请注意,从 Android 11(API 级别 30)开始,应用需要在 manifest 文件中声明它打算使用的所有自定义 scheme。如果您的应用需要支持特定的自定义 scheme,您需要在 manifest 文件中添加相应的声明: ```xml ``` ### 支付问题 #### 1. 微信支付提示`商家参数格式有误` 解决方案:请检查是否为 添加了 Referer 头 #### 2. 支付宝支付提示 'alipay(s): //xxx' 链接打不开 解决方案:为 APP 添加 scheme 唤端支持 ## 样式问题 ### 1. H5 订单页头部导航栏重复,出现两个导航栏 解决方案:针对指定页面,注入 js 的方式去除页面头部元素 ```java override fun onPageFinished(view: WebView?, url: String?) { if (url?.contains("trade-v3/settlement/orderview") == true) { view?.evaluateJavascript( "document.querySelector('.header').style.display='none';document.querySelector('header').style.display='none';document.querySelector('.view').style.paddingTop='6px';", null ) } super.onPageFinished(view, url) } ``` ### 2. H5 非订单页导航栏和APP导航栏重复,出现两个导航栏 解决方案: - 原生同学去除 webview 容器的 topBar,或者去除页面容器的 topBar,保留 webview 容器的 topBar - 在 webview 次级页面中拦截后退事件,使其返回上一页 详见本仓库[示例代码](https://gitee.com/guangmeng/iot-android-h5-demo/blob/master/app/src/main/java/com/example/ioth5demo/MainActivity.kt) ### 3. H5 首页出现后退按钮 ```java Scaffold( topBar = { TopAppBar( title = { Text(pageTitle) }, navigationIcon = { // 在次级页面才展示后退按钮 if (canGoBack) { IconButton(onClick = { currentWebView?.goBack() }) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back") } } } ) } ) ``` ## 手机号自动登录 在加载 h5 项目时,带上 `phone=手机号` 即可免登录,参数内容不需要加密,例如: