Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
p x
GeelyHMIWeb
Commits
6704f076
Commit
6704f076
authored
Jan 06, 2026
by
p x
Browse files
添加加载网页的方式
parent
5b3f0dc5
Changes
6
Hide whitespace changes
Inline
Side-by-side
app/src/main/AndroidManifest.xml
View file @
6704f076
...
...
@@ -5,6 +5,9 @@
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.ACCESS_FINE_LOCATION"
/>
<uses-permission
android:name=
"android.permission.ACCESS_COARSE_LOCATION"
/>
<uses-permission
android:name=
"android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore=
"ScopedStorage"
/>
...
...
app/src/main/java/com/sd/geelyhmiweb/JsApi.kt
View file @
6704f076
package
com.sd.geelyhmiweb
import
android.util.Log
import
android.webkit.JavascriptInterface
import
androidx.lifecycle.MutableLiveData
import
com.sd.geelyhmiweb.dsbridge.CompletionHandler
import
com.sd.geelyhmiweb.utils.
FileIo
Utils
import
com.sd.geelyhmiweb.utils.
Location
Utils
import
com.sd.geelyhmiweb.viewmodels.MainVM
class
JsApi
{
var
mainVM
:
MainVM
?=
null
var
mainVM
:
MainVM
?
=
null
//定位字符串
var
locStr
=
MutableLiveData
(
""
)
//同步API
@JavascriptInterface
fun
testSyn
(
msg
:
Object
):
String
{
return
msg
.
toString
()
+
"[syn call]"
fun
synLoc
(
arg
:
Any
,
handler
:
CompletionHandler
<
String
>)
{
LocationUtils
.
getInstan
().
onJsLoc
=
object
:
LocationUtils
.
OnJsLoc
{
override
fun
onJsLoc
(
str
:
String
)
{
// handler.complete(str);
// Log.d("------------js 调用 Android 获取异步位置=", str);
locStr
.
postValue
(
str
)
}
}
LocationUtils
.
getInstan
().
getLocation
()
}
//异步API
@JavascriptInterface
fun
testAsyn
(
msg
:
Object
,
handler
:
CompletionHandler
<
String
?
>
)
{
handler
.
complete
(
msg
.
toString
()
+
" [ asyn call]"
)
fun
stopLoc
(
arg
:
Any
?
)
{
LocationUtils
.
getInstan
().
stopLoc
(
)
}
@JavascriptInterface
fun
writeLog
(
msg
:
Object
)
{
// println("------------writeLog ${msg}")
...
...
@@ -30,4 +39,20 @@ class JsApi {
// FileIoUtils.writeToFile(gson.toJson(perceptionBean), "PerTarget_15_move.txt")
}
/* //同步API
@JavascriptInterface
fun testSyn(msg: Object): String {
return msg.toString() + "[syn call]"
}
//异步API
@JavascriptInterface
fun testAsyn(msg: Object, handler: CompletionHandler<String?>) {
handler.complete(msg.toString() + " [ asyn call]")
}*/
}
\ No newline at end of file
app/src/main/java/com/sd/geelyhmiweb/MainActivity.kt
View file @
6704f076
...
...
@@ -6,49 +6,54 @@ import android.util.Log
import
android.webkit.ConsoleMessage
import
android.webkit.SslErrorHandler
import
android.webkit.WebChromeClient
import
android.webkit.WebResourceError
import
android.webkit.WebResourceRequest
import
android.webkit.WebResourceResponse
import
android.webkit.WebSettings
import
android.webkit.WebView
import
android.webkit.WebViewClient
import
androidx.activity.viewModels
import
androidx.appcompat.app.AppCompatActivity
import
androidx.webkit.WebResourceErrorCompat
import
androidx.webkit.WebViewAssetLoader
import
androidx.webkit.WebViewClientCompat
import
com.sd.geelyhmiweb.databinding.ActivityMainBinding
import
com.sd.geelyhmiweb.dsbridge.OnReturnValue
import
com.sd.geelyhmiweb.utils.LocationUtils
import
com.sd.geelyhmiweb.utils.MyContants
import
com.sd.geelyhmiweb.viewmodels.MainVM
import
dagger.hilt.android.AndroidEntryPoint
import
kotlin.getValue
@AndroidEntryPoint
class
MainActivity
:
AppCompatActivity
()
{
override
fun
onDestroy
()
{
super
.
onDestroy
()
LocationUtils
.
getInstan
().
stopLoc
()
binding
.
dwebview
.
destroy
()
}
private
lateinit
var
binding
:
ActivityMainBinding
private
val
mainVM
:
MainVM
by
viewModels
()
private
lateinit
var
assetLoader
:
WebViewAssetLoader
override
fun
onDestroy
()
{
super
.
onDestroy
()
binding
.
dwebview
.
destroy
()
}
private
val
jsApi
=
JsApi
()
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
binding
=
ActivityMainBinding
.
inflate
(
layoutInflater
)
setContentView
(
binding
.
root
)
initWeb
()
}
LocationUtils
.
setLocManager
(
this
)
fun
initWeb
()
{
var
jsApi
=
JsApi
()
// LocationUtils.getInstan().getLocation()
jsApi
.
mainVM
=
mainVM
initWeb
()
initLis
()
}
private
fun
initWeb
()
{
assetLoader
=
WebViewAssetLoader
.
Builder
()
.
setHttpAllowed
(
true
)
.
addPathHandler
(
"/assets/"
,
WebViewAssetLoader
.
AssetsPathHandler
(
this
))
...
...
@@ -63,25 +68,37 @@ class MainActivity : AppCompatActivity() {
javaScriptEnabled
=
true
javaScriptCanOpenWindowsAutomatically
=
true
loadWithOverviewMode
=
true
cacheMode
=
WebSettings
.
LOAD_DEFAULT
domStorageEnabled
=
true
databaseEnabled
=
true
// 关键:禁用文件访问,强制走 AssetLoader 路由
setAllowFileAccess
(
false
)
setAllowContentAccess
(
false
)
setAllowFileAccessFromFileURLs
(
false
)
setAllowUniversalAccessFromFileURLs
(
false
)
if
(
MyContants
.
LOAD_WEB_FILE
==
1
)
{
setAllowFileAccess
(
true
)
setAllowContentAccess
(
true
)
setAllowFileAccessFromFileURLs
(
true
)
setAllowUniversalAccessFromFileURLs
(
true
)
}
else
if
(
MyContants
.
LOAD_WEB_FILE
==
2
)
{
setAllowFileAccess
(
false
)
setAllowContentAccess
(
false
)
setAllowFileAccessFromFileURLs
(
false
)
setAllowUniversalAccessFromFileURLs
(
false
)
}
// 混合内容模式(若前端有 HTTP 资源,需配置;正式环境建议仅 HTTPS)
setMixedContentMode
(
WebSettings
.
MIXED_CONTENT_ALWAYS_ALLOW
)
// 关键:禁用WebView的DNS缓存,强制走拦截逻辑
setCacheMode
(
WebSettings
.
LOAD_NO_CACHE
)
// 禁用网络加载(仅加载本地资产)
blockNetworkLoads
=
true
//
blockNetworkLoads = true
}
val
url
=
"file:///android_asset/dist/index.html"
// val url = "http://192.168.60.155:5173/"
val
websiteUrl
=
"http://appassets.androidplatform.net/assets/dist/index.html"
binding
.
dwebview
.
loadUrl
(
websiteUrl
)
var
url
=
if
(
MyContants
.
LOAD_WEB_FILE
==
1
)
{
"file:///android_asset/dist/index.html"
}
else
{
websiteUrl
}
binding
.
dwebview
.
loadUrl
(
url
)
binding
.
dwebview
.
webViewClient
=
object
:
WebViewClientCompat
()
{
override
fun
shouldInterceptRequest
(
...
...
@@ -93,8 +110,13 @@ class MainActivity : AppCompatActivity() {
// headers.put("sec-ch-ua-platform", "")
// headers.put("","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0")
// 优先拦截虚拟域名请求
return
assetLoader
.
shouldInterceptRequest
(
request
.
url
)
// return super.shouldInterceptRequest(view, request)
if
(
MyContants
.
LOAD_WEB_FILE
==
1
){
return
super
.
shouldInterceptRequest
(
view
,
request
)
}
else
if
(
MyContants
.
LOAD_WEB_FILE
==
2
){
return
assetLoader
.
shouldInterceptRequest
(
request
.
url
)
}
else
{
return
assetLoader
.
shouldInterceptRequest
(
request
.
url
)
}
}
override
fun
onReceivedHttpError
(
...
...
@@ -105,6 +127,14 @@ class MainActivity : AppCompatActivity() {
super
.
onReceivedHttpError
(
view
,
request
,
errorResponse
)
}
override
fun
onReceivedError
(
view
:
WebView
,
request
:
WebResourceRequest
,
error
:
WebResourceErrorCompat
)
{
super
.
onReceivedError
(
view
,
request
,
error
)
}
override
fun
onReceivedSslError
(
view
:
WebView
?,
handler
:
SslErrorHandler
?,
...
...
@@ -120,7 +150,7 @@ class MainActivity : AppCompatActivity() {
override
fun
onConsoleMessage
(
message
:
ConsoleMessage
?):
Boolean
{
Log
.
d
(
"---
pxl
"
,
"---
onConsoleMessage
"
,
"${message?.message()} -- From line "
+
"${message?.lineNumber()} of ${message?.sourceId()}"
)
return
true
...
...
@@ -130,4 +160,19 @@ class MainActivity : AppCompatActivity() {
}
private
fun
initLis
()
{
jsApi
.
locStr
.
observe
(
this
)
{
// handler.complete(str);
// Log.d("------------上报异步位置", it)
binding
.
dwebview
.
callHandler
(
"retLoc"
,
arrayOf
<
String
>(
it
),
OnReturnValue
<
String
>
{
retValue
->
/* Log.d(
"---jsbridge",
"call succeed,return value is $retValue"
)*/
})
}
}
}
\ No newline at end of file
app/src/main/java/com/sd/geelyhmiweb/ui/BootActivity.kt
View file @
6704f076
...
...
@@ -26,11 +26,10 @@ class BootActivity : AppCompatActivity() {
binding
=
ActivityBootBinding
.
inflate
(
layoutInflater
)
// enableEdgeToEdge()
setContentView
(
binding
.
root
)
// ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
// val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
// v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
// insets
// }
requestPers
()
}
private
fun
jumpMain
()
{
if
(
isAvp
)
{
startActivity
(
Intent
(
this
,
MainActivity
::
class
.
java
))
}
else
{
...
...
@@ -38,8 +37,11 @@ class BootActivity : AppCompatActivity() {
}
}
fun
requestPers
()
{
var
pers
=
mutableListOf
<
String
>()
private
fun
requestPers
()
{
val
pers
=
mutableListOf
(
Manifest
.
permission
.
ACCESS_FINE_LOCATION
,
Manifest
.
permission
.
ACCESS_COARSE_LOCATION
)
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
R
)
{
pers
.
add
(
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
)
pers
.
add
(
Manifest
.
permission
.
MANAGE_EXTERNAL_STORAGE
)
...
...
@@ -48,26 +50,27 @@ class BootActivity : AppCompatActivity() {
}
PermissionX
.
init
(
this
)
.
permissions
(
pers
)
.
onExplainRequestReason
{
scope
,
deniedList
->
scope
.
showRequestReasonDialog
(
deniedList
,
"需要同意以下授权才能正常使用"
,
"好的"
,
"取消"
)
}
//
.onExplainRequestReason { scope, deniedList ->
//
scope.showRequestReasonDialog(
//
deniedList,
//
"需要同意以下授权才能正常使用",
//
"好的",
//
"取消"
//
)
//
}
// .onForwardToSettings { scope, deniedList ->
// scope.showForwardToSettingsDialog(deniedList, "您需要手动在‘设置’中允许必要的权限", "OK", "Cancel")
// }
.
request
{
allGranted
,
grantedList
,
deniedList
->
if
(
allGranted
)
{
//
if (allGranted) {
// ToastHelper.showShort(this, "All permissions are granted")
}
else
{
ToastHelper
.
showShort
(
this
,
"权限被拒"
)
binding
.
root
.
postDelayed
({
finish
()
},
150
)
}
jumpMain
()
// } else {
//// ToastHelper.showShort(this, "权限被拒")
//// binding.root.postDelayed({
//// finish()
//// }, 150)
// }
}
}
...
...
app/src/main/java/com/sd/geelyhmiweb/utils/LocationUtils.kt
0 → 100644
View file @
6704f076
package
com.sd.geelyhmiweb.utils
import
android.annotation.SuppressLint
import
android.content.Context
import
android.location.Location
import
android.location.LocationListener
import
android.location.LocationManager
import
android.util.Log
class
LocationUtils
{
companion
object
{
private
var
instance
:
LocationUtils
?
=
null
fun
setLocManager
(
mContext
:
Context
)
{
if
(
instance
==
null
)
{
instance
=
LocationUtils
(
mContext
)
}
}
fun
getInstan
():
LocationUtils
{
return
instance
!!
}
}
private
lateinit
var
locationManager
:
LocationManager
private
var
locationProvider
:
String
=
""
private
var
location
:
Location
?
=
null
// private lateinit var locationUtils: LocationUtils
// mContext: Context
private
constructor
()
constructor
(
mContext
:
Context
)
{
locationManager
=
mContext
.
getSystemService
(
Context
.
LOCATION_SERVICE
)
as
LocationManager
}
@SuppressLint
(
"MissingPermission"
)
fun
getLocation
()
{
//1.获取位置管理器
// locationManager = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
//2.获取位置提供器,GPS或是NetWork
if
(
getProvider
().
isNullOrEmpty
())
{
return
}
if
(
location
!=
null
)
{
setLocation
(
location
!!
)
}
// 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
locationManager
.
requestLocationUpdates
(
locationProvider
,
1
,
0f
,
locationListener
)
}
@SuppressLint
(
"MissingPermission"
)
fun
getLastLocation
():
String
{
//1.获取位置管理器
// locationManager = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
//2.获取位置提供器,GPS或是NetWork
if
(
getProvider
().
isNullOrEmpty
())
{
return
""
}
var
locate
=
locationManager
?.
getLastKnownLocation
(
locationProvider
)
if
(
locate
!=
null
)
{
setLocation
(
locate
)
}
return
locate
?.
latitude
.
toString
()
+
" "
+
locate
?.
longitude
.
toString
()
}
private
fun
getProvider
():
String
{
val
providers
:
List
<
String
>
=
locationManager
.
getProviders
(
true
)
if
(
providers
.
contains
(
LocationManager
.
NETWORK_PROVIDER
))
{
//如果是网络定位
// Log.d("TAG", "如果是网络定位")
locationProvider
=
LocationManager
.
NETWORK_PROVIDER
}
else
if
(
providers
.
contains
(
LocationManager
.
GPS_PROVIDER
))
{
//如果是GPS定位
// Log.d("TAG", "如果是GPS定位")
locationProvider
=
LocationManager
.
GPS_PROVIDER
}
else
{
Log
.
d
(
"TAG"
,
"没有可用的位置提供器"
)
return
""
}
return
locationProvider
}
//获取经纬度
fun
showLocation
(
mContext
:
Context
):
Location
?
{
return
location
}
private
fun
setLocation
(
location
:
Location
)
{
this
.
location
=
location
val
loc
=
"${location.longitude} ${location.latitude}"
onJsLoc
?.
onJsLoc
(
loc
)
}
//定位监听
private
var
locationListener
=
object
:
LocationListener
{
override
fun
onLocationChanged
(
location
:
Location
)
{
// location.getAccuracy()//精确度
// Log.d("------", "定位改变: $location")
setLocation
(
location
)
}
}
//JS 定位回调
var
onJsLoc
:
OnJsLoc
?
=
null
interface
OnJsLoc
{
fun
onJsLoc
(
str
:
String
)
}
/***停止定位**/
fun
stopLoc
()
{
if
(
locationManager
!=
null
)
{
locationManager
.
removeUpdates
(
locationListener
)
}
}
}
\ No newline at end of file
app/src/main/java/com/sd/geelyhmiweb/utils/MyContants.kt
View file @
6704f076
...
...
@@ -3,6 +3,14 @@ package com.sd.geelyhmiweb.utils
object
MyContants
{
const
val
IS_DEBUG
=
true
var
HOST
=
if
(
IS_DEBUG
)
"http://laravel.suiyigou.shop/"
else
"https://api.suixinsuiyi.cn/"
/**
* 加载webview 的方式
* 1 = Cesium
* 2 = ThreeJS
*/
var
LOAD_WEB_FILE
=
1
// var PORT = if (IS_DEBUG) "123" else "34534"
// var SOCKET_HOSTNAME =
...
...
@@ -11,5 +19,4 @@ object MyContants {
// if (IS_DEBUG) 8082 else 0
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment