Commit 1ccbc004 authored by p x's avatar p x
Browse files

first

parent 032ec619
Pipeline #3090 failed with stages
in 0 seconds
package com.sd.cavphmi.net
import com.google.gson.Gson
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
object RequestBodyUtil {
/**
* 将参数封装成requestBody形式上传参数
* @param param 参数
* @return RequestBody
*/
fun toRequestBody(map: Map<String, Any>): RequestBody {
val gson = Gson()
var param = gson.toJson(map)
return param.toRequestBody("application/json;charset=UTF-8".toMediaTypeOrNull())
}
fun toRequestBody(any: Any): RequestBody {
var gson = Gson()
return gson.toJson(any)
.toRequestBody("application/json;charset=UTF-8".toMediaTypeOrNull())
}
}
\ No newline at end of file
package com.sd.cavphmi.net
import com.google.gson.GsonBuilder
import com.sd.cavphmi.MyAppcation
import com.sd.cavphmi.utils.MyContants
import okhttp3.Cache
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.io.File
object RetrofitApi {
// val CLIENT_BASIC = Credentials.basic("river-chief-server", "123456")
var retrofitBuild: Retrofit.Builder
var cache: Cache
init {
//设置缓存路径
val httpCacheDirectory =
File(
MyAppcation.instance().applicationContext.externalCacheDir,
"okhttp"
)
//设置缓存
cache = Cache(httpCacheDirectory, 50 * 1024 * 1024)
val mGson = GsonBuilder()
// .registerTypeAdapter(HttpErrorBean::class.java, HttpErrorTypeAdapter())
// .setLenient() // 设置GSON的非严格模式setLenient()
.create()
retrofitBuild = Retrofit.Builder()
.baseUrl(MyContants.HOST)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(mGson))
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
}
// fun getSSlSocketFactory(): SslData {
// val trustManagerFactory: TrustManagerFactory = TrustManagerFactory.getInstance(
// TrustManagerFactory.getDefaultAlgorithm()
// )
// trustManagerFactory.init(null as KeyStore?)
// val trustManagers: Array<TrustManager> = trustManagerFactory.getTrustManagers()
// check(!(trustManagers.size != 1 || trustManagers[0] !is X509TrustManager)) {
// ("Unexpected default trust managers:"
// + Arrays.toString(trustManagers))
// }
// val trustManager = trustManagers[0] as X509TrustManager
//
//
// val sslContext = SSLContext.getInstance("TLS")
// sslContext.init(null, arrayOf<TrustManager>(trustManager), null)
// val sslSocketFactory = sslContext.socketFactory
//
// return SslData(sslSocketFactory, trustManager)
// }
//
// data class SslData(val sslSocketFactory: SSLSocketFactory, var trustManager: X509TrustManager)
}
\ No newline at end of file
package com.sd.cavphmi.ui
import android.Manifest
import android.content.Intent
import androidx.lifecycle.ViewModelProvider
import com.minedata.minenavi.SDKInitializer
import com.minedata.minenavi.SDKInitializer.InitListener
import com.minedata.minenavi.mapdal.CoordType
import com.minedata.minenavi.poiquery.SearchUrlType
import com.permissionx.guolindev.PermissionX
import com.sd.cavphmi.BR
import com.sd.cavphmi.R
import com.sd.cavphmi.base.BaseActivity
import com.sd.cavphmi.base.MyBaseViewModel
import com.sd.cavphmi.databinding.ActivityBootBinding
import com.sd.cavphmi.utils.ToastHelper
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class BootActivity : BaseActivity<ActivityBootBinding, MyBaseViewModel>() {
// private val tcpUpVM: TcpUpVM by viewModels()
override fun getStatuBarColor(): Int {
return -1
}
override fun initContentView(): Int {
return R.layout.activity_boot
}
override fun initViewModel(): MyBaseViewModel {
return ViewModelProvider(this).get(MyBaseViewModel::class.java)
}
override fun initVariableId(): Int {
return BR.vm
}
// private var latLngInfo: LatLngInfo? = null
override fun initView() {
// tcpUpVM.owner=this
// tcpUpVM.upWork()
// viewModel.testWork()
initMap()
requestPers()
}
// fun getLatLngInfo() {
// latLngInfo = intent.getParcelableExtra<LatLngInfo>(MyContants.LAT_LNG_INFO)
//// var lat = intent.getDoubleExtra("LAT", 0.0)
//// var lng = intent.getDoubleExtra("LNG", 0.0)
// println("---------智慧 boot lng = ${latLngInfo?.lng} lat = ${latLngInfo?.lat}")
//// println("---------智慧 直接传 lat = $lat lng = $lng")
// }
private fun starMain() {
// requestPers()
binding.imageView.postDelayed({
var jump = Intent(this, MainActivity::class.java)
startActivity(jump)
finish()
}, 1000)
}
fun initMap() {
// 隐私合规接口
SDKInitializer.setAgreePrivacy(true)
// if (SDKInitializer.getServerHost().equals("mineservice.minedata.cn")) {
// SDKInitializer.setStyleUrl(
// MineMap.UrlType.basicMap,
// "https://service.minedata.cn/map/solu/style/1359221494104252416"
// )
// }
// 设置地图坐标系
SDKInitializer.setCoordType(CoordType.GCJ02)
SDKInitializer.setSearchUrlType(SearchUrlType.v1)
SDKInitializer.initialize(this, object : InitListener {
override fun onInitSuccess() {
println("---Map onInitSuccess map")
}
override fun onInitFailed(msg: String?) {
println("---Map onInitFailed msg = ${msg}")
}
})
}
fun requestPers() {
var list = listOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
)
PermissionX.init(this)
.permissions(list)
.onExplainRequestReason { scope, deniedList ->
scope.showRequestReasonDialog(deniedList, "Adas 需要同意以下授权才能正常使用", "好的", "取消")
}
// .onForwardToSettings { scope, deniedList ->
// scope.showForwardToSettingsDialog(deniedList, "您需要手动在‘设置’中允许必要的权限", "OK", "Cancel")
// }
.request { allGranted, grantedList, deniedList ->
if (allGranted) {
// ToastHelper.showShort(this, "All permissions are granted")
starMain()
} else {
ToastHelper.showShort(this, "权限被拒")
binding.root.postDelayed({
finish()
},150)
}
}
}
}
\ No newline at end of file
package com.sd.cavphmi.ui
import androidx.lifecycle.ViewModelProvider
import com.sd.cavphmi.BR
import com.sd.cavphmi.R
import com.sd.cavphmi.base.BaseActivity
import com.sd.cavphmi.base.MyBaseViewModel
import com.sd.cavphmi.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
override fun getStatuBarColor(): Int {
return -1
}
override fun initContentView(): Int {
return R.layout.activity_main
}
override fun initViewModel(): MyBaseViewModel {
return ViewModelProvider(this).get(MyBaseViewModel::class.java)
}
override fun initVariableId(): Int {
return BR.vm
}
override fun initView() {
}
}
\ No newline at end of file
package com.sd.cavphmi.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 com.minedata.minenavi.addons.DistanceBean
import com.minedata.minenavi.util.MineNaviUtil
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
/**
*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()
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// 分钟
/**
**计算预计用时
* @param speed 米/秒
* @param dis 米
**/
fun getExpectedTime(speed: Int, dis: Int): String {
if (speed == 0 || dis == 0)
return "剩余0分"
var mUtils = Utils()
var remainingTime = dis / speed
val s_arriveTime =
MineNaviUtil.relativeTimeStringFromNow(
remainingTime,
mUtils.is24Hour()
)
var stringBuilder = StringBuilder()
if (s_arriveTime.contains("天")) {
stringBuilder.append("预计")
.append(s_arriveTime.substring(0, s_arriveTime.indexOf("天") + 1) + "")
.append(s_arriveTime.substring(s_arriveTime.indexOf("天") + 1, s_arriveTime.length))
.append("到达")
} else if (s_arriveTime.contains("日")) {
stringBuilder.append("预计")
.append(s_arriveTime.substring(0, s_arriveTime.indexOf("日") + 1) + "")
.append(s_arriveTime.substring(s_arriveTime.indexOf("日") + 1, s_arriveTime.length))
.append("到达")
} else {
stringBuilder.append("预计").append(s_arriveTime).append("到达")
}
return stringBuilder.toString()
}
fun getExpectedTime(speed: Int, distanceBean: DistanceBean): String {
if (speed == 0 || distanceBean.distanceValue.toFloat() == 0f)
return "剩余0.0分"
var dis = 0//单位米
if (distanceBean.distanceUnit.contains("公里")) {
dis = distanceBean.distanceValue.toInt() * 1000
}
var mUtils = Utils()
var remainingTime = dis / speed
val s_arriveTime =
MineNaviUtil.relativeTimeStringFromNow(
remainingTime,
mUtils.is24Hour()
)
var stringBuilder = StringBuilder()
if (s_arriveTime.contains("天")) {
stringBuilder.append("预计")
.append(s_arriveTime.substring(0, s_arriveTime.indexOf("天") + 1) + "")
.append(s_arriveTime.substring(s_arriveTime.indexOf("天") + 1, s_arriveTime.length))
.append("到达")
} else if (s_arriveTime.contains("日")) {
stringBuilder.append("预计")
.append(s_arriveTime.substring(0, s_arriveTime.indexOf("日") + 1) + "")
.append(s_arriveTime.substring(s_arriveTime.indexOf("日") + 1, s_arriveTime.length))
.append("到达")
} else {
stringBuilder.append("预计").append(s_arriveTime).append("到达")
}
return stringBuilder.toString()
}
/**
* 计算时间差
*/
fun timeDifference(start_time: String, end_time: String): Long {
var star = stringToDate(start_time, FORMAT_TIME)?.time ?: 0
var end = stringToDate(end_time, FORMAT_TIME)?.time ?: 0
var longExpend = end - star
return longExpend
}
/**
* 比价时间前后
*/
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 {
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
package com.ltzw.adasdriver.utils
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Build
import android.provider.Settings
import android.util.DisplayMetrics
import android.util.TypedValue
/**
*author:pc-20171125
*data:2019/11/7 16:08
*/
object DisplayUtil {
fun getDpi(): Int {
return Resources.getSystem().displayMetrics.densityDpi
}
fun px2dp(pxValue: Float): Int {
val scale = Resources.getSystem().displayMetrics.density
return (pxValue / scale + 0.5f).toInt()
}
fun dp2px(dipValue: Float): Int {
val scale = Resources.getSystem().displayMetrics.density
return (dipValue * scale + 0.5f).toInt()
}
fun px2sp(pxValue: Float): Int {
val fontScale = Resources.getSystem().displayMetrics.scaledDensity
return (pxValue / fontScale + 0.5f).toInt()
}
fun sp2px(spValue: Float): Int {
val fontScale = Resources.getSystem().displayMetrics.scaledDensity
return (spValue * fontScale + 0.5f).toInt()
}
private val mTmpValue = TypedValue()
fun getXmlDef(context: Context, id: Int): Int {
synchronized(mTmpValue) {
val value: TypedValue = mTmpValue
context.resources.getValue(id, value, true)
return TypedValue.complexToFloat(value.data).toInt()
}
}
fun getNavigationBarHeight(context: Context): Int {
val mInPortrait =
context.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
val result = 0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
if (hasNavBar(context as Activity)) {
val key: String
if (mInPortrait) {
key = "navigation_bar_height"
} else {
key = "navigation_bar_height_landscape"
}
return getInternalDimensionSize(context, key)
}
}
return result
}
private fun hasNavBar(activity: Activity): Boolean {
//判断小米手机是否开启了全面屏,开启了,直接返回false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Settings.Global.getInt(activity.contentResolver, "force_fsg_nav_bar", 0) != 0) {
return false
}
}
//其他手机根据屏幕真实高度与显示高度是否相同来判断
val windowManager = activity.windowManager
val d = windowManager.defaultDisplay
val realDisplayMetrics = DisplayMetrics()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
d.getRealMetrics(realDisplayMetrics)
}
val realHeight = realDisplayMetrics.heightPixels
val realWidth = realDisplayMetrics.widthPixels
val displayMetrics = DisplayMetrics()
d.getMetrics(displayMetrics)
val displayHeight = displayMetrics.heightPixels
val displayWidth = displayMetrics.widthPixels
return realWidth - displayWidth > 0 || realHeight - displayHeight > 0
}
private fun getInternalDimensionSize(context: Context, key: String): Int {
var result = 0
try {
val resourceId = context.resources.getIdentifier(key, "dimen", "android")
if (resourceId > 0) {
result =
Math.round(context.resources.getDimensionPixelSize(resourceId) * Resources.getSystem().displayMetrics.density / context.resources.displayMetrics.density)
}
} catch (ignored: Resources.NotFoundException) {
return 0
}
return result
}
}
\ No newline at end of file
package com.ltzw.adasdriver.utils
import android.os.Build
object MobileUtils {
// if (ModelUtils.isEMUI() && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
// mPwdEt.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL);
// mPwdEt.setTransformationMethod(PasswordTransformationMethod.getInstance());
// }
fun isMIUI(): Boolean {
val manufacturer: String = Build.MANUFACTURER
return "xiaomi".equals(manufacturer, ignoreCase = true)
}
fun isEMUI(): Boolean {
val manufacturer: String = Build.MANUFACTURER
return "HUAWEI".equals(manufacturer, ignoreCase = true)
}
fun isOPPO(): Boolean {
val manufacturer: String = Build.MANUFACTURER
return "OPPO".equals(manufacturer, ignoreCase = true)
}
fun isVIVO(): Boolean {
val manufacturer: String = Build.MANUFACTURER
return "vivo".equals(manufacturer, ignoreCase = true)
}
}
\ No newline at end of file
package com.sd.cavphmi.utils
object MyContants {
const val IS_DEBUG = true
var HOST = if (IS_DEBUG) "http://laravel.suiyigou.shop/" else "https://api.suixinsuiyi.cn/"
var PORT = if (IS_DEBUG) "123" else "34534"
var SOCKET_HOSTNAME =
if (IS_DEBUG) "192.168.60.77" else ""
var SOCKET_RECEIVE_PORT =
if (IS_DEBUG) 8082 else 0
var DOWNLOAD_APP_URL =
"https://app.mi.com/download/1325540?id=com.sxsy.easyclient&ref=search&nonce=-6756103978404716128%3A26875199&appClientId=2882303761517485445&appSignature=BJDg3ZbQJhRoaomIe0kkGJ32i6hbX9HduukAmwpZqpQ"
const val PERMISSON_REQUESTCODE: Int = 10
const val online = true
/**
* 智旅APK传智*/
const val LAT_LNG_INFO = "LAT_LNG_INFO"
/***当前速度***/
var CUR_SPEED = 0
const val MOCK_LAT = 39.9129
const val MOCK_LNG = 116.3723
// var CUR_LAT = MOCK_LAT
// var CUR_LNG = MOCK_LNG
var CUR_LAT = 0.0
var CUR_LNG = 0.0
// const val MOCK_LAT = 39.56
// const val MOCK_LNG = 116.20
// 116.372641,39.913242
}
\ No newline at end of file
package com.sd.cavphmi.utils
import androidx.security.crypto.EncryptedSharedPreferences
import com.sd.cavphmi.MyAppcation
object MyPres {
private const val PREFS_NAME = "adas"
private const val MASTER_KEY_ALIAS = "masterkeyalias"
private val sharedPreferences by lazy {
EncryptedSharedPreferences.create(
PREFS_NAME,
MASTER_KEY_ALIAS,
MyAppcation.instance().applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}
var token: String
set(value) {
with(sharedPreferences.edit()) {
putString("token", value)
commit()
}
}
get() {
return sharedPreferences.getString("token", "") ?: ""
}
var hisSearch: String
set(value) {
with(sharedPreferences.edit()) {
putString("hisSearch", value)
commit()
}
}
get() {
return sharedPreferences.getString("hisSearch", "") ?: ""
}
/**
* 全类型历史搜素
*/
var curLat: String
set(value) {
with(sharedPreferences.edit()) {
putString("curLat", value)
commit()
}
}
get() {
return sharedPreferences.getString("curLat", "") ?: ""
}
/**
* 专题资料历史搜素
*/
var curLng: String
set(value) {
with(sharedPreferences.edit()) {
putString("curLng", value)
commit()
}
}
get() {
return sharedPreferences.getString("curLng", "") ?: ""
}
/**
* 资料历史搜素
*/
var dataSearch: String
set(value) {
with(sharedPreferences.edit()) {
putString("dataSearch", value)
commit()
}
}
get() {
return sharedPreferences.getString("dataSearch", "") ?: ""
}
/**
* 问答历史搜素
*/
var qaSearch: String
set(value) {
with(sharedPreferences.edit()) {
putString("qaSearch", value)
commit()
}
}
get() {
return sharedPreferences.getString("qaSearch", "") ?: ""
}
/**
* 首次授权
*/
var isFrist: Boolean
set(value) {
with(sharedPreferences.edit()) {
putBoolean("isFrist", value)
commit()
}
}
get() {
return sharedPreferences.getBoolean("isFrist", true)
}
/**
* 邀请码
*/
var invCode: String
set(value) {
with(sharedPreferences.edit()) {
putString("invcode", value)
commit()
}
}
get() {
return sharedPreferences.getString("invcode", "") ?: ""
}
/**
* 个人电话
*/
var mobile: String
set(value) {
with(sharedPreferences.edit()) {
putString("mobile", value)
commit()
}
}
get() {
return sharedPreferences.getString("mobile", "") ?: ""
}
/**
* 删除领域
*/
var goodField: String
set(value) {
with(sharedPreferences.edit()) {
putString("goodField", value)
commit()
}
}
get() {
return sharedPreferences.getString("goodField", "") ?: ""
}
var userId: String
set(value) {
with(sharedPreferences.edit()) {
putString("userId", value)
commit()
}
}
get() {
return sharedPreferences.getString("userId", "") ?: ""
}
/**
* 极光推送ID
*/
var registrationId: String
set(value) {
with(sharedPreferences.edit()) {
putString("registrationId", value)
commit()
}
}
get() {
return sharedPreferences.getString("registrationId", "") ?: ""
}
}
\ No newline at end of file
package com.sd.cavphmi.utils;
import static android.content.Context.WINDOW_SERVICE;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import androidx.annotation.RequiresApi;
import com.gyf.barlibrary.BarHide;
import com.gyf.barlibrary.ImmersionBar;
import com.sd.cavphmi.R;
import java.lang.reflect.Method;
import java.util.List;
/**
* 获取一些屏幕相关的信息
*/
public class ScreenUtil {
private static final String PHONE_FLAG_XIAO_MI = "xiaomi";
private static final String PHONE_FLAG_HUA_WEI = "HUAWEI";
private static final String PHONE_FLAG_OPPO = "oppo";
private static final String PHONE_FLAG_VIVO = "vivo";
public static final int NAVIGATION_BAR_ON_RIGHT = 1;
public static final int NAVIGATION_BAR_ON_LiFT = 3;
private Context mContext;
private Window mWindow;
private WindowManager mWindowManager;
private View statusView;
private int mNavigationBarHeight;
private boolean isUserChangeSystemBrightness = false;
private int mCurrentSystemBrightness = 100;
private DisplayMetrics mDisplayMetrics;
private int mNotchWidth = 0;
private int mNotchHeight = 0;
private int mHorizontalMaxWidth;
public void init(Context context, Window window) {
mContext = context;
mWindow = window;
mWindowManager = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
mHorizontalMaxWidth = Utils.getInstance().dp2Px(465);
}
private static class SingletonHolder {
public static final ScreenUtil instance = new ScreenUtil();
}
public static ScreenUtil getInstance() {
return SingletonHolder.instance;
}
public int getNotchWidth() {
if (mNotchWidth != 0) {
return mNotchWidth;
}
int notchWidth = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
//小米8升级到MIUI 11后获取的刘海宽度有问题 为676 官方为560,有问题会影响自定义状态栏,为防止其他型号手机升级有问题,以下数据写死
//来源 https://dev.mi.com/console/doc/detail?pId=1341
if (Build.MODEL.equals("MI 8") || Build.MODEL.equals("MI 8 Explorer Edition") || Build.MODEL.equals("MI 8 UD")) {
notchWidth = 560;
} else if (Build.MODEL.equals("MI 8 SE")) {
notchWidth = 540;
} else if (Build.MODEL.equals("MI8Lite")) {
notchWidth = 296;
} else if (Build.MODEL.equals("POCO F1")) {
notchWidth = 588;
} else if (Build.MODEL.equals("Redmi 6 Pro")) {
notchWidth = 352;
} else if (Build.MODEL.equals("Redmi Note 7")) {
notchWidth = 116;
}
if (notchWidth != 0) {
return notchWidth;
}
DisplayCutout displayCutout = getDisplayCutout((Activity) mContext);
if (displayCutout != null) {
List<Rect> boundingRects = displayCutout.getBoundingRects();
if (boundingRects.size() != 0) {
int left = boundingRects.get(0).left;
int screenWidth = getScreenWidth();
if (left > screenWidth / 2) {//刘海描述右边的区域
notchWidth = screenWidth - (screenWidth - left) * 2;
} else {
notchWidth = screenWidth - left * 2;
}
}
}
} else {
if (isXiaoMiPhone()) {
notchWidth = getXiaoMiNotchSize(mContext)[0];
} else if (isHUAWEIPhone()) {
notchWidth = getHuaWeiNotchSize(mContext)[0];
} else if (isOPPOPhone()) {
notchWidth = 324;
} else if (isVivoPhone()) {
notchWidth = Utils.getInstance().dp2Px(100);
}
}
mNotchWidth = notchWidth;
return notchWidth;
}
public int getNotchHeight() {
if (mNotchHeight != 0) {
return mNotchHeight;
}
int notchHeight = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
DisplayCutout displayCutout = getDisplayCutout((Activity) mContext);
if (displayCutout != null) { //通过cutout是否为null判断目前是否开启了刘海屏
List<Rect> boundingRects = displayCutout.getBoundingRects();
if (boundingRects.size() != 0) {
Rect rect = boundingRects.get(0);
notchHeight = rect.height();
//如果刘海的高度大于150,证明是横屏,有问题,取width()
if (notchHeight > 150) {
notchHeight = rect.width();
}
}
} else {
return notchHeight;
}
} else {
if (isXiaoMiPhone()) {
notchHeight = getXiaoMiNotchSize(mContext)[1];
} else if (isHUAWEIPhone()) {
notchHeight = getHuaWeiNotchSize(mContext)[1];
} else if (isOPPOPhone()) {
notchHeight = 80;
} else if (isVivoPhone()) {
notchHeight = Utils.getInstance().dp2Px(32);// 32dp为状态栏高度,刘海高度为27dp
}
}
if (notchHeight == 0) {
notchHeight = getStatusBarHeight();
}
mNotchHeight = notchHeight;
return notchHeight;
}
public int getLiuHaiping() {
if (mNotchHeight != 0) {
return mNotchHeight;
}
int notchHeight = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
DisplayCutout displayCutout = getDisplayCutout((Activity) mContext);
if (displayCutout != null) { //通过cutout是否为null判断目前是否开启了刘海屏
List<Rect> boundingRects = displayCutout.getBoundingRects();
if (boundingRects.size() != 0) {
Rect rect = boundingRects.get(0);
notchHeight = rect.height();
//如果刘海的高度大于150,证明是横屏,有问题,取width()
if (notchHeight > 150) {
notchHeight = rect.width();
}
}
} else {
return notchHeight;
}
} else {
if (isXiaoMiPhone()) {
notchHeight = getXiaoMiNotchSize(mContext)[1];
} else if (isHUAWEIPhone()) {
notchHeight = getHuaWeiNotchSize(mContext)[1];
} else if (isOPPOPhone()) {
notchHeight = 80;
} else if (isVivoPhone()) {
notchHeight = Utils.getInstance().dp2Px(32);// 32dp为状态栏高度,刘海高度为27dp
}
}
return notchHeight;
}
@RequiresApi(api = Build.VERSION_CODES.M)
private DisplayCutout getDisplayCutout(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
View decorView = activity.getWindow().getDecorView();
if (decorView != null) {
WindowInsets windowInsets = decorView.getRootWindowInsets();
if (windowInsets != null) {
return windowInsets.getDisplayCutout();
}
}
}
return null;
}
/**
* 获取状态栏高度
*/
public int getStatusBarHeight() {
int statusBarHeight = 0;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
statusBarHeight = mContext.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
if (statusBarHeight == 0) {
int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = mContext.getResources().getDimensionPixelSize(resourceId);
}
}
if (statusBarHeight == 0) {
Rect rectangle = new Rect();
mWindow.getDecorView().getWindowVisibleDisplayFrame(rectangle);
statusBarHeight = rectangle.top;
}
return statusBarHeight;
}
/**
* 能否用自定义状态栏
*/
public boolean useCustomStatusBar() {
if (!canUseImmersive()) {
return false;
}
if (isXiaoMiOpenHideFullScreenToggle(mContext)) {
return false;
}
return true;
}
/**
* 获取小米手机刘海屏宽高 int[0] 为宽度 int[1] 为高度
*/
private int[] getXiaoMiNotchSize(Context context) {
int[] ret = new int[]{0, 0};
int resourceWidthId = context.getResources().getIdentifier("notch_width", "dimen", "android");
if (resourceWidthId > 0) {
ret[0] = (context.getResources().getDimensionPixelSize(resourceWidthId)) + 10;
}
int resourceHeightId = context.getResources().getIdentifier("notch_height", "dimen", "android");
if (resourceHeightId > 0) {
ret[1] = context.getResources().getDimensionPixelSize(resourceHeightId) + 30;
}
return ret;
}
/**
* 获取华为手机刘海屏宽高 int[0] 为宽度 int[1] 为高度
*/
private int[] getHuaWeiNotchSize(Context context) {
int[] ret = new int[]{0, 0};
try {
ClassLoader cl = context.getClassLoader();
Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
Method get = HwNotchSizeUtil.getMethod("getNotchSize");
ret = (int[]) get.invoke(HwNotchSizeUtil);
} catch (ClassNotFoundException e) {
Log.e("test", "getNotchSize ClassNotFoundException");
} catch (NoSuchMethodException e) {
Log.e("test", "getNotchSize NoSuchMethodException");
} catch (Exception e) {
Log.e("test", "getNotchSize Exception");
} finally {
return ret;
}
}
public boolean isXiaoMiPhone() {
return Build.MANUFACTURER.equalsIgnoreCase(PHONE_FLAG_XIAO_MI);
}
public boolean isHUAWEIPhone() {
return Build.MANUFACTURER.equalsIgnoreCase(PHONE_FLAG_HUA_WEI);
}
public boolean isOPPOPhone() {
return Build.MANUFACTURER.equalsIgnoreCase(PHONE_FLAG_OPPO);
}
public boolean isVivoPhone() {
return Build.MANUFACTURER.equalsIgnoreCase(PHONE_FLAG_VIVO);
}
/**
* 小米是否开启了隐藏全面屏的开关(系统设置里)
*/
public boolean isXiaoMiOpenHideFullScreenToggle(Context context) {
return ImmersionBar.hasNotchScreen((Activity) context) && isXiaoMiPhone()
&& Settings.Global.getInt(context.getContentResolver(), "force_black", 0) == 1;
}
/**
* 获取当前屏幕的亮度
*
* @param context
* @return 返回是一个int值 在0 ~ 255之间
*/
public int getSystemBrightness(Context context) {
int nowBrightnessValue = 0;
try {
nowBrightnessValue = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
} catch (Exception e) {
e.printStackTrace();
}
return nowBrightnessValue;
}
/**
* 设置当前系统屏幕亮度值 0 ~ 255
*
* @param context
* @param paramInt 设置的值
*/
public void setSystemScreenBrightness(Context context, int paramInt) {
try {
Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, paramInt);
} catch (Exception localException) {
localException.printStackTrace();
}
}
/**
* 判断是否开启了自动亮度调节
* 自动 = 1 SCREEN_BRIGHTNESS_MODE_AUTOMATIC
* 手动 = 0 SCREEN_BRIGHTNESS_MODE_MANUAL
*
* @param context
* @return
*/
public boolean isAutoBrightness(Context context) {
boolean isAutoBrightness = false;
try {
isAutoBrightness = Settings.System.getInt(
context.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
return isAutoBrightness;
}
/**
* 改变App当前Window亮度
* lp.screenBrightness 范围 0.0 ~ 1.0之间
*
* @param brightness
* @param context activity的context
*/
public void changeAppBrightness(Context context, float brightness) {
Window window = ((Activity) context).getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
if (brightness == -1) {
lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
} else {
lp.screenBrightness = brightness;
}
window.setAttributes(lp);
}
/**
* 停止自动亮度调节
*
* @param context
*/
public void stopAutoBrightness(Context context) {
Settings.System.putInt(context.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
}
/**
* 开启亮度自动调节
*
* @param context
*/
public void startAutoBrightness(Context context) {
Settings.System.putInt(context.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
}
public void cleanup() {
mContext.getContentResolver().unregisterContentObserver(mBrightnessObserver);
}
/**
* 设置降低屏幕亮度策略
*
* @param enable 是否打开
*/
public void enableScreenBrightnessDarkStrategy(boolean enable) {
if (Utils.getInstance().isCharging() || isAutoBrightness(mContext)) {
return;
}
if (enable) {
isUserChangeSystemBrightness = false;
mCurrentSystemBrightness = getSystemBrightness(mContext);
setSystemScreenBrightness(mContext, mCurrentSystemBrightness / 2);
mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), false, mBrightnessObserver);
} else {
mContext.getContentResolver().unregisterContentObserver(mBrightnessObserver);
if (!isUserChangeSystemBrightness)
setSystemScreenBrightness(mContext, mCurrentSystemBrightness);
}
}
/**
* 注册光观察者: context.getContentResolver().registerContentObserver(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), false, mBrightnessObserver);
* 应用销毁解观察者: context.getContentResolver().unregisterContentObserver(mBrightnessObserver);
* 如果开启自动亮度调节,获取系统亮度,是一个值,调节bar,获取系统亮度还是那个值
* 如果关闭自动亮度调节,获取的亮度是一个值,调节bar,获取系统亮度是调节后的值
* 如果开启自动亮度调节,此方法监听不到系统亮度变化
*/
private ContentObserver mBrightnessObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
isUserChangeSystemBrightness = true;
}
};
public Window getWindow() {
return mWindow;
}
/**
* 获取屏幕宽 可用显示区域大小
*/
public int getScreenWidth() {
mDisplayMetrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(mDisplayMetrics);
return mDisplayMetrics.widthPixels;
}
public int getScreenHeight() {
mDisplayMetrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(mDisplayMetrics);
return mDisplayMetrics.heightPixels;
}
/**
* 获取横向屏幕可用显示区域最大宽度
*/
public int getHorizontalMaxWidth() {
int screenWidthTwoFifths = getScreenWidth() * 2 / 5;
if (screenWidthTwoFifths > mHorizontalMaxWidth) {
return mHorizontalMaxWidth;
} else {
return screenWidthTwoFifths;
}
}
/**
* 地图显示的高,获取的是正常竖屏的高
*/
public int getMapShowHeight() {
int mapShowHeight;
if (canUseImmersive()) {
mapShowHeight = getRealScreenHeight() - getNavigationBarHeight();
} else {
mapShowHeight = getRealScreenHeight() - getNavigationBarHeight() - getStatusBarHeight();
}
return mapShowHeight;
}
/**
* 通过反射拿到屏幕实际的高度(包括状态栏和导航栏),获取的是正常竖屏的高
*/
private int getRealScreenHeight() {
int dpi = 0;
Display display = ((Activity) mContext).getWindowManager().getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, dm);
if (isScreenLandscape()) {
dpi = dm.widthPixels;
} else {
dpi = dm.heightPixels;
}
} catch (Exception e) {
e.printStackTrace();
}
if (dpi == 0) {
if (isScreenLandscape()) {
dpi = getScreenWidth();
} else {
if (ImmersionBar.hasNotchScreen((Activity) mContext)) {
dpi = getAvailableScreenHeight() + getNotchHeight() + getNavigationBarHeight();
} else {
dpi = getAvailableScreenHeight() + getStatusBarHeight() + getNavigationBarHeight();
}
}
}
return dpi;
}
/**
* 计算屏幕可用高度(此方法会受到软键盘 状态栏 底部导航栏的影响,不适合view自绘中调用,性能会有损耗)
* rect的top 是指 如果状态栏显示 则top值是状态栏高度 如果不显示则为0
* rect的bottom 是指 如果底部导航栏显示 bottom是屏幕的高度减去导航栏的高度 如果底部导航栏不显示 bottom的值是屏幕高度
*/
private int horizontalAvailableScreenHeight, verticalAvailableScreenHeight;
private int getAvailableScreenHeight() {
if (isScreenLandscape()) {
if (horizontalAvailableScreenHeight == 0) {
Rect rect = new Rect();
mWindow.getDecorView().getWindowVisibleDisplayFrame(rect);
horizontalAvailableScreenHeight = rect.right - rect.left;
}
return horizontalAvailableScreenHeight;
} else {
if (verticalAvailableScreenHeight == 0) {
Rect rect = new Rect();
mWindow.getDecorView().getWindowVisibleDisplayFrame(rect);
verticalAvailableScreenHeight = rect.bottom - rect.top;
}
return verticalAvailableScreenHeight;
}
}
/**
* 设置是否全屏
*/
// public void enableFullScreen(boolean enable) {
// if (ImmersionBar.hasNotchScreen((Activity) mContext)) {
// setStatusBarVisible(!enable);
// } else {
// if (enable) {
// ImmersionBar.with((Activity) mContext)
// .hideBar(BarHide.FLAG_HIDE_STATUS_BAR)
// .init();
// } else {
// ImmersionBar.with((Activity) mContext)
// .hideBar(BarHide.FLAG_SHOW_BAR)
// .init();
// }
// }
// }
/**
* 设置状态栏是否可见
*/
private void setStatusBarVisible(boolean show) {
int uiFlags;
if (show) {
uiFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
uiFlags |= 0x00001000;
} else {
uiFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN;
uiFlags |= 0x00001000;
}
mWindow.getDecorView().setSystemUiVisibility(uiFlags);
}
/**
* 获取导航栏虚拟按键的高度,如果虚拟按键隐藏就返回0,否则返回虚拟按键的高度
*/
public int getNavigationBarHeight() {
if (isNavigationBarShow()) {
return calculateNavigationBarHeight();
} else {
mNavigationBarHeight = 0;
return mNavigationBarHeight;
}
}
/**
* 获取忽略导航栏隐藏来获取导航栏的高,即算导航栏显示时候的高
*/
public int getNavigationBarHeightIgnoreHide() {
if (mNavigationBarHeight != 0) {
return mNavigationBarHeight;
} else {
return calculateNavigationBarHeight();
}
}
/**
* 计算虚拟按键的高度
*/
private int calculateNavigationBarHeight() {
if (mNavigationBarHeight == 0) {
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("navigation_bar_height").get(object).toString());
mNavigationBarHeight = mContext.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
}
if (mNavigationBarHeight == 0) {
Resources res = mContext.getResources();
int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
mNavigationBarHeight = res.getDimensionPixelSize(resourceId);
}
}
if (mNavigationBarHeight == 0) {
Rect rect = new Rect();
mWindow.getDecorView().getWindowVisibleDisplayFrame(rect);
Point realSize = new Point();
mWindowManager.getDefaultDisplay().getRealSize(realSize);
mNavigationBarHeight = realSize.y - rect.bottom;
}
return mNavigationBarHeight;
}
/**
* 是否保持屏幕常亮
*
* @param enable true为保持常亮
*/
public void enableKeepScreenOn(boolean enable) {
if (enable) {
mWindow.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
public void setNotchShowContent(boolean isShow) {
setNotchShowContent(mWindow, isShow);
}
/**
* 设置刘海区是否显示内容
*
* @param window 当前显示的window
* @param isShow 刘海区域是否显示内容,如果false即刘海区域变黑,不显示内容
*/
public void setNotchShowContent(Window window, boolean isShow) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (isShow) {
WindowManager.LayoutParams lp = window.getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
window.setAttributes(lp);
} else {
WindowManager.LayoutParams lp = window.getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
window.setAttributes(lp);
}
}
}
/**
* 判断虚拟导航栏是否显示
*
* @return true(显示虚拟导航栏),false(不显示或不支持虚拟导航栏)
*/
private boolean isNavigationBarShow() {
//判断小米手机是否开启了全面屏,开启了,直接返回false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Settings.Global.getInt(mContext.getContentResolver(), "force_fsg_nav_bar", 0) != 0) {
return false;
}
}
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1 || isHUAWEIPhone()) {
int screenRealHeight = getRealScreenHeight();
int statusBarHeight = getStatusBarHeight();
int screenAvailableHeight = getAvailableScreenHeight();
return screenAvailableHeight + statusBarHeight < screenRealHeight;
} else {
//其他手机根据屏幕真实高度与显示高度是否相同来判断
Display d = mWindowManager.getDefaultDisplay();
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
d.getRealMetrics(realDisplayMetrics);
}
int realHeight = realDisplayMetrics.heightPixels;
int realWidth = realDisplayMetrics.widthPixels;
DisplayMetrics displayMetrics = new DisplayMetrics();
d.getMetrics(displayMetrics);
int displayHeight = displayMetrics.heightPixels;
int displayWidth = displayMetrics.widthPixels;
return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
}
}
/**
* 判断手机是否使用了沉浸式
*
* @return true 表示使用了 false表示没使用
*/
public boolean canUseImmersive() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
/**
* 判断当前屏幕方向是否为横屏
*
* @param context 当前需要判断是否是横屏的Activity的Context
* @return true 横屏 false 竖屏
*/
public boolean isScreenLandscape(Context context) {
Configuration mConfiguration = context.getResources().getConfiguration(); //获取设置的配置信息
int ori = mConfiguration.orientation; //获取屏幕方向
return ori == Configuration.ORIENTATION_LANDSCAPE;
}
/**
* 判断当前屏幕横屏方向
*/
public int horizontalDirection() {
return ((Activity) mContext).getWindowManager().getDefaultDisplay().getRotation();
}
/**
* 判断当前屏幕方向是否为横屏,注意 此方法适用于关于MainActivity的横竖屏判断
*
* @return true 横屏 false 竖屏
*/
public boolean isScreenLandscape() {
return isScreenLandscape(mContext);
}
// public int getDimen10Px() {
// return mContext.getResources().getDimensionPixelOffset(R.dimen.nz_px_10);
// }
//
// public int getDimen20Px() {
// return mContext.getResources().getDimensionPixelOffset(R.dimen.nz_px_20);
// }
//
// //主页面底部抽拉菜单适配刘海屏
// public int getAdaptationLiuHaipingHeigh() {
// if (getLiuHaiping() == 0) {
// return mContext.getResources().getDimensionPixelSize(R.dimen.nz_px_56);
// }
// return getLiuHaiping();
// }
private Drawable mShadowDrawable;
private Rect mDrawablePadding;
public Rect getShadowBgRect(int drawableResId) {
mShadowDrawable = mContext.getResources().getDrawable(drawableResId);
mDrawablePadding = new Rect();
mShadowDrawable.getPadding(mDrawablePadding);
return mDrawablePadding;
}
public void closeSoftInput(Context context, EditText et){
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
// 对于当前焦点的View
imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
}
}
\ No newline at end of file
package com.sd.cavphmi.utils
import android.app.Activity
import android.app.ActivityManager
import android.content.*
import android.content.pm.PackageManager
import android.content.res.Resources
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import android.telephony.TelephonyManager
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.annotation.RequiresPermission
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import com.ltzw.adasdriver.utils.MobileUtils
import java.io.File
object SystemUtils {
fun getScreenWidth(): Int {
val dm = Resources.getSystem().displayMetrics
return dm.widthPixels
}
fun getScreenHeight(): Int {
val dm = Resources.getSystem().displayMetrics
return dm.heightPixels
}
/**
* 调用系统打电话
*
* @param phone
*/
fun callSystemTell(context: Context, phone: String) {
if (!phone.isNullOrEmpty()) {
try {
// var intent = Intent(Intent.ACTION_DIAL, phone.toUri())
var intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$phone"))
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
}
}
}
/**
* 获取当前应用程序的版本号
*/
fun getAppVersionCode(context: Context): Int {
var version = 0
try {
version = context.packageManager.getPackageInfo(context.packageName, 0).versionCode
} catch (e: PackageManager.NameNotFoundException) {
throw RuntimeException(context.javaClass.simpleName + "the application not found")
}
return version
}
/**
* 获取当前应用程序的版本号
*/
fun getAppVersionName(context: Context): String {
var version = "0"
try {
version = context.packageManager.getPackageInfo(context.packageName, 0).versionName.toString()
} catch (e: PackageManager.NameNotFoundException) {
throw RuntimeException("the application not found")
}
return version
}
/**
* 关闭软键盘
*/
fun closeKeyboard(view: View, context: Context) {
val imm = ContextCompat.getSystemService(context, InputMethodManager::class.java)
imm?.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
/**
* 打卡软键盘
*/
fun showKeyboard(view: View, context: Context) {
view.isFocusable = true
view.requestFocus()
val imm = ContextCompat.getSystemService(context, InputMethodManager::class.java)
imm?.showSoftInput(view, 0)
}
/**
* 适配华为安全键盘
*/
fun etHuaWeiKeybroad(et: EditText) {
if (MobileUtils.isEMUI() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
with(et) {
inputType =
android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_VARIATION_NORMAL
transformationMethod =
android.text.method.PasswordTransformationMethod.getInstance()
}
}
}
fun setStatusBarColor(activity: Activity, colorId: Int) {
val window = activity.window
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = ContextCompat.getColor(activity, colorId)
}
/**
* 通过上下文找到activity
*/
fun findActivity(context: Context): Activity? {
if (context is Activity) {
return context
}
return if (context is ContextWrapper) {
val wrapper = context as ContextWrapper
findActivity(wrapper.baseContext)
} else {
null
}
}
@RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE")
fun getPhoneIMEI(context: Context): String? {
val tm = ContextCompat.getSystemService(context, TelephonyManager::class.java)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return tm?.deviceId
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
return tm?.getImei(0)
} else {
return Settings.System.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
}
}
/**
* 复制文字到剪切板
*/
fun copyTextClip(context: Context, text: String) {
// 得到剪贴板管理器
val cmb = ContextCompat.getSystemService(context, ClipboardManager::class.java)
var clipData = ClipData.newPlainText("", text)
cmb?.setPrimaryClip(clipData)
}
fun exitApp(context: Context) {
// val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val activityManager = ContextCompat.getSystemService(context, ActivityManager::class.java)
val appTaskList = activityManager?.appTasks
if (appTaskList != null) {
for (appTask in appTaskList) {
appTask.finishAndRemoveTask()
}
}
}
fun openThridUrl(url: String, context: Context) {
var myurl = url
if (!url.startsWith("http://") && !url.startsWith("https://")) {
myurl = "http://$url"
}
try {
val uri = Uri.parse(myurl)
val intent = Intent(Intent.ACTION_VIEW, uri)
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
// LogUtil.e("--------", "没找到Activity url=$url")
}
}
//android获取一个用于打开HTML文件的intent
fun openHtmlFileIntent(urlParam: String, context: Context) {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
// val uri = Uri.fromFile(File(urlParam))
var file = File(urlParam)
var uri: Uri?
if (Build.VERSION.SDK_INT >= 24) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
uri = FileProvider.getUriForFile(context, "com.zhaolaobao.fileProvider", file)
} else {
uri = Uri.fromFile(file)
}
var type = ""
/* 取得扩展名 */
var suffix = urlParam.substringAfterLast(".").toLowerCase()
println("----url 后缀 = ${suffix}")
when (suffix) {
"pdf" -> type = "application/pdf"
"ppt", "pptx" -> type = "application/vnd.ms-powerpoint"
// "pptx" -> type =
// "application/vnd.openxmlformats-officedocument.presentationml.presentation"
"doc" -> type = "application/msword"
"docx" -> type =
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
"xls", "xlsx" -> type = "application/vnd.ms-excel"
"txt" -> type = "text/plain"
else -> type = "*/*"
}
intent.setDataAndType(uri, type)
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
ToastHelper.showShort(context, "不支持打开")
}
}
/**
*跳转到应用外部打开
*/
fun openFile(file: File, context: Context) {
var intent = Intent(Intent.ACTION_VIEW)
intent.addCategory("android.intent.category.DEFAULT")
var uri: Uri?
if (Build.VERSION.SDK_INT >= 24) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
uri = FileProvider.getUriForFile(context, "com.zhaolaobao.fileProvider", file)
} else {
uri = Uri.fromFile(file)
}
var type = ""
/* 取得扩展名 */
var end = file.name.substringAfterLast(".").toLowerCase()
when (end) {
"pdf" -> type = "application/pdf"
"ppt" -> type = "application/vnd.ms-powerpoint"
"pptx" -> type =
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
"doc" -> type = "application/msword"
"docx" -> type =
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
"xls" -> type = "application/vnd.ms-excel"
"xlsx" -> type = "application/vnd.ms-excel"
"txt" -> type = "text/plain"
else -> type = "*/*"
}
intent.setDataAndType(uri, type)
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
// context.toast("不支持打开")
}
}
/**
* 登录超时
*/
fun timeOutLoginActivity(context: Context) {
context.startActivity(Intent().apply {
// flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
action = "goLoginActivity"
putExtra("is_login_timeout", true)
})
}
/**
* 账户禁用
*/
fun accountDisLoginActivity(context: Context) {
context.startActivity(Intent().apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
action = "goLoginActivity"
putExtra("is_login_timeout", false)
})
}
/**
* 应用是否在电池白名单里
*/
fun isIgnoringBatteryOptimizations(context: Context): Boolean {
var isIgnoring = false
val powerManager = ContextCompat.getSystemService(context, PowerManager::class.java)
if (powerManager != null) {
isIgnoring = powerManager.isIgnoringBatteryOptimizations(context.packageName)
}
return isIgnoring
}
}
\ No newline at end of file
package com.sd.cavphmi.utils
import android.content.Context
import android.text.SpannableString
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.TextView
import android.widget.Toast
/**
*author:pc-20171125
*data:2019/11/8 11:18
*/
object ToastHelper {
/**
* 短时间显示Toast
*/
fun showShort(context: Context, message: String) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).run {
show()
}
}
// /**
// * 短时间显示Toast
// */
// 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()
// }
}
/*********************************************************************************************************************************
* NaviCore Corporate MIT License 0.1
* Copyright (c) 2019 GIS Core R&D Department, NavInfo Corp.
*
* Permission is hereby granted, free of charge, to any entity within the corporation(Entity) obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit Entities to whom the Software is furnished to do so, subject to the following conditions:
*
* 1. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. and
* 2. The above copyright notice, this permission notice and the acknowledgments below shall be displayed in UI or web pages
* if the Software is redistributed in binary form or as web service.
*
* Acknowledgments: "This work uses NaviZeroAndroid provided by GIS Core R&D Department, NavInfo Corp."
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* You may also get a copy of the license at http://navicore.cn/license/NC_MIT_0.1
**********************************************************************************************************************************/
package com.sd.cavphmi.utils;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.media.AudioManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.StatFs;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;
import com.minedata.minenavi.SDKInitializer;
import com.minedata.minenavi.addons.DistanceBean;
import com.minedata.minenavi.addons.TimeBean;
import com.minedata.minenavi.map.MineMap;
import com.minedata.minenavi.mapdal.DistanceStringInfo;
import com.minedata.minenavi.mapdal.NativeEnv;
import com.minedata.minenavi.util.MineNaviUtil;
import java.io.BufferedReader;
import java.io.FileReader;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class Utils {
private Context mContext;
private AudioManager mAudioManager;
private PackageManager mPackageManager;
private float mDpiFactor = 2.0f;
private boolean mIsInited = false;
private Timer mTimer;
private Context mApplicationContext;
private CountDownTimer mCountDownTimer;
private static class SingletonHolder {
public static final Utils instance = new Utils();
}
public static Utils getInstance() {
return SingletonHolder.instance;
}
public void init(Context context) {
if (mIsInited) {
return;
}
mContext = context;
mApplicationContext = context.getApplicationContext();
mTimer = new Timer();
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mPackageManager = mContext.getPackageManager();
mDpiFactor = context.getResources().getDisplayMetrics().density;
mIsInited = true;
}
/**
* 获取当前音量值
*/
public int getCurrentVolume() {
return mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
}
/**
* 获取音量最大值
*/
public int getMaxVolume() {
return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
}
/**
* 设置当前的音量
*/
public void setVolume(int volumeValue) {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volumeValue, AudioManager.FLAG_PLAY_SOUND);//设置值为Val
}
/**
* APP是否处于前台
*/
public boolean isAppOnForeground() {
ActivityManager activityManager = (ActivityManager) mContext.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
String packageName = mContext.getApplicationContext().getPackageName();
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager
.getRunningAppProcesses();
if (appProcesses == null)
return false;
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(packageName)
&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
return false;
}
/**
* 判断设备是否正在充电
*/
public boolean isCharging() {
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = mContext.registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
return isCharging;
}
/**
* 获取屏幕的高,如果横屏的话,返回的高就是屏幕的宽,如果是竖屏的话,返回的高就是屏幕的高,获取的高是从状态栏到导航栏整体的高
*
* @param activity 当前的activity
* @return 屏幕的高
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public int getWindowHeight(Activity activity) {
Point realSize = new Point();
activity.getWindowManager().getDefaultDisplay().getRealSize(realSize);
return realSize.y;
}
/**
* 获取屏幕的高,如果横屏的话,返回的高就是屏幕的宽,如果是竖屏的话,返回的高就是屏幕的高,获取的高是从状态栏到导航栏整体的高
*
* @param activity 当前的activity
* @return 屏幕的高
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public int getWindowWidth(Activity activity) {
Point realSize = new Point();
activity.getWindowManager().getDefaultDisplay().getRealSize(realSize);
return realSize.x;
}
/**
* 平移动画
*/
private TranslateAnimation mTranslateAnimation;
public void translateAnimation(View view, float fromX, float toX, float fromY, float toY, long duration, Animation.AnimationListener animationListener,
boolean isFillAfter) {
mTranslateAnimation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, fromX, Animation.RELATIVE_TO_SELF, toX,
Animation.RELATIVE_TO_SELF, fromY, Animation.RELATIVE_TO_SELF, toY);
mTranslateAnimation.setDuration(duration);
mTranslateAnimation.setFillAfter(isFillAfter);
if (animationListener != null) {
mTranslateAnimation.setAnimationListener(animationListener);
}
view.startAnimation(mTranslateAnimation);
}
/**
* 混合动画动画
*/
public void translateAnimationWithAbsolute(View view, float fromAlpha, float toAlpha, long alaphDuration, long startTime, float fromX, float toX, float fromY, float toY,
long translateDuration, long animationSetDuration, Animation.AnimationListener animationListener,
boolean isFillAfter) {
//途径点1——————————添加文字移动平移动画 333
AnimationSet animationSet = new AnimationSet(true);
AlphaAnimation animationa = new AlphaAnimation(fromAlpha, toAlpha);
animationa.setDuration(alaphDuration);
animationa.setStartTime(startTime);
animationSet.addAnimation(animationa);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, fromX, Animation.ABSOLUTE, toX, Animation.ABSOLUTE,
fromY, Animation.ABSOLUTE, toY);
translateAnimation.setDuration(translateDuration);
animationSet.addAnimation(translateAnimation);
animationSet.setDuration(animationSetDuration);
animationSet.setAnimationListener(animationListener);
animationSet.setFillAfter(isFillAfter);
view.startAnimation(animationSet);
}
public boolean isTranslateAnimationHasEnded() {
if (mTranslateAnimation == null) {
return true;
}
return mTranslateAnimation.hasEnded();
}
/**
* 地图是否是2d模式
*/
public final boolean isMap2dStyle(MineMap mineMap) {
return mineMap.getElevation() == 90;
}
/**
* 地图是否是3d模式
*/
public final boolean isMap3dStyle(MineMap mineMap) {
return mineMap.getElevation() != 90;
}
/**
* 延时操作
*
* @param runnable
* @param delayed
*/
private Handler delayedViewOperateHandler = new Handler();
public void doDelayedViewOperate(Runnable runnable, long delayed) {
delayedViewOperateHandler.postDelayed(runnable, delayed);
}
public Handler getDelayedViewOperateHandler() {
return delayedViewOperateHandler;
}
public void cleanup() {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
/**
* 秒转换成分钟,向上取整
*
* @param secondTime 秒
* @return 取整后的分钟
*/
public final int second2Minute(int secondTime) {
return (secondTime + 59) / 60;
}
/**
* 将以秒为单位的时间格式化
*
* @param secondTime 秒
* @return 得到格式化的时间
*/
public String formatTime(int secondTime) {
String sTotalTime;
int minutes = second2Minute(secondTime);
if (minutes < 60) {
sTotalTime = minutes + "分钟";
} else {
int remainMin = minutes % 60;
sTotalTime = minutes / 60 + "小时" + (remainMin == 0 ? "" : remainMin + "分");
}
return sTotalTime;
}
/**
* 格式化到千米,如果距离不小于100km或整千米,保留整数;否则保留小数点后一位,比如 110000 -> 110,8000 -> 8, 8001 -> 8, 800 -> 0.8, 99 -> 0
*
* @param distance 距离,单位:米
* @return 格式化后以千米表示的结果,不包含单位
*/
public String formatDistanceToKm(int distance) {
String distanceValue;
if (distance >= 100000 || distance % 1000 == 0) {
distanceValue = String.valueOf(distance / 1000);
} else {
distanceValue = String.format(Locale.getDefault(), "%.1f", (distance / 100) / 10.0);
}
return distanceValue;
}
public DistanceBean formatDistance(int distance, boolean isEnglishDistanceUnit) {
DistanceStringInfo distanceStringInfo = MineNaviUtil.distance2String(distance, isEnglishDistanceUnit ? MineNaviUtil.DistanceUnit.english : MineNaviUtil.DistanceUnit.normal, false);
String distanceValue = "";
String distanceUnit = "";
switch (distanceStringInfo.unit) {
case MineNaviUtil.GisUnit.m:
distanceUnit = isEnglishDistanceUnit ? "m" : "米";
break;
case MineNaviUtil.GisUnit.km:
distanceUnit = isEnglishDistanceUnit ? "km" : "公里";
break;
case MineNaviUtil.GisUnit.mi:
distanceUnit = isEnglishDistanceUnit ? "mile" : "英里";
break;
case MineNaviUtil.GisUnit.ft:
distanceUnit = isEnglishDistanceUnit ? "ft" : "英尺";
break;
}
distanceValue = distanceStringInfo.distanceString.split(distanceUnit)[0];
return new DistanceBean(distanceValue, distanceUnit);
}
public TimeBean calcTimeBean(int time) {
int totalMinute = (time + 59) / 60;
int timeHour = totalMinute / 60;
int timeMinute = totalMinute % 60;
return new TimeBean(timeHour, timeMinute);
}
/**
* 弹出/隐藏键盘
*/
public void enableInputMethod(boolean enable, EditText editText) {
InputMethodManager inputManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (enable) {
//弹出键盘
inputManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
} else {
//隐藏键盘
inputManager.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}
/**
* 弹出/隐藏键盘 : 防止焦点丢失
*/
public void enableInputMethodWithFocus(boolean enable, EditText editText) {
InputMethodManager inputManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
editText.setFocusable(enable);
editText.setFocusableInTouchMode(enable);
editText.requestFocus();
if (enable) {
//弹出键盘
editText.requestFocus();
inputManager.showSoftInput(editText, 0);
} else {
//隐藏键盘
inputManager.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}
/**
* 光标移到文字后
*/
public void setSelectionEnd(EditText editText) {
if (editText != null) {
String b = editText.getText().toString();
editText.setSelection(b.length());
}
}
/**
* 无焦点情况下隐藏键盘
*/
public void hideKeyboard(Context context) {
Activity activity = (Activity) context;
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
View v = activity.getWindow().peekDecorView();
if (null != v) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
public String getStrDistance(Point point1, Point point2) {
int distance = MineNaviUtil.distance(point1, point2);
return MineNaviUtil.distance2String(distance, MineNaviUtil.DistanceUnit.normal, false).distanceString;
}
public int dp2Px(float dp) {
return (int) (dp * mDpiFactor + 0.5f);
}
public int px2Dp(int px) {
return (int) (px / mDpiFactor + 0.5f);
}
/**
* 判断系统当前是24小时制还是 12小时制
*/
public boolean is24Hour() {
return android.text.format.DateFormat.is24HourFormat(mContext);
}
/**
* 将流量大小(B)格式化为显示文本,规则如下:<br>
* 1. 小于1K时,显示xxB,例如2B<br>
* 2. 小于1M时,显示xxKB,例如250KB<br>
* 3. 小于1G时,显示xxMB,例如250MB<br>
* 4. 不小于1G时,显示xx.xGB,例如1.0GB, 10.5GB
*
* @param size 流量大小,单位:字节
*/
public String formatTrafficDataSize(long size) {
if (size < 1024) {
return size + "B";
} else if (size < 1024 * 1024) {
return size / 1024 + "KB";
} else if (size < 10 * 1024 * 1024) {
return String.format("%.1fM", size / (1024.0 * 1024));
} else if (size < 1024L * 1024 * 1024) {
return size / (1024 * 1024) + "MB";
} else {
return String.format("%.1fGB", size / (1024.0 * 1024 * 1024));
}
}
/**
* 获取版本号名字
*/
public String getVerName() {
String verName = "";
try {
verName = mPackageManager.getPackageInfo(mApplicationContext.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return verName;
}
/**
* 获取版本号
*/
public int getVersionCode() {
int versionCode = 0;
try {
versionCode = mPackageManager.getPackageInfo(mApplicationContext.getPackageName(), 0).versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return versionCode;
}
/**
* 获取app名字
*/
public String getAppName() {
String appName = "";
try {
PackageInfo packageInfo = mPackageManager.getPackageInfo(mApplicationContext.getPackageName(), 0);
appName = packageInfo.applicationInfo.loadLabel(mPackageManager).toString();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return appName;
}
/**
* 全角转半角
*
* @return 半角字符串
*/
public String toDBC(String input) {
char c[] = input.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == '\u3000') {
c[i] = ' ';
} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
c[i] = (char) (c[i] - 65248);
}
}
return new String(c);
}
/**
* 系统Toast
*/
public void showToast(Context context, String msg) {
Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
toast.setText(msg);
toast.show();
}
public void scheduleTimerTask(TimerTask timerTask, long time) {
if (mTimer != null && timerTask != null) {
mTimer.schedule(timerTask, time);
}
}
/**
* 软件运行环境是否是手机
*
* @return
*/
public boolean isMobilePhone() {
try {
if (ScreenUtil.getInstance().isScreenLandscape() && getTotalRam(mContext) <= 2.0f
&& getSdcardAvailableSize(SDKInitializer.getAppPath()) < (25L * 1024 * 1024 * 1024)) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
/**
* 根据包名获取当前数据存储的路径后缀
*/
public String getCurrentStoragePathSuffix() {
String suffix = "";
if (isTestVersion()) {
suffix = "/mapbar/NaviZero";
} else if (isReleaseVersion()) {
suffix = "/mapbar/NaviZeroRelease";
}
return suffix;
}
public boolean isTestVersion() {
String packageName = mContext.getPackageName();
return TextUtils.equals("com.mapbar.navigation.zero", packageName);
}
public boolean isReleaseVersion() {
String packageName = mContext.getPackageName();
return TextUtils.equals("com.mapbar.navigation.zero.release", packageName);
}
public String getLoginAppName() {
return isTestVersion() ? "naviZeroBeta" : "naviZeroRelease";
}
/**
* 获取SD卡大小
*
* @param sdcardPath
* @return
*/
public long getSdcardAvailableSize(String sdcardPath) {
long size = 0;
StatFs statFs = new StatFs(sdcardPath);
int blockSize = statFs.getBlockSize();
int totalBlocks = statFs.getBlockCount();
size = (long) totalBlocks * blockSize;
return size;
}
public float getTotalRam(Context context) {
String path = "/proc/meminfo";
String firstLine = null;
float totalRam = 0;
try {
FileReader fileReader = new FileReader(path);
BufferedReader br = new BufferedReader(fileReader, 8192);
firstLine = br.readLine().split("\\s+")[1];
br.close();
} catch (Exception e) {
e.printStackTrace();
}
if (firstLine != null) {
totalRam = Float.valueOf(firstLine) / (1024 * 1024);
}
return totalRam;
}
public Bitmap createCircleBitmap(Bitmap resource) {
//获取图片的宽度
int width = resource.getWidth();
Paint paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
//创建一个与原bitmap一样宽度的正方形bitmap
Bitmap circleBitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
//以该bitmap为低创建一块画布
Canvas canvas = new Canvas(circleBitmap);
//以(width/2, width/2)为圆心,width/2为半径画一个圆
canvas.drawCircle(width / 2, width / 2, width / 2, paint);
//设置画笔为取交集模式
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//裁剪图片
canvas.drawBitmap(resource, 0, 0, paint);
return circleBitmap;
}
private SimpleDateFormat mSimpleDateFormat;
/**
* local时间转换成UTC时间
*
* @param date 时间格式 例: 2019-5-21 14:12:38
* @return 返回格式化好的时间 例: 2019-5-21 22:12:38
*/
public String formatLocalDate(String date) {
if (mSimpleDateFormat == null) {
mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
Date localDate = null;
try {
localDate = mSimpleDateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
long localTimeInMillis = localDate.getTime() + 60 * 60 * 8 * 1000;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(localTimeInMillis);
return mSimpleDateFormat.format(calendar.getTime());
}
/**
* /**
* 使用SHA1算法对字符串进行加密
*
* @param str 要签名的字符串
* @return SHA1 签名后的内容
*/
public static String sha1Digest(String str) {
if (str == null || str.length() == 0) {
return null;
}
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
/**
* 随机字符串
*
* @return 随机字符串
*/
public static String randomString() {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 10; i++) {
int number = random.nextInt(str.length());
char charAt = str.charAt(number);
sb.append(charAt);
}
return sb.toString();
}
/**
* 开启横竖屏模式
*
* @param activity 需要开启横竖屏的activity
* @param isOpen 是否打开
*/
public void enableHorizontalAndVerticalScreenMode(Activity activity, boolean isOpen) {
activity.setRequestedOrientation(isOpen ? ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
/**
* 开启横竖屏模式
*
* @param isOpen 是否打开
*/
public void enableHorizontalAndVerticalScreenMode(boolean isOpen) {
enableHorizontalAndVerticalScreenMode((Activity) mContext, isOpen);
}
/**
* 是否有网络连接
*
* @return
*/
public boolean isHaveNetwork() {
int netWorkState = NativeEnv.getNetworkStatus(mContext);
if (netWorkState == NativeEnv.NetworkStatus.unavailable) {
return false;
}
return true;
}
public boolean isNumber(String str) {
for (int i = str.length(); --i >= 0; ) {
int chr = str.charAt(i);
if (chr < 48 || chr > 57)
return false;
}
return true;
}
/***
* MD5加密
*/
public static String string2MD5(String inStr) {
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
return "";
}
byte[] md5Bytes = md5.digest(inStr.getBytes());
StringBuffer hexValue = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
int val = ((int) md5Bytes[i]) & 0xff;
if (val < 16)
hexValue.append("0");
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString().toUpperCase();
}
public static String base64(String str) {
return Base64.encodeToString(str.getBytes(), Base64.DEFAULT);
}
public static String location2String(Point pt) {
return String.format("%.5f,%.5f", pt.x / 100000.0, pt.y / 100000.0);
}
public static Point string2Location(String str) {
try {
String[] parts = str.split(",");
return new Point((int) (Float.valueOf(parts[0]) * 100000), (int) (Float.valueOf(parts[1]) * 100000));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment