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
ShuDaoPathWeb
Commits
5616a99e
Commit
5616a99e
authored
Jun 06, 2025
by
p x
Browse files
first
parent
67ef9b69
Pipeline
#3086
failed with stages
in 0 seconds
Changes
520
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
app/src/main/java/com/sd/shupathwebview/utils/AmapUtils.java
0 → 100644
View file @
5616a99e
/**
*
*/
package
com.sd.shupathwebview.utils
;
import
java.text.SimpleDateFormat
;
import
java.util.Locale
;
import
com.amap.api.location.AMapLocation
;
import
android.content.Context
;
import
android.content.pm.PackageInfo
;
import
android.content.pm.PackageManager
;
import
android.text.TextUtils
;
/**
* 辅助工具类
* @创建时间: 2015年11月24日 上午11:46:50
* @项目名称: AMapLocationDemo2.x
* @author hongming.wang
* @文件名称: Utils.java
* @类型名称: Utils
*/
public
class
AmapUtils
{
/**
* 开始定位
*/
public
final
static
int
MSG_LOCATION_START
=
0
;
/**
* 定位完成
*/
public
final
static
int
MSG_LOCATION_FINISH
=
1
;
/**
* 停止定位
*/
public
final
static
int
MSG_LOCATION_STOP
=
2
;
public
final
static
String
KEY_URL
=
"URL"
;
public
final
static
String
URL_H5LOCATION
=
"file:///android_asset/sdkLoc.html"
;
/**
* 根据定位结果返回定位信息的字符串
* @param location
* @return
*/
public
synchronized
static
String
getLocationStr
(
AMapLocation
location
){
if
(
null
==
location
){
return
null
;
}
StringBuffer
sb
=
new
StringBuffer
();
//errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
if
(
location
.
getErrorCode
()
==
0
){
sb
.
append
(
"定位成功"
+
"\n"
);
sb
.
append
(
"定位类型: "
+
location
.
getLocationType
()
+
"\n"
);
sb
.
append
(
"经 度 : "
+
location
.
getLongitude
()
+
"\n"
);
sb
.
append
(
"纬 度 : "
+
location
.
getLatitude
()
+
"\n"
);
sb
.
append
(
"精 度 : "
+
location
.
getAccuracy
()
+
"米"
+
"\n"
);
sb
.
append
(
"提供者 : "
+
location
.
getProvider
()
+
"\n"
);
sb
.
append
(
"速 度 : "
+
location
.
getSpeed
()
+
"米/秒"
+
"\n"
);
sb
.
append
(
"角 度 : "
+
location
.
getBearing
()
+
"\n"
);
// 获取当前提供定位服务的卫星个数
sb
.
append
(
"星 数 : "
+
location
.
getSatellites
()
+
"\n"
);
sb
.
append
(
"国 家 : "
+
location
.
getCountry
()
+
"\n"
);
sb
.
append
(
"省 : "
+
location
.
getProvince
()
+
"\n"
);
sb
.
append
(
"市 : "
+
location
.
getCity
()
+
"\n"
);
sb
.
append
(
"城市编码 : "
+
location
.
getCityCode
()
+
"\n"
);
sb
.
append
(
"区 : "
+
location
.
getDistrict
()
+
"\n"
);
sb
.
append
(
"区域 码 : "
+
location
.
getAdCode
()
+
"\n"
);
sb
.
append
(
"地 址 : "
+
location
.
getAddress
()
+
"\n"
);
sb
.
append
(
"兴趣点 : "
+
location
.
getPoiName
()
+
"\n"
);
//定位完成的时间
sb
.
append
(
"定位时间: "
+
formatUTC
(
location
.
getTime
(),
"yyyy-MM-dd HH:mm:ss"
)
+
"\n"
);
}
else
{
//定位失败
sb
.
append
(
"定位失败"
+
"\n"
);
sb
.
append
(
"错误码:"
+
location
.
getErrorCode
()
+
"\n"
);
sb
.
append
(
"错误信息:"
+
location
.
getErrorInfo
()
+
"\n"
);
sb
.
append
(
"错误描述:"
+
location
.
getLocationDetail
()
+
"\n"
);
}
//定位之后的回调时间
sb
.
append
(
"回调时间: "
+
formatUTC
(
System
.
currentTimeMillis
(),
"yyyy-MM-dd HH:mm:ss"
)
+
"\n"
);
return
sb
.
toString
();
}
private
static
SimpleDateFormat
sdf
=
null
;
public
static
String
formatUTC
(
long
l
,
String
strPattern
)
{
if
(
TextUtils
.
isEmpty
(
strPattern
))
{
strPattern
=
"yyyy-MM-dd HH:mm:ss"
;
}
if
(
sdf
==
null
)
{
try
{
sdf
=
new
SimpleDateFormat
(
strPattern
,
Locale
.
CHINA
);
}
catch
(
Throwable
e
)
{
}
}
else
{
sdf
.
applyPattern
(
strPattern
);
}
return
sdf
==
null
?
"NULL"
:
sdf
.
format
(
l
);
}
/**
* 获取app的名称
* @param context
* @return
*/
public
static
String
getAppName
(
Context
context
)
{
String
appName
=
""
;
try
{
PackageManager
packageManager
=
context
.
getPackageManager
();
PackageInfo
packageInfo
=
packageManager
.
getPackageInfo
(
context
.
getPackageName
(),
0
);
int
labelRes
=
packageInfo
.
applicationInfo
.
labelRes
;
appName
=
context
.
getResources
().
getString
(
labelRes
);
}
catch
(
Throwable
e
)
{
e
.
printStackTrace
();
}
return
appName
;
}
}
app/src/main/java/com/sd/shupathwebview/utils/CustomLog.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.utils
import
android.os.Environment
import
android.util.Log
import
java.io.File
import
java.io.FileWriter
import
java.io.IOException
import
java.text.SimpleDateFormat
import
java.util.Date
object
CustomLog
{
const
val
LOG_FILE_NAME
:
String
=
"app_log.txt"
const
val
LOG_TAG
:
String
=
"CustomLog"
var
fileWriter
:
FileWriter
?
=
null
init
{
try
{
val
logFile
=
File
(
Environment
.
getExternalStoragePublicDirectory
(
Environment
.
DIRECTORY_DOWNLOADS
),
LOG_FILE_NAME
)
// val logFile = File("D:\\", LOG_FILE_NAME)
fileWriter
=
FileWriter
(
logFile
,
true
)
// true for append mode
}
catch
(
e
:
IOException
)
{
Log
.
e
(
LOG_TAG
,
"Error initializing log file"
,
e
)
}
}
fun
clearLog
(){
val
logFile
=
File
(
Environment
.
getExternalStoragePublicDirectory
(
Environment
.
DIRECTORY_DOWNLOADS
),
LOG_FILE_NAME
)
if
(
logFile
.
exists
()){
logFile
.
deleteOnExit
()
}
}
fun
d
(
tag
:
String
?,
message
:
String
)
{
Log
.
d
(
tag
,
message
)
writeToFile
(
tag
,
message
)
}
fun
i
(
tag
:
String
?,
message
:
String
)
{
Log
.
i
(
tag
,
message
)
writeToFile
(
tag
,
message
)
}
fun
e
(
tag
:
String
?,
message
:
String
)
{
Log
.
e
(
tag
,
message
)
writeToFile
(
tag
,
message
)
}
private
fun
writeToFile
(
tag
:
String
?,
message
:
String
)
{
if
(
fileWriter
!=
null
)
{
try
{
val
sdf
:
SimpleDateFormat
=
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
)
val
timeStamp
:
String
=
sdf
.
format
(
Date
())
fileWriter
!!
.
append
(
"$timeStamp - $tag: $message\n"
)
fileWriter
!!
.
flush
()
// Optional, to ensure immediate writing to file
}
catch
(
e
:
IOException
)
{
Log
.
e
(
LOG_TAG
,
"Error writing to log file"
,
e
)
}
}
}
}
\ No newline at end of file
app/src/main/java/com/sd/shupathwebview/utils/FileIoUtils.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.utils
import
android.content.ContentValues
import
android.content.Context
import
android.graphics.Bitmap
import
android.net.Uri
import
android.os.Build
import
android.os.Environment
import
android.provider.MediaStore
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.coroutineScope
import
kotlinx.coroutines.runBlocking
import
kotlinx.coroutines.withContext
import
java.io.*
import
java.math.BigDecimal
object
FileIoUtils
{
/**
* 读取asset 文件
*/
fun
getAssetContent
(
context
:
Context
,
fileName
:
String
):
String
{
val
assetManager
=
context
.
assets
var
stringBuilder
=
StringBuilder
()
var
bf
:
BufferedReader
?
=
null
try
{
val
inputReader
=
InputStreamReader
(
assetManager
.
open
(
fileName
))
bf
=
BufferedReader
(
inputReader
)
var
line
=
""
while
(!
bf
.
run
{
line
=
readLine
()
return
@run
line
}.
isNullOrEmpty
())
{
stringBuilder
.
append
(
line
)
}
bf
?.
close
()
assetManager
.
close
()
return
stringBuilder
.
toString
()
}
catch
(
e
:
IOException
)
{
e
.
printStackTrace
()
return
""
}
finally
{
bf
?.
close
()
assetManager
.
close
()
}
}
suspend
fun
getAssetMock
(
context
:
Context
,
fileName
:
String
,
dst
:
MutableList
<
String
>)
:
Int
{
val
assetManager
=
context
.
assets
var
bf
:
BufferedReader
?
=
null
try
{
val
inputReader
=
InputStreamReader
(
assetManager
.
open
(
fileName
))
bf
=
BufferedReader
(
inputReader
)
var
line
=
""
while
(!
bf
.
run
{
line
=
readLine
()
return
@run
line
}.
isNullOrEmpty
())
{
dst
.
add
(
line
)
}
bf
?.
close
()
return
1
}
catch
(
e
:
IOException
)
{
e
.
printStackTrace
()
}
finally
{
bf
?.
close
()
}
return
0
}
/**
* 读取asset 文件
*/
fun
getAsset
(
context
:
Context
,
fileName
:
String
):
String
{
val
assetManager
=
context
.
assets
var
inputStream
:
InputStream
?
=
null
var
str
=
""
try
{
inputStream
=
assetManager
.
open
(
fileName
)
val
size
=
inputStream
.
available
()
val
bytes
=
ByteArray
(
size
)
inputStream
.
read
(
bytes
)
str
=
String
(
bytes
)
}
catch
(
e
:
IOException
)
{
e
.
printStackTrace
()
}
finally
{
inputStream
?.
close
()
// assetManager.close()
}
return
str
}
//Uri获取真实路径转换成File的方法
fun
getAbsoluteImagePath
(
contentUri
:
Uri
,
context
:
Context
):
String
{
// can post image
var
res
=
""
val
proj
=
arrayOf
(
MediaStore
.
Images
.
Media
.
DATA
)
val
cursor
=
context
.
contentResolver
.
query
(
contentUri
,
proj
,
null
,
null
,
null
)
if
(
cursor
!!
.
moveToFirst
())
{
val
column_index
=
cursor
.
getColumnIndexOrThrow
(
MediaStore
.
Images
.
Media
.
DATA
)
res
=
cursor
.
getString
(
column_index
)
}
cursor
.
close
()
return
res
}
/**
* 把图片复制到应用缓存里
*/
fun
copyHeImgFileToPath
(
context
:
Context
,
fileName
:
String
,
source
:
File
,
isRemove
:
Boolean
=
true
):
File
?
{
try
{
var
dir
=
File
(
context
.
externalCacheDir
,
"xunhepic"
)
if
(!
dir
.
exists
())
{
dir
.
mkdirs
()
}
var
imgFile
=
File
(
dir
,
fileName
)
if
(!
dir
.
exists
())
{
imgFile
.
createNewFile
()
}
var
fosfrom
=
FileInputStream
(
source
)
var
fosto
=
FileOutputStream
(
imgFile
)
var
bt
=
ByteArray
(
1024
)
var
c
=
0
while
(
fosfrom
.
run
{
c
=
read
(
bt
)
return
@run
c
}
>
0
)
{
fosto
.
write
(
bt
,
0
,
c
)
//将内容写到新文件当
}
if
(
isRemove
)
{
// source.deleteOnExit()
}
fosfrom
.
close
()
fosto
.
close
()
return
imgFile
}
catch
(
e
:
IOException
)
{
return
null
}
}
//file文件读取成byte[]
fun
readFileToByte
(
file
:
File
?):
ByteArray
?
{
val
byte_size
=
1024
val
b
=
ByteArray
(
byte_size
)
try
{
val
fileInputStream
=
FileInputStream
(
file
)
val
outputStream
=
ByteArrayOutputStream
(
byte_size
)
var
length
:
Int
while
(
fileInputStream
.
read
(
b
).
also
{
length
=
it
}
!=
-
1
)
{
outputStream
.
write
(
b
,
0
,
length
)
}
fileInputStream
.
close
()
outputStream
.
close
()
return
outputStream
.
toByteArray
()
}
catch
(
e
:
IOException
)
{
e
.
printStackTrace
()
}
return
null
}
/**
* 获取总共的缓存
*/
fun
getTotalCacheSize
(
context
:
Context
):
Long
{
var
size
:
Long
=
0
return
try
{
size
=
getFolderSize
(
context
.
cacheDir
)
size
+=
getFolderSize
(
context
.
filesDir
)
// size += getFolderSize(context.externalCacheDir)
size
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
0
}
}
/**
* 获取文件夹大小
*/
private
fun
getFolderSize
(
file
:
File
?):
Long
{
if
(
file
==
null
)
{
return
0
}
var
size
:
Long
=
0
try
{
val
fileList
=
file
!!
.
listFiles
()
for
(
i
in
fileList
.
indices
)
{
// 如果下面还有文件
size
=
if
(
fileList
[
i
].
isDirectory
)
{
size
+
getFolderSize
(
fileList
[
i
])
}
else
{
size
+
fileList
[
i
].
length
()
}
}
}
catch
(
e
:
java
.
lang
.
Exception
)
{
e
.
printStackTrace
()
}
return
size
}
/**
* 删除总共的缓存
*/
fun
deleteTotalCacheSize
(
context
:
Context
)
{
runBlocking
{
coroutineScope
{
withContext
(
Dispatchers
.
IO
)
{
context
.
cacheDir
.
deleteRecursively
()
context
.
filesDir
.
deleteRecursively
()
// if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
// context.externalCacheDir?.deleteRecursively()
// }
}
}
}
}
/**
* 格式化单位
*/
fun
getFormatSize
(
size
:
Double
):
String
?
{
val
kiloByte
=
size
/
1024
if
(
kiloByte
<
1
)
{
return
size
.
toString
()
+
"Byte"
}
val
megaByte
=
kiloByte
/
1024
if
(
megaByte
<
1
)
{
val
result1
=
BigDecimal
(
kiloByte
.
toString
())
return
result1
.
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
)
.
toPlainString
().
toString
()
+
"KB"
}
val
gigaByte
=
megaByte
/
1024
if
(
gigaByte
<
1
)
{
val
result2
=
BigDecimal
(
megaByte
.
toString
())
return
result2
.
setScale
(
1
,
BigDecimal
.
ROUND_HALF_UP
)
.
toPlainString
().
toString
()
+
"MB"
}
val
teraBytes
=
gigaByte
/
1024
if
(
teraBytes
<
1
)
{
val
result3
=
BigDecimal
(
gigaByte
.
toString
())
return
result3
.
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
)
.
toPlainString
().
toString
()
+
"GB"
}
val
result4
=
BigDecimal
(
teraBytes
)
return
result4
.
setScale
(
2
,
BigDecimal
.
ROUND_HALF_UP
).
toPlainString
()
.
toString
()
+
"TB"
}
/**
* 保存图片到本地相册
*/
fun
saveBitmapToGalley
(
context
:
Context
,
bitmap
:
Bitmap
)
{
try
{
var
parentDir
:
File
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
Q
)
{
if
(
Environment
.
getExternalStorageState
().
equals
(
Environment
.
MEDIA_MOUNTED
))
{
parentDir
=
context
.
getExternalFilesDir
(
Environment
.
DIRECTORY_DCIM
)
!!
}
else
{
return
}
}
else
{
parentDir
=
Environment
.
getExternalStoragePublicDirectory
(
Environment
.
DIRECTORY_DCIM
)
}
var
fileName
=
"firend.jpg"
var
file
=
File
(
parentDir
,
fileName
)
val
contentValues
=
ContentValues
()
contentValues
.
put
(
MediaStore
.
Images
.
Media
.
DISPLAY_NAME
,
fileName
)
contentValues
.
put
(
MediaStore
.
Images
.
Media
.
MIME_TYPE
,
"image/JPEG"
)
//兼容Android Q和以下版本
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
Q
)
{
//android Q中不再使用DATA字段,而用RELATIVE_PATH代替
//RELATIVE_PATH是相对路径不是绝对路径
//DCIM是系统文件夹,关于系统文件夹可以到系统自带的文件管理器中查看,不可以写没存在的名字
contentValues
.
put
(
MediaStore
.
Images
.
Media
.
RELATIVE_PATH
,
Environment
.
DIRECTORY_DCIM
)
var
uri
=
context
.
contentResolver
.
insert
(
MediaStore
.
Images
.
Media
.
EXTERNAL_CONTENT_URI
,
contentValues
)
// LogUtil.v("-------uri= " + uri)
if
(
uri
!=
null
)
{
//若生成了uri,则表示该文件添加成功
//使用流将内容写入该uri中即可
val
outputStream
=
context
.
contentResolver
.
openOutputStream
(
uri
)
if
(
outputStream
!=
null
)
{
bitmap
.
compress
(
Bitmap
.
CompressFormat
.
JPEG
,
90
,
outputStream
)
outputStream
.
flush
()
outputStream
.
close
()
}
}
}
else
{
contentValues
.
put
(
MediaStore
.
Images
.
Media
.
DATA
,
Environment
.
DIRECTORY_DCIM
)
MediaStore
.
Images
.
Media
.
insertImage
(
context
.
contentResolver
,
bitmap
,
fileName
,
null
)
var
outputStream
=
FileOutputStream
(
file
)
if
(
file
.
exists
())
{
file
.
delete
()
}
else
{
file
.
createNewFile
()
}
bitmap
.
compress
(
Bitmap
.
CompressFormat
.
JPEG
,
90
,
outputStream
)
outputStream
.
flush
()
outputStream
.
close
()
}
// LogUtil.e("------ " + file?.toUri())
// context.sendBroadcast(
// Intent(
// Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
// file?.toUri()
// )
// )
}
catch
(
e
:
java
.
lang
.
Exception
)
{
e
.
printStackTrace
()
}
}
}
\ No newline at end of file
app/src/main/java/com/sd/shupathwebview/utils/MyContants.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.utils
object
MyContants
{
/**从obu来的数据**/
const
val
obu_data
=
"obu_data"
/***JS方法名***/
const
val
getOBUData
=
"getOBUData"
const
val
getDeviceData
=
"getDeviceData"
}
\ No newline at end of file
app/src/main/java/com/sd/shupathwebview/utils/ToastHelper.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.utils
import
android.content.Context
import
android.view.Gravity
import
android.widget.Toast
/**
*author:pc-20171125
*data:2019/11/8 11:18
*/
object
ToastHelper
{
/**
* 短时间显示Toast
*
* @param message
*/
fun
showShort
(
context
:
Context
,
message
:
String
)
{
Toast
.
makeText
(
context
,
message
,
Toast
.
LENGTH_SHORT
).
run
{
setGravity
(
Gravity
.
CENTER
,
0
,
0
)
show
()
}
}
// /**
// * 短时间显示Toast
// *
// * @param message
// */
// fun showShort(message: Int) {
// if (isShow)
// Toast.makeText(BaseApp.context, message, Toast.LENGTH_SHORT).show()
// }
// /**
// * 长时间显示Toast
// *
// * @param message
// */
// fun showLong(message: CharSequence) {
// if (isShow)
// Toast.makeText(BaseApp.context, message, Toast.LENGTH_LONG).show()
// }
}
app/src/main/java/com/sd/shupathwebview/viewmodels/AMapLoc.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.viewmodels
import
android.content.Context
import
android.icu.text.DecimalFormat
import
android.location.Location
import
android.text.TextUtils
import
androidx.lifecycle.MutableLiveData
import
androidx.lifecycle.ViewModel
import
com.amap.api.location.AMapLocationClient
import
com.amap.api.location.AMapLocationClientOption
import
com.amap.api.location.AMapLocationClientOption.AMapLocationMode
import
com.amap.api.location.AMapLocationClientOption.AMapLocationProtocol
import
com.amap.api.location.AMapLocationListener
import
com.amap.api.location.AMapLocationQualityReport
import
com.sd.shupathwebview.bean.MyLoc
import
com.sd.shupathwebview.utils.AmapUtils
import
com.sd.shupathwebview.utils.CustomLog
import
dagger.hilt.android.lifecycle.HiltViewModel
import
dagger.hilt.android.qualifiers.ApplicationContext
import
javax.inject.Inject
@HiltViewModel
class
AMapLoc
@Inject
constructor
(
@ApplicationContext
var
context
:
Context
)
:
ViewModel
()
{
val
TAG
=
AMapLoc
::
class
.
java
::
getSimpleName
.
toString
()
private
var
locationClient
:
AMapLocationClient
?
=
null
private
var
locationOption
:
AMapLocationClientOption
?
=
null
private
var
myLoc
=
MyLoc
()
var
myLocValue
=
MutableLiveData
<
MyLoc
>()
/**
* 初始化定位
*
* @since 2.8.0
* @author hongming.wang
*/
fun
initLocation
()
{
//初始化client
try
{
locationClient
=
AMapLocationClient
(
context
)
locationOption
=
getDefaultOption
()
//设置定位参数
locationClient
?.
setLocationOption
(
locationOption
)
// 设置定位监听
locationClient
?.
setLocationListener
(
locationListener
)
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
}
}
/**
* 默认的定位参数
* @since 2.8.0
* @author hongming.wang
*/
private
fun
getDefaultOption
():
AMapLocationClientOption
{
val
mOption
=
AMapLocationClientOption
()
mOption
.
setLocationMode
(
AMapLocationMode
.
Hight_Accuracy
)
//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
mOption
.
setGpsFirst
(
false
)
//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
mOption
.
setHttpTimeOut
(
30000
)
//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
mOption
.
setInterval
(
1000
)
//可选,设置定位间隔。默认为2秒
mOption
.
setNeedAddress
(
false
)
//可选,设置是否返回逆地理地址信息。默认是true
mOption
.
setOnceLocation
(
false
)
//可选,设置是否单次定位。默认是false
mOption
.
setOnceLocationLatest
(
false
)
//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
AMapLocationClientOption
.
setLocationProtocol
(
AMapLocationProtocol
.
HTTP
)
//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
mOption
.
setSensorEnable
(
false
)
//可选,设置是否使用传感器。默认是false
mOption
.
setWifiScan
(
true
)
//可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
mOption
.
setLocationCacheEnable
(
true
)
//可选,设置是否使用缓存定位,默认为true
mOption
.
setGeoLanguage
(
AMapLocationClientOption
.
GeoLanguage
.
DEFAULT
)
//可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言)
return
mOption
}
private
fun
getTrancesportOption
():
AMapLocationClientOption
{
val
mOption
=
AMapLocationClientOption
()
/**
* 设置签到场景,相当于设置为:
* option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
* option.setOnceLocation(false);
* option.setOnceLocationLatest(false);
* option.setMockEnable(false);
* option.setWifiScan(true);
*
* 其他属性均为模式属性。
* 如果要改变其中的属性,请在在设置定位场景之后进行
*/
mOption
.
setHttpTimeOut
(
1000
)
//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
mOption
.
setInterval
(
2000
)
//可选,设置定位间隔。默认为2秒
mOption
.
setLocationPurpose
(
AMapLocationClientOption
.
AMapLocationPurpose
.
Transport
)
return
mOption
}
/**
* 定位监听
*/
var
locationListener
:
AMapLocationListener
=
AMapLocationListener
{
location
->
if
(
null
!=
location
)
{
val
sb
=
StringBuffer
()
//errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
if
(
location
.
errorCode
==
0
)
{
sb
.
append
(
"定位成功"
+
"\n"
)
sb
.
append
(
"定位类型: "
+
location
.
locationType
+
"\n"
)
sb
.
append
(
"经 度 : "
+
location
.
longitude
+
"\n"
)
sb
.
append
(
"纬 度 : "
+
location
.
latitude
+
"\n"
)
sb
.
append
(
"精 度 : "
+
location
.
accuracy
+
"米"
+
"\n"
)
sb
.
append
(
"提供者 : "
+
location
.
provider
+
"\n"
)
sb
.
append
(
"速 度 : "
+
location
.
speed
+
"米/秒"
+
"\n"
)
sb
.
append
(
"角 度 : "
+
location
.
bearing
+
"\n"
)
// 获取当前提供定位服务的卫星个数
sb
.
append
(
"星 数 : "
+
location
.
satellites
+
"\n"
)
sb
.
append
(
"国 家 : "
+
location
.
country
+
"\n"
)
sb
.
append
(
"省 : "
+
location
.
province
+
"\n"
)
sb
.
append
(
"市 : "
+
location
.
city
+
"\n"
)
sb
.
append
(
"城市编码 : "
+
location
.
cityCode
+
"\n"
)
sb
.
append
(
"区 : "
+
location
.
district
+
"\n"
)
sb
.
append
(
"区域 码 : "
+
location
.
adCode
+
"\n"
)
sb
.
append
(
"地 址 : "
+
location
.
address
+
"\n"
)
sb
.
append
(
"兴趣点 : "
+
location
.
poiName
+
"\n"
)
//定位完成的时间
sb
.
append
(
"定位时间: "
+
AmapUtils
.
formatUTC
(
location
.
time
,
"yyyy-MM-dd HH:mm:ss"
)
+
"\n"
)
}
else
{
//定位失败
sb
.
append
(
"定位失败"
+
"\n"
)
sb
.
append
(
"错误码:"
+
location
.
errorCode
+
"\n"
)
sb
.
append
(
"错误信息:"
+
location
.
errorInfo
+
"\n"
)
sb
.
append
(
"错误描述:"
+
location
.
locationDetail
+
"\n"
)
}
sb
.
append
(
"***定位质量报告***"
).
append
(
"\n"
)
sb
.
append
(
"* WIFI开关:"
)
.
append
(
if
(
location
.
locationQualityReport
.
isWifiAble
)
"开启"
else
"关闭"
)
.
append
(
"\n"
)
sb
.
append
(
"* GPS状态:"
)
.
append
(
getGPSStatusString
(
location
.
locationQualityReport
.
gpsStatus
)).
append
(
"\n"
)
sb
.
append
(
"* GPS星数:"
).
append
(
location
.
locationQualityReport
.
gpsSatellites
)
.
append
(
"\n"
)
sb
.
append
(
"* 网络类型:"
+
location
.
locationQualityReport
.
networkType
).
append
(
"\n"
)
sb
.
append
(
"* 网络耗时:"
+
location
.
locationQualityReport
.
netUseTime
).
append
(
"\n"
)
sb
.
append
(
"****************"
).
append
(
"\n"
)
//定位之后的回调时间
sb
.
append
(
"回调时间: "
+
AmapUtils
.
formatUTC
(
System
.
currentTimeMillis
(),
"yyyy-MM-dd HH:mm:ss"
)
+
"\n"
)
//解析定位结果,
val
result
=
sb
.
toString
()
CustomLog
.
d
(
TAG
,
result
)
setMyLocation
(
location
,
result
)
}
else
{
CustomLog
.
d
(
TAG
,
"定位失败,loc is null"
)
}
}
private
fun
setMyLocation
(
location
:
Location
,
debugString
:
String
=
""
)
{
var
decimalFormat
=
DecimalFormat
(
"#.00000000"
)
var
strLat
=
decimalFormat
.
format
(
location
.
latitude
)
var
strLng
=
decimalFormat
.
format
(
location
.
longitude
)
myLoc
.
lat
=
strLat
.
toDouble
()
myLoc
.
lng
=
strLng
.
toDouble
()
myLoc
.
speed
=
location
.
speed
myLoc
.
accuracy
=
location
.
accuracy
myLoc
.
bearing
=
location
.
bearing
// myLoc.com_time = location.time
myLoc
.
debugStr
=
debugString
println
(
"--------lng = ${myLoc.lat} lng = ${myLoc.lng}"
)
myLocValue
.
value
=
myLoc
// val loc = location.latitude.toString() + " " + location.longitude.toString()
}
/**
* 获取GPS状态的字符串
* @param statusCode GPS状态码
* @return
*/
private
fun
getGPSStatusString
(
statusCode
:
Int
):
String
{
var
str
=
""
when
(
statusCode
)
{
AMapLocationQualityReport
.
GPS_STATUS_OK
->
str
=
"GPS状态正常"
AMapLocationQualityReport
.
GPS_STATUS_NOGPSPROVIDER
->
str
=
"手机中没有GPS Provider,无法进行GPS定位"
AMapLocationQualityReport
.
GPS_STATUS_OFF
->
str
=
"GPS关闭,建议开启GPS,提高定位质量"
AMapLocationQualityReport
.
GPS_STATUS_MODE_SAVING
->
str
=
"选择的定位模式中不包含GPS定位,建议选择包含GPS定位的模式,提高定位质量"
AMapLocationQualityReport
.
GPS_STATUS_NOGPSPERMISSION
->
str
=
"没有GPS定位权限,建议开启gps定位权限"
}
return
str
}
/**
* 开始定位
*
* @since 2.8.0
* @author hongming.wang
*/
fun
startLocation
()
{
try
{
//根据控件的选择,重新设置定位参数
// resetOption()
// 设置定位参数
locationClient
?.
setLocationOption
(
locationOption
)
// 启动定位
locationClient
?.
startLocation
()
}
catch
(
e
:
java
.
lang
.
Exception
)
{
e
.
printStackTrace
()
}
}
/**
* 停止定位
*
* @since 2.8.0
* @author hongming.wang
*/
fun
stopLocation
()
{
try
{
// 停止定位
locationClient
?.
stopLocation
()
}
catch
(
e
:
java
.
lang
.
Exception
)
{
e
.
printStackTrace
()
}
}
/**
* 销毁定位
*
* @since 2.8.0
* @author hongming.wang
*/
fun
destroyLocation
()
{
if
(
null
!=
locationClient
)
{
/**
* 如果AMapLocationClient是在当前Activity实例化的,
* 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
*/
locationClient
?.
onDestroy
()
locationClient
=
null
locationOption
=
null
}
}
}
\ No newline at end of file
app/src/main/java/com/sd/shupathwebview/viewmodels/MyLocVM.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.viewmodels
import
android.Manifest
import
android.annotation.SuppressLint
import
android.content.Context
import
android.icu.text.DecimalFormat
import
android.location.Location
import
android.location.LocationListener
import
android.location.LocationManager
import
android.util.Log
import
androidx.annotation.RequiresPermission
import
androidx.lifecycle.LiveData
import
androidx.lifecycle.MutableLiveData
import
androidx.lifecycle.ViewModel
import
com.sd.shupathwebview.bean.MyLoc
import
dagger.hilt.android.lifecycle.HiltViewModel
import
dagger.hilt.android.qualifiers.ApplicationContext
import
javax.inject.Inject
@HiltViewModel
class
MyLocVM
@Inject
constructor
(
// @Assisted private val savedStateHandle: SavedStateHandle
@ApplicationContext
var
context
:
Context
)
:
ViewModel
()
{
private
var
locationManager
=
context
.
getSystemService
(
Context
.
LOCATION_SERVICE
)
as
LocationManager
private
var
locationProvider
:
String
=
""
private
var
location
:
Location
?
=
null
private
var
myLoc
=
MyLoc
()
var
myLocValue
=
MutableLiveData
<
MyLoc
>()
@RequiresPermission
(
allOf
=
[
Manifest
.
permission
.
ACCESS_FINE_LOCATION
,
Manifest
.
permission
.
ACCESS_COARSE_LOCATION
])
fun
getLocation
():
LiveData
<
MyLoc
>
{
//1.获取位置管理器
// locationManager = mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
//2.获取位置提供器,GPS或是NetWork
if
(!
getProvider
().
isNullOrEmpty
())
{
if
(
location
!=
null
)
{
setMyLocation
(
location
!!
)
}
// 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
locationManager
.
requestLocationUpdates
(
locationProvider
,
1
,
0f
,
locationListener
)
}
return
myLocValue
}
@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
)
{
setMyLocation
(
locate
)
}
return
locate
?.
latitude
.
toString
()
+
" "
+
locate
?.
longitude
.
toString
()
}
private
fun
getProvider
():
String
{
val
providers
:
List
<
String
>
=
locationManager
.
getProviders
(
true
)
if
(
providers
.
contains
(
LocationManager
.
GPS_PROVIDER
))
{
//如果是GPS定位
// Log.d("TAG", "如果是GPS定位")
locationProvider
=
LocationManager
.
NETWORK_PROVIDER
}
else
if
(
providers
.
contains
(
LocationManager
.
NETWORK_PROVIDER
))
{
//如果是网络定位
// Log.d("TAG", "如果是网络定位")
locationProvider
=
LocationManager
.
NETWORK_PROVIDER
}
else
{
Log
.
d
(
"TAG"
,
"没有可用的位置提供器"
)
return
""
}
return
locationProvider
}
private
fun
setMyLocation
(
location
:
Location
)
{
this
.
location
=
location
var
decimalFormat
=
DecimalFormat
(
"#.000000000"
)
var
strLat
=
decimalFormat
.
format
(
location
.
latitude
)
var
strLng
=
decimalFormat
.
format
(
location
.
longitude
)
myLoc
.
lat
=
strLat
.
toDouble
()
myLoc
.
lng
=
strLng
.
toDouble
()
myLoc
.
speed
=
location
.
speed
myLoc
.
bearing
=
location
.
bearing
println
(
"--------lng = ${myLoc.lat} lng = ${myLoc.lng}"
)
myLocValue
.
value
=
myLoc
// val loc = location.latitude.toString() + " " + location.longitude.toString()
}
var
locationListener
=
object
:
LocationListener
{
override
fun
onLocationChanged
(
location
:
Location
)
{
// location.getAccuracy()//精确度
println
(
"--------location.latitude = ${location.latitude} longitude ${location.longitude}"
)
setMyLocation
(
location
)
}
}
fun
desLis
()
{
if
(
locationManager
!=
null
)
{
locationManager
.
removeUpdates
(
locationListener
);
}
}
}
\ No newline at end of file
app/src/main/java/com/sd/shupathwebview/works/AioClient.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.works
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.launch
import
java.net.InetSocketAddress
import
java.net.StandardSocketOptions
import
java.nio.ByteBuffer
import
java.nio.channels.AsynchronousSocketChannel
import
java.nio.channels.CompletionHandler
import
java.nio.charset.Charset
import
java.util.concurrent.Executors
import
java.util.concurrent.Future
import
java.util.concurrent.TimeUnit
class
AioClient
{
// private val TCP_URL = "192.168.60.113"
private
val
TCP_URL
=
"192.168.60.176"
private
val
PORT
=
8080
private
lateinit
var
channel
:
AsynchronousSocketChannel
fun
connectAIO
()
{
channel
=
AsynchronousSocketChannel
.
open
()
channel
.
setOption
(
StandardSocketOptions
.
SO_KEEPALIVE
,
true
)
channel
.
setOption
(
StandardSocketOptions
.
SO_REUSEADDR
,
true
)
channel
.
setOption
(
StandardSocketOptions
.
TCP_NODELAY
,
true
)
// val connectFuture: Future<Void> =
// channel.connect(InetSocketAddress(TCP_URL, PORT))
// var cd=connectFuture.get()
// var a=0
// return cd // 等待连接完成
channel
.
connect
<
Void
?>(
InetSocketAddress
(
TCP_URL
,
PORT
),
null
,
object
:
CompletionHandler
<
Void
?,
Void
?>
{
override
fun
completed
(
result
:
Void
?,
attachment
:
Void
?)
{
System
.
out
.
println
(
"----连接成功"
)
read1
()
// heart()
}
override
fun
failed
(
exc
:
Throwable
?,
attachment
:
Void
?)
{
System
.
err
.
println
(
"-------连接失败: "
+
exc
?.
message
);
}
}
)
}
fun
write
()
{
// 异步写入数据
val
buffer
=
ByteBuffer
.
wrap
(
"----Hello Server"
.
toByteArray
())
val
writeResult
:
Future
<
Int
>
=
channel
.
write
(
buffer
)
var
a
=
writeResult
.
get
()
var
b
=
1
}
fun
read
()
{
CoroutineScope
(
Dispatchers
.
IO
).
launch
{
val
response
=
ByteBuffer
.
allocate
(
1024
)
val
readResult
:
Future
<
Int
>
=
channel
.
read
(
response
)
var
result
=
readResult
.
get
()
response
.
flip
()
if
(
result
?:
0
>
0
)
{
response
.
flip
()
val
data
=
ByteArray
(
response
.
limit
())
response
.
get
(
data
)
var
str
=
data
.
toString
(
Charset
.
forName
(
"UTF-8"
))
System
.
out
.
println
(
"-----read1 clent 数据部分= : "
+
String
(
data
))
}
}
}
fun
read1
()
{
println
(
"----------channel.isOpen "
+
channel
.
isOpen
)
val
response
=
ByteBuffer
.
allocate
(
8192
)
channel
.
read
(
response
,
response
,
object
:
CompletionHandler
<
Int
,
ByteBuffer
>
{
override
fun
completed
(
result
:
Int
?,
attachment
:
ByteBuffer
?)
{
println
(
"-----read()1 = result = ${result}"
)
if
(
result
?:
0
>
0
)
{
response
.
flip
()
// val data = ByteArray(response.remaining())
val
data
=
ByteArray
(
response
.
limit
())
response
.
get
(
data
)
var
str
=
data
.
toString
(
Charset
.
forName
(
"UTF-8"
))
System
.
out
.
println
(
"-----read1 clent 数据部分= : "
+
String
(
data
))
}
}
override
fun
failed
(
exc
:
Throwable
?,
attachment
:
ByteBuffer
?)
{
System
.
out
.
println
(
"-----read1 clent 读取失败= : "
+
exc
?.
message
)
}
})
}
fun
heart
()
{
var
heartbeatExecutor
=
Executors
.
newScheduledThreadPool
(
1
)
// 启动心跳线程
heartbeatExecutor
.
scheduleAtFixedRate
({
try
{
channel
.
write
(
ByteBuffer
.
wrap
(
ByteArray
(
0
)))
}
catch
(
e
:
Exception
)
{
// reconnect()
}
},
0
,
30
,
TimeUnit
.
SECONDS
)
}
}
// fun read() {
// CoroutineScope(Dispatchers.IO).launch {
// val response = ByteBuffer.allocate(1024)
//
// val readResult: Future<Int> = channel.read(response)
// readResult.get()
// response.flip()
// //// // 解析字段
// var deviceId = response.get() // 设备ID
// var temperature = response.getShort(); // 温度
// var humidity = response.getFloat(); // 湿度
////
// System.out.println("Device ID: " + deviceId);
// System.out.println("Temperature: " + temperature);
// System.out.println("Humidity: " + humidity);
//
// val data = ByteArray(response.remaining())
// response.get(data);
// System.out.println("-----clent 数据部分= : " + String(data))
// }
// }
app/src/main/java/com/sd/shupathwebview/works/SocketWorker.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.works
import
android.app.NotificationChannel
import
android.app.NotificationManager
import
android.content.Context
import
android.content.pm.ServiceInfo
import
androidx.core.app.NotificationCompat
import
androidx.work.CoroutineWorker
import
androidx.work.ForegroundInfo
import
androidx.work.WorkManager
import
androidx.work.WorkerParameters
import
com.sd.shupathwebview.R
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.withContext
import
java.net.InetSocketAddress
import
java.net.StandardSocketOptions
import
java.nio.ByteBuffer
import
java.nio.channels.AsynchronousSocketChannel
import
java.nio.channels.CompletionHandler
import
java.nio.charset.Charset
/**
* 链接任务
*/
class
SocketWorker
constructor
(
val
appContext
:
Context
,
workerParams
:
WorkerParameters
)
:
CoroutineWorker
(
appContext
,
workerParams
)
{
init
{
}
// private val notificationManager = appContext.getSystemService(Context.NOTIFICATION_SERVICE) as
// NotificationManager
val
notificationId
=
51
// var client = AioClient()
private
val
TCP_URL
=
"192.168.60.176"
private
val
PORT
=
8080
private
lateinit
var
channel
:
AsynchronousSocketChannel
override
suspend
fun
doWork
():
Result
{
setForeground
(
createForegroundInfo
())
return
Result
.
success
()
}
// fun connectAIO() {
// channel = AsynchronousSocketChannel.open()
// channel.setOption(StandardSocketOptions.SO_KEEPALIVE, true)
// channel.setOption(StandardSocketOptions.SO_REUSEADDR, true)
// channel.setOption(StandardSocketOptions.TCP_NODELAY, true)
//// val connectFuture: Future<Void> =
//// channel.connect(InetSocketAddress(TCP_URL, PORT))
//// var cd=connectFuture.get()
//// return cd // 等待连接完成
// channel.connect<Void?>(
// InetSocketAddress(TCP_URL, PORT),
// null,
// object : CompletionHandler<Void?, Void?> {
//
// override fun completed(result: Void?, attachment: Void?) {
// System.out.println("----连接成功")
// read1()
//// heart()
// }
//
// override fun failed(exc: Throwable?, attachment: Void?) {
// System.err.println("-------连接失败: " + exc?.message);
// }
// }
// )
// }
fun
read1
()
{
var
aa
=
channel
.
isOpen
val
response
=
ByteBuffer
.
allocate
(
8192
)
channel
.
read
(
response
,
response
,
object
:
CompletionHandler
<
Int
,
ByteBuffer
>
{
override
fun
completed
(
result
:
Int
?,
attachment
:
ByteBuffer
?)
{
println
(
"-----read()1 = result = ${result}"
)
if
(
result
?:
0
>
0
)
{
response
.
flip
()
// val data = ByteArray(response.remaining())
val
data
=
ByteArray
(
response
.
limit
())
response
.
get
(
data
)
var
str
=
data
.
toString
(
Charset
.
forName
(
"UTF-8"
))
System
.
out
.
println
(
"-----read1 clent 数据部分= : "
+
String
(
data
))
}
}
override
fun
failed
(
exc
:
Throwable
?,
attachment
:
ByteBuffer
?)
{
System
.
out
.
println
(
"-----read1 clent 读取失败= : "
+
exc
?.
message
)
}
})
}
// Creates an instance of ForegroundInfo which can be used to update the
// ongoing notification.
private
fun
createForegroundInfo
(
progress
:
String
=
""
):
ForegroundInfo
{
val
mNotificationManager
=
appContext
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
// 通知渠道的id
val
id
=
"my_channel_01"
// 用户可以看到的通知渠道的名字.
val
name
:
CharSequence
=
appContext
.
getString
(
R
.
string
.
app_name
)
val
description
=
appContext
.
getString
(
R
.
string
.
app_name
)
val
importance
=
NotificationManager
.
IMPORTANCE_HIGH
val
mChannel
=
NotificationChannel
(
id
,
name
,
importance
)
mNotificationManager
.
createNotificationChannel
(
mChannel
)
val
title
=
appContext
.
getString
(
R
.
string
.
notification_title
)
val
notification
=
NotificationCompat
.
Builder
(
appContext
,
id
)
.
setContentTitle
(
title
)
.
setTicker
(
title
)
.
setContentText
(
title
)
.
setSmallIcon
(
R
.
mipmap
.
ic_launcher
)
// Create the notification to display while the service is running
.
build
()
return
ForegroundInfo
(
notificationId
,
notification
,
ServiceInfo
.
FOREGROUND_SERVICE_TYPE_DATA_SYNC
)
}
private
fun
createChannel
()
{
// Create a Notification channel
// 通知渠道的id
// val CHANNEL_ID = "my_channel_01"
// val notification: Notification = Notification.Builder(this)
// .setContentTitle("")
// .setContentText("")
// .setChannelId(CHANNEL_ID)
// .build()
// ServiceCompat.startForeground(SystemForegroundService.getInstance(), notification)
}
}
\ No newline at end of file
app/src/main/java/com/sd/shupathwebview/works/TcpConntctVM.kt
0 → 100644
View file @
5616a99e
package
com.sd.shupathwebview.works
import
android.content.Context
import
androidx.lifecycle.ViewModel
import
androidx.lifecycle.viewModelScope
import
androidx.work.OneTimeWorkRequestBuilder
import
androidx.work.WorkInfo
import
androidx.work.WorkManager
import
androidx.work.workDataOf
import
com.sd.shupathwebview.dsbridge.DWebView
import
com.sd.shupathwebview.dsbridge.OnReturnValue
import
com.sd.shupathwebview.network.NettyReceiveClient
import
com.sd.shupathwebview.utils.CustomLog
import
com.sd.shupathwebview.utils.FileIoUtils
import
com.sd.shupathwebview.utils.MyContants
import
dagger.hilt.android.lifecycle.HiltViewModel
import
dagger.hilt.android.qualifiers.ApplicationContext
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.async
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.withContext
import
javax.inject.Inject
@HiltViewModel
class
TcpConntctVM
@Inject
constructor
(
// @Assisted private val savedStateHandle: SavedStateHandle
@ApplicationContext
var
context
:
Context
)
:
ViewModel
()
{
var
obuStr
=
""
private
var
nettyReceiveClient
=
NettyReceiveClient
()
// var socketWorker = OneTimeWorkRequestBuilder<SocketWorker>().build()
fun
startWork
()
{
var
socketWorker
=
OneTimeWorkRequestBuilder
<
SocketWorker
>()
.
setInputData
(
workDataOf
(
"nettyReceiveClient"
to
nettyReceiveClient
))
.
build
()
// val oneWorker = OneTimeWorkRequest.Builder(OneWorker::class).build()
WorkManager
.
getInstance
(
context
).
enqueue
(
socketWorker
)
// WorkManager.getInstance(context).getWorkInfoByIdLiveData(socketWorker.id)
// .observe(owner!!, { it ->
// println("-----connectWorker.state = ${it?.state}")
// if (it?.state?.isFinished == true) {
// println("-------connectWorker isFinished")
// }
// })
}
var
mockList
=
mutableListOf
<
String
>()
fun
readMockData
()
{
viewModelScope
.
launch
{
// withContext(Dispatchers.IO) {
var
result
=
FileIoUtils
.
getAssetMock
(
context
,
"OBU_MOCK/BSM-1-JJ-CY-10hz-S0ms.pf"
,
mockList
)
CustomLog
.
d
(
"---pxl"
,
"模拟数据读完了 result = $result"
)
// mockList.forEach{
// CustomLog.d("---pxl","每行模拟数据= $it")
// }
// }
}
}
fun
sendMockData
(
dwebview
:
DWebView
)
{
viewModelScope
.
launch
{
mockList
.
forEach
{
CustomLog
.
d
(
"---pxl "
,
"准备给webview的模拟数据是 = ${it}"
)
dwebview
.
callHandler
(
MyContants
.
getOBUData
,
arrayOf
(
it
),
object
:
OnReturnValue
<
String
>
{
override
fun
onValue
(
retValue
:
String
?)
{
CustomLog
.
d
(
"---pxl "
,
"getOBUData Android 收到webview的回调 onValue= ${retValue.toString()}"
)
}
})
CustomLog
.
d
(
"---pxl "
,
"getOBUData 睡200ms"
)
delay
(
200
)
}
}
}
fun
stopWork
()
{
nettyReceiveClient
.
close
()
}
}
\ No newline at end of file
app/src/main/res/drawable/ic_launcher_background.xml
0 → 100644
View file @
5616a99e
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"108dp"
android:height=
"108dp"
android:viewportWidth=
"108"
android:viewportHeight=
"108"
>
<path
android:fillColor=
"#3DDC84"
android:pathData=
"M0,0h108v108h-108z"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M9,0L9,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,0L19,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M29,0L29,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M39,0L39,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M49,0L49,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M59,0L59,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M69,0L69,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M79,0L79,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M89,0L89,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M99,0L99,108"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,9L108,9"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,19L108,19"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,29L108,29"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,39L108,39"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,49L108,49"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,59L108,59"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,69L108,69"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,79L108,79"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,89L108,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M0,99L108,99"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,29L89,29"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,39L89,39"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,49L89,49"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,59L89,59"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,69L89,69"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M19,79L89,79"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M29,19L29,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M39,19L39,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M49,19L49,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M59,19L59,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M69,19L69,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
<path
android:fillColor=
"#00000000"
android:pathData=
"M79,19L79,89"
android:strokeWidth=
"0.8"
android:strokeColor=
"#33FFFFFF"
/>
</vector>
app/src/main/res/drawable/ic_launcher_foreground.xml
0 → 100644
View file @
5616a99e
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:aapt=
"http://schemas.android.com/aapt"
android:width=
"108dp"
android:height=
"108dp"
android:viewportWidth=
"108"
android:viewportHeight=
"108"
>
<path
android:pathData=
"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"
>
<aapt:attr
name=
"android:fillColor"
>
<gradient
android:endX=
"85.84757"
android:endY=
"92.4963"
android:startX=
"42.9492"
android:startY=
"49.59793"
android:type=
"linear"
>
<item
android:color=
"#44000000"
android:offset=
"0.0"
/>
<item
android:color=
"#00000000"
android:offset=
"1.0"
/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth=
"1"
android:strokeColor=
"#00000000"
/>
</vector>
\ No newline at end of file
app/src/main/res/layout/activity_main.xml
0 → 100644
View file @
5616a99e
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/main"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:keepScreenOn=
"true"
android:background=
"#675662"
tools:context=
".MainActivity"
>
<com.sd.shupathwebview.dsbridge.DWebView
android:id=
"@+id/dwebview"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:visibility=
"gone"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/mipmap-hdpi/ic_launcher.png
0 → 100644
View file @
5616a99e
4.72 KB
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
0 → 100644
View file @
5616a99e
2.83 KB
app/src/main/res/mipmap-mdpi/ic_launcher.png
0 → 100644
View file @
5616a99e
4.72 KB
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
0 → 100644
View file @
5616a99e
1.73 KB
app/src/main/res/mipmap-xhdpi/ic_launcher.png
0 → 100644
View file @
5616a99e
4.72 KB
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
0 → 100644
View file @
5616a99e
3.83 KB
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
0 → 100644
View file @
5616a99e
4.72 KB
Prev
1
…
21
22
23
24
25
26
Next
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