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
e02e65d3
Commit
e02e65d3
authored
Oct 17, 2025
by
p x
Browse files
交互
parent
8d5907a7
Changes
7
Show whitespace changes
Inline
Side-by-side
app/src/main/AndroidManifest.xml
View file @
e02e65d3
...
@@ -5,6 +5,9 @@
...
@@ -5,6 +5,9 @@
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore=
"ScopedStorage"
/>
<application
<application
android:name=
".MyApplication"
android:name=
".MyApplication"
...
@@ -20,8 +23,8 @@
...
@@ -20,8 +23,8 @@
tools:targetApi=
"31"
>
tools:targetApi=
"31"
>
<activity
<activity
android:name=
".ui.LoginActivity"
android:name=
".ui.LoginActivity"
android:exported=
"true"
android:configChanges=
"orientation"
android:configChanges=
"orientation"
android:exported=
"true"
android:screenOrientation=
"landscape"
>
android:screenOrientation=
"landscape"
>
<intent-filter>
<intent-filter>
...
@@ -32,11 +35,21 @@
...
@@ -32,11 +35,21 @@
</activity>
</activity>
<activity
<activity
android:name=
".MainActivity"
android:name=
".MainActivity"
android:exported=
"false"
android:screenOrientation=
"landscape"
android:configChanges=
"orientation"
android:configChanges=
"orientation"
android:launchMode=
"singleTask"
/>
android:exported=
"false"
android:launchMode=
"singleTask"
android:screenOrientation=
"landscape"
/>
<provider
android:name=
"androidx.core.content.FileProvider"
android:authorities=
"${applicationId}.provider"
android:exported=
"false"
android:grantUriPermissions=
"true"
>
<meta-data
android:name=
"android.support.FILE_PROVIDER_PATHS"
android:resource=
"@xml/file_paths"
/>
</provider>
</application>
</application>
...
...
app/src/main/java/com/sd/geelyhmiweb/JsApi.kt
0 → 100644
View file @
e02e65d3
package
com.sd.geelyhmiweb
import
android.webkit.JavascriptInterface
import
com.sd.geelyhmiweb.dsbridge.CompletionHandler
import
com.sd.geelyhmiweb.utils.FileIoUtils
import
com.sd.geelyhmiweb.viewmodels.MainVM
class
JsApi
{
var
mainVM
:
MainVM
?=
null
//同步API
@JavascriptInterface
fun
testSyn
(
msg
:
String
):
String
{
return
msg
.
toString
()
+
"[syn call]"
}
//异步API
@JavascriptInterface
fun
testAsyn
(
msg
:
String
,
handler
:
CompletionHandler
<
String
?
>)
{
handler
.
complete
(
msg
.
toString
()
+
" [ asyn call]"
)
}
@JavascriptInterface
fun
writeLog
(
msg
:
String
)
{
println
(
"------------ writeLog"
)
mainVM
?.
writeLog
(
msg
)
// FileIoUtils.writeToFile(gson.toJson(perceptionBean), "PerTarget_15_move.txt")
}
}
\ No newline at end of file
app/src/main/java/com/sd/geelyhmiweb/MainActivity.kt
View file @
e02e65d3
...
@@ -12,14 +12,20 @@ import android.webkit.WebResourceResponse
...
@@ -12,14 +12,20 @@ import android.webkit.WebResourceResponse
import
android.webkit.WebSettings
import
android.webkit.WebSettings
import
android.webkit.WebView
import
android.webkit.WebView
import
android.webkit.WebViewClient
import
android.webkit.WebViewClient
import
androidx.activity.viewModels
import
androidx.appcompat.app.AppCompatActivity
import
androidx.appcompat.app.AppCompatActivity
import
com.sd.geelyhmiweb.databinding.ActivityMainBinding
import
com.sd.geelyhmiweb.databinding.ActivityMainBinding
import
com.sd.geelyhmiweb.viewmodels.MainVM
import
dagger.hilt.android.AndroidEntryPoint
import
dagger.hilt.android.AndroidEntryPoint
import
kotlin.getValue
@AndroidEntryPoint
@AndroidEntryPoint
class
MainActivity
:
AppCompatActivity
()
{
class
MainActivity
:
AppCompatActivity
()
{
private
lateinit
var
binding
:
ActivityMainBinding
private
lateinit
var
binding
:
ActivityMainBinding
private
var
mainVM
:
MainVM
by
viewModels
()
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
binding
=
ActivityMainBinding
.
inflate
(
layoutInflater
)
binding
=
ActivityMainBinding
.
inflate
(
layoutInflater
)
...
@@ -30,11 +36,13 @@ class MainActivity : AppCompatActivity() {
...
@@ -30,11 +36,13 @@ class MainActivity : AppCompatActivity() {
fun
initWeb
()
{
fun
initWeb
()
{
// DWebView.setWebContentsDebuggingEnabled(true)
var
jsApi
=
JsApi
()
jsApi
.
mainVM
=
mainVM
binding
.
dwebview
.
addJavascriptObject
(
jsApi
,
null
)
// DWebView.setWebContentsDebuggingEnabled(true)
binding
.
dwebview
.
settings
.
run
{
binding
.
dwebview
.
settings
.
run
{
// userAgentString="Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36"
// userAgentString="Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36"
javaScriptEnabled
=
true
javaScriptEnabled
=
true
javaScriptCanOpenWindowsAutomatically
=
true
javaScriptCanOpenWindowsAutomatically
=
true
loadWithOverviewMode
=
true
loadWithOverviewMode
=
true
...
@@ -95,7 +103,6 @@ class MainActivity : AppCompatActivity() {
...
@@ -95,7 +103,6 @@ class MainActivity : AppCompatActivity() {
binding
.
dwebview
.
webChromeClient
=
object
:
WebChromeClient
()
{
binding
.
dwebview
.
webChromeClient
=
object
:
WebChromeClient
()
{
override
fun
onConsoleMessage
(
message
:
ConsoleMessage
?):
Boolean
{
override
fun
onConsoleMessage
(
message
:
ConsoleMessage
?):
Boolean
{
Log
.
d
(
Log
.
d
(
"---pxl "
,
"---pxl "
,
...
...
app/src/main/java/com/sd/geelyhmiweb/utils/DateUtils.kt
0 → 100644
View file @
e02e65d3
package
com.sd.geelyhmiweb.utils
import
android.graphics.Color
import
android.text.SpannableString
import
android.text.style.ForegroundColorSpan
import
android.text.style.RelativeSizeSpan
import
androidx.core.text.set
import
java.text.ParseException
import
java.text.SimpleDateFormat
import
java.util.Calendar
import
java.util.Date
import
java.util.GregorianCalendar
import
java.util.Locale
import
java.util.TimeZone
/**
*author:pc-20171125
*data:2019/11/7 15:59
* 时间工具类
*/
object
DateUtils
{
val
FORMAT_YEAR
=
"yyyy"
val
FORMAT_MONTH_DAY
=
"MM月dd日"
val
FORMAT_DATE
=
"yyyy-MM-dd"
val
FORMAT_DATE_NO_SLASHES
=
"yyyyMMdd"
val
FORMAT_TIME
=
"HH:mm"
val
FORMAT_MONTH_DAY_TIME
=
"MM月dd日 HH:mm"
val
FORMAT_DATE_TIME
=
"yyyy-MM-dd HH:mm"
val
FORMAT_DATE1_TIME
=
"yyyy/MM/dd HH:mm"
val
FORMAT_DATE_TIME_SECOND
=
"yyyy-MM-dd HH:mm:ss"
val
FORMAT_MM_DD
=
"MM.dd"
val
FORMAT_YYYY_MM_DD
=
"yyyy.MM.dd"
val
FORMAT_DATE_CHINA
=
"yyyy年MM月dd日"
val
FORMAT_DATE_TIME_CHINA
=
"yyyy年MM月dd日 HH:mm"
// 显示聊天记录的格式
val
CHAT_TIME
=
"mm:ss"
private
val
sdf
=
SimpleDateFormat
(
FORMAT_DATE
,
Locale
.
CHINESE
)
private
val
YEAR
=
365
*
24
*
60
*
60
// 年
private
val
MONTH
=
30
*
24
*
60
*
60
// 月
private
val
DAY
=
24
*
60
*
60
// 天
private
val
HOUR
=
60
*
60
// 小时
private
val
MINUTE
=
60
// 分钟
/**
* 计算时间差
*/
fun
timeDifferenceDay
(
start_time
:
String
,
end_time
:
String
):
Int
{
var
sDate
=
sdf
.
parse
(
start_time
)
var
eDate
=
sdf
.
parse
(
end_time
)
var
diff
=
(
eDate
.
time
-
sDate
.
time
).
div
(
24
*
60
*
60
*
1000
).
toInt
()
// 将毫秒转换为天
return
diff
}
/**
* 比价时间前后
*/
fun
diffBeforeAfter
(
start_time
:
String
,
end_time
:
String
):
Boolean
{
if
(
end_time
.
isNullOrEmpty
())
{
return
false
}
var
star
=
stringToDate
(
start_time
,
FORMAT_TIME
)
var
end
=
stringToDate
(
end_time
,
FORMAT_TIME
)
return
star
?.
before
(
end
)
?:
false
}
/**
* 根据时间戳获取描述性时间,如3分钟前,1天前
*
* @param timestamp 时间戳 单位为毫秒
* @return 时间字符串
*/
fun
getDescriptionTimeFromTimestamp
(
timestamp
:
Long
):
String
{
val
currentTime
=
System
.
currentTimeMillis
()
// 与现在时间相差秒数
val
timeGap
=
(
currentTime
-
timestamp
)
/
1000
println
(
"timeGap: $timeGap"
)
val
timeStr
:
String
if
(
timeGap
>
YEAR
)
{
timeStr
=
(
timeGap
/
YEAR
).
toString
()
+
"年前"
}
else
if
(
timeGap
>
MONTH
)
{
timeStr
=
(
timeGap
/
MONTH
).
toString
()
+
"个月前"
}
else
if
(
timeGap
>
DAY
)
{
// 1天以上
timeStr
=
(
timeGap
/
DAY
).
toString
()
+
"天前"
}
else
if
(
timeGap
>
HOUR
)
{
// 1小时-24小时
timeStr
=
(
timeGap
/
HOUR
).
toString
()
+
"小时前"
}
else
if
(
timeGap
>
MINUTE
)
{
// 1分钟-59分钟
timeStr
=
(
timeGap
/
MINUTE
).
toString
()
+
"分钟前"
}
else
{
// 1秒钟-59秒钟
timeStr
=
"刚刚"
}
return
timeStr
}
/**
* 获取当前日期的指定格式的字符串
*
* @param format 指定的日期时间格式,若为null或""则使用指定的格式"yyyy-MM-dd HH:MM"
*/
fun
getCurrentTime
(
format
:
String
=
FORMAT_DATE
):
String
{
val
sdf
=
SimpleDateFormat
(
format
,
Locale
.
CHINESE
)
sdf
.
applyPattern
(
format
)
return
sdf
.
format
(
Date
())
}
/**
* 格林威治时间
*/
fun
getCurrentTimeGMT
():
String
{
val
cd
=
Calendar
.
getInstance
()
cd
.
add
(
Calendar
.
HOUR
,
+
8
)
val
sdf
=
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
,
Locale
.
US
)
sdf
.
timeZone
=
TimeZone
.
getTimeZone
(
"GMT"
)
// 设置时区为GMT
return
sdf
.
format
(
cd
.
getTime
())
}
/**
* date类型转换为String类型
* formatType格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
* data Date类型的时间
*/
fun
dateToString
(
data
:
Date
?,
formatType
:
String
):
String
{
return
SimpleDateFormat
(
formatType
).
format
(
data
)
}
/**
* long类型转换为String类型
* currentTime要转换的long类型的时间
* formatType要转换的string类型的时间格式
*/
@JvmStatic
fun
longToString
(
currentTime
:
Long
,
formatType
:
String
):
String
{
val
strTime
:
String
// long类型转成Date类型
val
date
=
longToDate
(
currentTime
,
formatType
)
// date类型转成String
strTime
=
dateToString
(
date
,
formatType
)
return
strTime
}
/**
* string类型转换为date类型
* strTime要转换的string类型的时间,formatType要转换的格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日
* HH时mm分ss秒,
* strTime的时间格式必须要与formatType的时间格式相同
*/
fun
stringToDate
(
strTime
:
String
,
formatType
:
String
):
Date
?
{
val
formatter
=
SimpleDateFormat
(
formatType
)
var
date
:
Date
?
=
null
try
{
date
=
formatter
.
parse
(
strTime
)
}
catch
(
e
:
ParseException
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
()
}
return
date
}
/**
* long转换为Date类型
* currentTime要转换的long类型的时间
* formatType要转换的时间格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
*/
fun
longToDate
(
currentTime
:
Long
,
formatType
:
String
):
Date
?
{
// 根据long类型的毫秒数生命一个date类型的时间
val
dateOld
=
Date
(
currentTime
)
// 把date类型的时间转换为string
val
sDateTime
=
dateToString
(
dateOld
,
formatType
)
// 把String类型转换为Date类型
return
stringToDate
(
sDateTime
,
formatType
)
}
/**
* string类型转换为long类型
*
* strTime要转换的String类型的时间
* formatType时间格式
* strTime的时间格式和formatType的时间格式必须相同
*/
fun
stringToLong
(
strTime
:
String
,
formatType
:
String
):
Long
{
// String类型转成date类型
val
date
=
stringToDate
(
strTime
,
formatType
)
return
if
(
date
==
null
)
{
0
}
else
{
// date类型转成long类型
dateToLong
(
date
)
}
}
/**
* date类型转换为long类型
* date要转换的date类型的时间
*/
fun
dateToLong
(
date
:
Date
):
Long
{
return
date
.
time
}
/**
* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.
*
* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);<br></br>
*
* 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。
*
* @param srcDate 要处理的源日期时间对象
* @param mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)
* @return 输出格式形如:“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
* @author 即时通讯网([url = http : / / www.52im.net]http : / / www.52im.net[ / url])
* @since 4.5
*/
fun
getTimeStringAutoShort2
(
srcDate
:
Date
,
mustIncludeTime
:
Boolean
):
String
{
var
ret
=
""
try
{
val
gcCurrent
=
GregorianCalendar
()
gcCurrent
.
time
=
Date
()
val
currentYear
=
gcCurrent
.
get
(
GregorianCalendar
.
YEAR
)
val
currentMonth
=
gcCurrent
.
get
(
GregorianCalendar
.
MONTH
)
+
1
val
currentDay
=
gcCurrent
.
get
(
GregorianCalendar
.
DAY_OF_MONTH
)
val
gcSrc
=
GregorianCalendar
()
gcSrc
.
time
=
srcDate
val
srcYear
=
gcSrc
.
get
(
GregorianCalendar
.
YEAR
)
val
srcMonth
=
gcSrc
.
get
(
GregorianCalendar
.
MONTH
)
+
1
val
srcDay
=
gcSrc
.
get
(
GregorianCalendar
.
DAY_OF_MONTH
)
// 要额外显示的时间分钟
val
timeExtraStr
=
if
(
mustIncludeTime
)
" "
+
getTimeString
(
srcDate
,
"HH:mm"
)
else
""
// 当年
if
(
currentYear
==
srcYear
)
{
val
currentTimestamp
=
gcCurrent
.
timeInMillis
val
srcTimestamp
=
gcSrc
.
timeInMillis
// 相差时间(单位:毫秒)
val
delta
=
currentTimestamp
-
srcTimestamp
// 当天(月份和日期一致才是)
if
(
currentMonth
==
srcMonth
&&
currentDay
==
srcDay
)
{
// 时间相差60秒以内
if
(
delta
<
60
*
1000
)
ret
=
"刚刚"
else
ret
=
getTimeString
(
srcDate
,
"HH:mm"
)
// 否则当天其它时间段的,直接显示“时:分”的形式
}
else
{
// 昨天(以“现在”的时候为基准-1天)
val
yesterdayDate
=
GregorianCalendar
()
yesterdayDate
.
add
(
GregorianCalendar
.
DAY_OF_MONTH
,
-
1
)
// 前天(以“现在”的时候为基准-2天)
val
beforeYesterdayDate
=
GregorianCalendar
()
beforeYesterdayDate
.
add
(
GregorianCalendar
.
DAY_OF_MONTH
,
-
2
)
// 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值
// 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,
// 这两者间只相差2小时,直接用“delta/(3600 * 1000)” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)
if
(
srcMonth
==
yesterdayDate
.
get
(
GregorianCalendar
.
MONTH
)
+
1
&&
srcDay
==
yesterdayDate
.
get
(
GregorianCalendar
.
DAY_OF_MONTH
)
)
{
ret
=
"昨天$timeExtraStr"
// -1d
}
else
if
(
srcMonth
==
beforeYesterdayDate
.
get
(
GregorianCalendar
.
MONTH
)
+
1
&&
srcDay
==
beforeYesterdayDate
.
get
(
GregorianCalendar
.
DAY_OF_MONTH
)
)
{
ret
=
"前天$timeExtraStr"
// -2d
}
else
{
// 跟当前时间相差的小时数
val
deltaHour
=
delta
/
(
3600
*
1000
)
// 如果小于 7*24小时就显示星期几
if
(
deltaHour
<
7
*
24
)
{
val
weekday
=
arrayOf
(
"星期日"
,
"星期一"
,
"星期二"
,
"星期三"
,
"星期四"
,
"星期五"
,
"星期六"
)
// 取出当前是星期几
val
weedayDesc
=
weekday
[
gcSrc
.
get
(
GregorianCalendar
.
DAY_OF_WEEK
)
-
1
]
ret
=
weedayDesc
+
timeExtraStr
}
else
ret
=
getTimeString
(
srcDate
,
"yyyy/M/d"
)
+
timeExtraStr
// 否则直接显示完整日期时间
}
// “前天”判断逻辑同上
}
// 当年 && 当天之外的时间(即昨天及以前的时间)
}
else
ret
=
getTimeString
(
srcDate
,
"yyyy/M/d"
)
+
timeExtraStr
}
catch
(
e
:
Exception
)
{
System
.
err
.
println
(
"【DEBUG-getTimeStringAutoShort】计算出错:"
+
e
.
message
+
" 【NO】"
)
}
return
ret
}
/**
* * 返回指定pattern样的日期时间字符串。
*
* @param dt
* @param pattern
* @return 如果时间转换成功则返回结果,否则返回空字符串""
* @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])
*/
fun
getTimeString
(
dt
:
Date
,
pattern
:
String
):
String
{
try
{
val
sdf
=
SimpleDateFormat
(
pattern
)
//"yyyy-MM-dd HH:mm:ss"
sdf
.
timeZone
=
TimeZone
.
getDefault
()
return
sdf
.
format
(
dt
)
}
catch
(
e
:
Exception
)
{
return
""
}
}
/**
* 获取会议时间
*/
public
fun
getConfTime
(
beginTime
:
String
,
endTime
:
String
):
String
{
//开始时间long
val
beginTimeLong
=
stringToLong
(
beginTime
,
FORMAT_DATE_TIME_SECOND
)
//结束时间long
val
endTimeLong
=
stringToLong
(
endTime
,
FORMAT_DATE_TIME_SECOND
)
//开始的年月
val
beginDate
=
longToString
(
beginTimeLong
,
FORMAT_DATE
)
val
endDate
=
longToString
(
endTimeLong
,
FORMAT_DATE
)
var
confTime
=
""
//开始的日期系统
if
(
beginDate
.
equals
(
endDate
))
{
confTime
=
"${
longToString
(
beginTimeLong
,
FORMAT_DATE_TIME
)
}-
$
{
longToString
(
endTimeLong
,
FORMAT_TIME
)}
"
}
else
{
confTime
=
"${
longToString
(
beginTimeLong
,
FORMAT_DATE_TIME
)
}-
$
{
longToString
(
endTimeLong
,
FORMAT_DATE_TIME
)}
"
}
return
confTime
}
/**
* 格式化时间
*
* @param longTime 时间
* @return 格式后的时间
* @history 2013-8-26 v1.0.0 cWX176935 create
* @since 1.1
*/
fun
formatTimeFString
(
longTime
:
Long
):
String
{
var
time
=
"%2d:%2d"
val
min
=
parseLongToInt
(
longTime
/
60
)
val
sec
=
parseLongToInt
(
longTime
%
60
)
time
=
String
.
format
(
time
,
min
,
sec
)
return
time
.
replace
(
' '
,
'0'
)
}
/**
* 格式化时间
*
* @param longTime 时间
* @return 格式后的时间 格式为1分1秒
* @history 2013-8-26 v1.0.0 cWX176935 create
* @since 1.1
*/
fun
longToString
(
longTime
:
Long
):
String
{
var
time
=
"%2d:%2d"
val
min
=
parseLongToInt
(
longTime
/
60
)
val
sec
=
parseLongToInt
(
longTime
%
60
)
var
timeBuilder
=
StringBuilder
()
if
(
min
>
0
)
{
timeBuilder
.
append
(
"${min}分"
)
}
timeBuilder
.
append
(
"${sec}秒"
)
return
timeBuilder
.
toString
()
}
/**
* @param value
* @return
*/
private
fun
parseLongToInt
(
value
:
Long
):
Int
{
return
Math
.
round
(
value
.
toFloat
())
}
/**
* 时间转 中文易读格式
*/
fun
secToTime
(
sec
:
Long
):
String
{
var
timeStr
=
""
var
hour
=
"00"
var
minute
=
"00"
var
second
=
"00"
hour
=
String
.
format
(
"%02d"
,
(
sec
/
3600
).
toInt
())
var
surplusMin
=
sec
%
3600
minute
=
String
.
format
(
"%02d"
,
(
surplusMin
/
60
).
toInt
())
var
surplusSec
=
surplusMin
%
60
second
=
String
.
format
(
"%02d"
,
surplusSec
)
timeStr
=
"${hour}:${minute}:${second}"
return
timeStr
}
/**
* 在订单详情里 时间转 中文易读格式
*/
fun
secToTimeOrderDetail
(
sec
:
Long
):
SpannableString
{
var
timeStr
=
""
var
hour
=
"00"
var
minute
=
"00"
var
second
=
"00"
hour
=
String
.
format
(
"%02d"
,
(
sec
/
3600
).
toInt
())
var
surplusMin
=
sec
%
3600
minute
=
String
.
format
(
"%02d"
,
(
surplusMin
/
60
).
toInt
())
// var surplusSec = surplusMin % 60
// second = String.format("%02d", surplusSec)
timeStr
=
"${hour} 小时 ${minute} 分钟"
var
star
=
0
var
end
=
star
+
hour
.
count
()
val
sizeSpan1
=
RelativeSizeSpan
(
1.4f
)
val
sizeSpan2
=
RelativeSizeSpan
(
1.4f
)
var
spanStr
=
SpannableString
(
timeStr
)
spanStr
.
set
(
star
..
end
,
sizeSpan1
)
star
=
end
+
4
end
=
star
+
minute
.
count
()
spanStr
.
set
(
star
..
end
,
sizeSpan2
)
return
spanStr
}
/**
* 子订单剩余时间 中文易读格式
*/
fun
orderGrabbingDecToTime
(
sec
:
Long
):
SpannableString
{
var
timeStr
:
SpannableString
var
day
=
"00"
var
hour
=
"00"
var
minute
=
"00"
var
second
=
"00"
day
=
String
.
format
(
"%02d"
,
(
sec
/
(
3600
*
24
)).
toInt
())
var
surplusHour
=
sec
%
(
3600
*
24
)
hour
=
String
.
format
(
"%02d"
,
(
surplusHour
/
3600
).
toInt
())
var
surplusMin
=
sec
%
3600
minute
=
String
.
format
(
"%02d"
,
(
surplusMin
/
60
).
toInt
())
var
surplusSec
=
surplusMin
%
60
second
=
String
.
format
(
"%02d"
,
surplusSec
)
timeStr
=
SpannableString
(
"有效期还剩 ${day}天: ${hour}小时: ${minute}分: ${second}秒"
)
var
foregroundColorSpan1
=
ForegroundColorSpan
(
Color
.
parseColor
(
"#F95F2C"
))
var
foregroundColorSpan2
=
ForegroundColorSpan
(
Color
.
parseColor
(
"#F95F2C"
))
var
foregroundColorSpan3
=
ForegroundColorSpan
(
Color
.
parseColor
(
"#F95F2C"
))
var
foregroundColorSpan4
=
ForegroundColorSpan
(
Color
.
parseColor
(
"#F95F2C"
))
var
star
=
6
var
end
=
6
+
day
.
count
()
timeStr
.
set
(
star
..
end
,
foregroundColorSpan1
)
star
=
end
+
3
end
=
star
+
hour
.
count
()
timeStr
.
set
(
star
,
end
,
foregroundColorSpan2
)
star
=
end
+
4
end
=
star
+
minute
.
count
()
timeStr
.
set
(
star
..
end
,
foregroundColorSpan3
)
star
=
end
+
3
end
=
star
+
second
.
count
()
timeStr
.
set
(
star
..
end
,
foregroundColorSpan4
)
return
timeStr
}
}
\ No newline at end of file
app/src/main/java/com/sd/geelyhmiweb/utils/FileIoUtils.kt
0 → 100644
View file @
e02e65d3
package
com.sd.geelyhmiweb.utils
import
android.os.Environment
import
android.util.Log
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.withContext
import
java.io.File
import
java.io.FileWriter
import
java.io.IOException
object
FileIoUtils
{
private
var
fileWriter
:
FileWriter
?
=
null
suspend
fun
writeToFile
(
message
:
String
,
fileName
:
String
)
{
// if (MyContants.WRITE_LOG){
withContext
(
Dispatchers
.
IO
)
{
try
{
val
file
=
File
(
Environment
.
getExternalStoragePublicDirectory
(
Environment
.
DIRECTORY_DOWNLOADS
),
fileName
)
fileWriter
=
FileWriter
(
file
,
true
)
// true for append mode
fileWriter
!!
.
append
(
"$message\n"
)
fileWriter
!!
.
flush
()
// Optional, to ensure immediate writing to file
}
catch
(
e
:
IOException
)
{
Log
.
e
(
"------writeToFile"
,
"Error initializing log file"
,
e
)
}
}
// }
}
}
\ No newline at end of file
app/src/main/java/com/sd/geelyhmiweb/viewmodels/MainVM.kt
0 → 100644
View file @
e02e65d3
package
com.sd.geelyhmiweb.viewmodels
import
android.content.Context
import
androidx.lifecycle.ViewModel
import
androidx.lifecycle.viewModelScope
import
com.sd.geelyhmiweb.utils.FileIoUtils
import
dagger.hilt.android.lifecycle.HiltViewModel
import
dagger.hilt.android.qualifiers.ApplicationContext
import
kotlinx.coroutines.launch
import
javax.inject.Inject
@HiltViewModel
class
MainVM
@Inject
constructor
(
// private var loginRepo: LoginRepo,
@ApplicationContext
var
context
:
Context
)
:
ViewModel
()
{
fun
writeLog
(
str
:
String
){
viewModelScope
.
launch
{
FileIoUtils
.
writeToFile
(
str
,
"log.txt"
)
}
}
}
\ No newline at end of file
app/src/main/res/xml/file_paths.xml
0 → 100644
View file @
e02e65d3
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name=
"external-path"
path=
"."
/>
</paths>
</resources>
\ 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