Merge remote-tracking branch 'origin/dev_robotaxi-d_240227_6.3.0' into dev_robotaxi-d_240227_6.3.0

This commit is contained in:
jiaguofeng
2024-03-07 13:58:14 +08:00
92 changed files with 3338 additions and 486 deletions

View File

@@ -24,6 +24,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListener
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant; import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant;
import com.mogo.eagle.core.utilcode.util.ActivityUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils; import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.map.overlay.IMoGoOverlayManager; import com.mogo.map.overlay.IMoGoOverlayManager;
import com.mogo.map.overlay.core.Level; import com.mogo.map.overlay.core.Level;
@@ -529,7 +530,7 @@ public class BusFragment extends BaseBusTabFragment<BusFragment, BusPresenter>
} }
if ((int)mSwitchLine.getTag() == 0){//切换路线 if ((int)mSwitchLine.getTag() == 0){//切换路线
Intent intent = new Intent(getContext(), BusSwitchLineActivity.class); Intent intent = new Intent(getContext(), BusSwitchLineActivity.class);
startActivity(intent); ActivityUtils.startActivity(intent);
}else {//结束任务 }else {//结束任务
OCHCommitDialog.Builder builder = new OCHCommitDialog.Builder(); OCHCommitDialog.Builder builder = new OCHCommitDialog.Builder();
OCHCommitDialog closeLineConfirmDialog = builder OCHCommitDialog closeLineConfirmDialog = builder

View File

@@ -0,0 +1,155 @@
package com.mogo.och.common.module.manager.auditionmanager
import android.media.AudioManager
import android.media.MediaPlayer
import android.os.Handler
import android.os.HandlerThread
import android.os.Message
import android.text.TextUtils
//播放试听
object Audition: MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener, MediaPlayer.OnSeekCompleteListener {
private val TAG = "Audition"
var mediaPlayer: MediaPlayer? = null
var oldPath: String? = null
private var listener: OnAuditionListener? = null
private val handler: Handler
interface OnAuditionListener {
fun onAuditionCompletion(path: String?)
fun onSeekCompletion(currentPlay: Long)
fun onCurrentPosition(currentPlay: Long, duration: Long)
}
fun registerOnAuditionListener(listener: OnAuditionListener?) {
this.listener = listener
}
fun unregisterOnAuditionListener() {
listener = null
}
init {
val frequentThread = HandlerThread("frequent_drawer")
frequentThread.start()
handler = object : Handler(frequentThread.looper) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if (msg.what == 0) {
if (mediaPlayer != null && listener != null) {
val currentPosition = mediaPlayer!!.currentPosition
val duration = mediaPlayer!!.duration
listener!!.onCurrentPosition(currentPosition.toLong(), duration.toLong())
}
sendEmptyMessageDelayed(0, 500)
}
}
}
}
val isPlaying: Boolean
get() = mediaPlayer != null && mediaPlayer!!.isPlaying
fun play(path: String) {
if (TextUtils.equals(oldPath, path)) {
return
}
oldPath = path
if (mediaPlayer != null) {
mediaPlayer!!.release()
mediaPlayer = null
}
if (mediaPlayer == null) {
mediaPlayer = MediaPlayer()
mediaPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
mediaPlayer!!.setOnPreparedListener(this)
mediaPlayer!!.setOnCompletionListener(this)
mediaPlayer!!.setOnSeekCompleteListener(this)
}
try {
mediaPlayer!!.setDataSource(path)
} catch (e: Exception) {
e.printStackTrace()
}
mediaPlayer!!.prepareAsync()
}
fun stop() {
oldPath = null
if (mediaPlayer != null) {
mediaPlayer!!.stop()
mediaPlayer!!.reset()
}
}
fun pause() {
if (mediaPlayer != null && mediaPlayer!!.isPlaying) {
mediaPlayer!!.pause()
}
}
fun toggle(path: String):Boolean {
if (mediaPlayer != null) {
if(TextUtils.equals(oldPath, path)) {
if (mediaPlayer!!.isPlaying) {
mediaPlayer!!.pause()
return false
} else {
mediaPlayer!!.start()
return true
}
}else{
play(path)
return true
}
}else{
play(path)
return true
}
}
fun start():Boolean {
if (mediaPlayer != null) {
mediaPlayer!!.start()
return true
}
return false
}
fun playOrStop(path: String): Boolean {
return if (!TextUtils.equals(oldPath, path)) {
play(path)
true
} else {
stop()
false
}
}
fun onDestroy() {
stop()
mediaPlayer = null
}
override fun onPrepared(mp: MediaPlayer) {
mp.start()
if (listener != null) {
listener!!.onCurrentPosition(mp.currentPosition.toLong(), mp.duration.toLong())
}
handler.sendEmptyMessageDelayed(0, 500)
}
override fun onCompletion(mp: MediaPlayer) {
if (listener != null) {
listener!!.onAuditionCompletion(oldPath)
}
oldPath = null
}
override fun onSeekComplete(mp: MediaPlayer) {
if (listener != null) {
listener!!.onSeekCompletion(mp.currentPosition.toLong())
}
}
}

View File

@@ -0,0 +1,257 @@
package com.mogo.och.common.module.manager.auditionmanager
import android.media.MediaExtractor
import android.media.MediaFormat
import android.net.Uri
import android.os.Environment
import android.text.TextUtils
import com.google.gson.reflect.TypeToken
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.download.DownloadUtils
import com.mogo.eagle.core.utilcode.download.callback.IDownloadListener
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.Utils
import com.mogo.och.common.module.manager.orderlogmanager.OchChainLogManager
import com.mogo.och.common.module.manager.orderlogmanager.OchChainLogManager.EVENT_KEY_INFE_WITH_MUSIC
import com.mogo.och.common.module.utils.FileUtils
import com.mogo.och.common.module.wigets.media.MediaPlayLogger
import rx.Single
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import com.mogo.eagle.core.utilcode.util.FileUtils as FileHelper
object AuditionCacheManager {
private var dataChangeListener:DataChangeListener?=null
private val context = AbsMogoApplication.getApp()
private const val TAG = "AuditionCacheManager"
init {
createFileCacheDir()
}
// 命名规则 缓存文件夹/md5.后缀名
private fun getMusicDataByLocationConfig() {
ThreadUtils.getIoPool().execute {
val localAdDataList = mutableListOf<MusicData>()
try {
val datas: MusicDataList = GsonUtils.fromJson(
FunctionBuildConfig.musicUrlConfig, object : TypeToken<MusicDataList>() {}.type
)
localAdDataList.addAll(datas.musics)
} catch (e: Exception) {
e.printStackTrace()
}
localAdDataList.forEach {
if (isLocalCacheFileExists(it)) {
// 存在
val locationPath = getCacheFileFullPathByUrl(it)
val fileMD5 = FileHelper.getFileMD5ToString(locationPath)
if(fileMD5==it.md5){// 文件存在切md5一致
it.path = locationPath
val duration = getDuration(locationPath)
it.duration = duration
dataChangeListener?.addOneData(it)
CallerLogger.d(M_OCHCOMMON+ TAG,"文件已下载添加播放列表中")
addTag("文件已下载添加播放列表中:${it}")
}else{
// 删除缓存
FileHelper.delete(locationPath)
if(it.isCloud()) {
// 去下载
downloadFile(it)
addTag("缓存已下载但md5对应不上:${it}")
}else{
copyRaw2Music(it.songUrl,locationPath)
it.path = locationPath
val duration = getDuration(locationPath)
it.duration = duration
dataChangeListener?.addOneData(it)
}
}
}else{
if(it.isCloud()) {
// 不存在
downloadFile(it)
addTag("第一次下载:${it}")
}else{
val locationPath = getCacheFileFullPathByUrl(it)
copyRaw2Music(it.songUrl,locationPath)
it.path = locationPath
val duration = getDuration(locationPath)
it.duration = duration
dataChangeListener?.addOneData(it)
}
}
}
}
}
/**
* 创建media缓存文件夹目录优先放SD卡
*/
private fun createFileCacheDir(): Boolean {
val cacheDirPath = getFileCacheDir()
MediaPlayLogger.printInfoLog("createFileCacheDir dirPath=$cacheDirPath")
return FileHelper.createFileDir(cacheDirPath)
}
/**
* 获取本地缓存文件的文件全路径
*/
private fun getFileCacheDir(): String {
// 有些手机需要通过自定义目录
val relativePath = "mogo" + File.separator + "music" + File.separator
val cacheDir = File(Environment.getExternalStorageDirectory(), relativePath)
if (FileHelper.createOrExistsDir(cacheDir)) {
return cacheDir.absolutePath
}
return FileUtils.getCacheDirectory(context, "") + relativePath
}
/**
* 获取文件缓存的缓存path, 文件名以base64编码避免 中文命名,重复文件名的影响
*/
private fun getCacheFileFullPathByUrl(musicData: MusicData): String {
return getFileCacheDir() +File.separator+ getCacheFileName(musicData)
}
/**
* 本地是否已经存在下载完成的文件
*/
private fun isLocalCacheFileExists(musicData: MusicData): Boolean {
val localVideoCacheFilePath = getCacheFileFullPathByUrl(musicData)
return FileHelper.isFileExists(localVideoCacheFilePath)
}
/**
* 本地缓存文件的文件名md5编码避免文件名重复或者特殊字符编码问题
*/
private fun getCacheFileName(musicData: MusicData): String {
val fileSuffix = FileUtils.getExtension(musicData.songUrl)
if (TextUtils.isEmpty(fileSuffix)) {
return ""
}
return musicData.md5 + FileUtils.EXTENSION_SEPARATOR + fileSuffix
}
/**
* 下载文件
*/
private fun downloadFile(musicData: MusicData) {
val downloadUrl = musicData.songUrl
val downloadDir = getFileCacheDir()
val downloadFileName = getCacheFileName(musicData)
DownloadUtils.downLoad(context, downloadUrl, downloadDir, downloadFileName, object :IDownloadListener{
override fun onStart(url: String) {
addTag("开始下载:${musicData}")
}
override fun onProgress(url: String, downloaded: Long, total: Long) {
}
override fun onFinished(url: String, path: String) {
val fileMD5 = FileHelper.getFileMD5ToString(path)
if(fileMD5==musicData.md5){// 文件存在切md5一致
musicData.path = path
dataChangeListener?.addOneData(musicData)
addTag("下载完成切md5对应上:${musicData}")
}else{
// 下载成功但是下载的文件md5不一致不能使用
}
}
override fun onError(url: String, error: String?) {
// 下载失败
addTag("下载失败:${musicData}")
}
})
}
fun addDataChangeListener(dataChangeListener: DataChangeListener) {
this.dataChangeListener = dataChangeListener
getMusicDataByLocationConfig()
}
public interface DataChangeListener{
fun addOneData(it: MusicData)
}
private fun addTag(logInfo:String){
OchChainLogManager.writeChainLog(TAG,logInfo,eventID=EVENT_KEY_INFE_WITH_MUSIC)
}
/**
* 获取mp3音频的总时长 单位ms
*
* @param mp3FilePath MP3文件路径
* @return 时长
*/
fun getDuration(mp3FilePath: String): Long {
if (!com.mogo.eagle.core.utilcode.util.FileUtils.isFileExists(mp3FilePath)) {
return 0
}
if (!mp3FilePath.endsWith("mp3")) {
return 0
}
var mex: MediaExtractor? = null
try {
mex = MediaExtractor()
mex.setDataSource(mp3FilePath)
val mf = mex.getTrackFormat(0)
return mf.getLong(MediaFormat.KEY_DURATION) / 1000L
} catch (e: IOException) {
} finally {
mex?.release()
}
return 0
}
fun copyRaw2Music(url:String,dst:String){
val path = Uri.parse(url).path
path?.let {
val split = it.split("/")
if(split.size==3&&split.get(1)=="raw"){
try {
val fileName = split[2]
val nameAndprex = fileName.split(".")
val resourceId: Int = context.resources.getIdentifier(nameAndprex[0], "raw", context.packageName)
val openRawResource = context.resources.openRawResource(resourceId)
val outputStream: OutputStream = FileOutputStream(dst)
val buffer = ByteArray(1024)
var length: Int
while (openRawResource.read(buffer).also { length = it } > 0) {
outputStream.write(buffer, 0, length)
}
outputStream.close()
openRawResource.close()
}catch (e:IOException){
e.printStackTrace()
}
}
}
}
}

View File

@@ -0,0 +1,156 @@
package com.mogo.och.common.module.manager.auditionmanager
import com.mogo.och.common.module.manager.distancemamager.IDistanceListener
import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager
import java.util.concurrent.ConcurrentHashMap
object AuditionManager: AuditionCacheManager.DataChangeListener, Audition.OnAuditionListener {
val musicList = mutableListOf<MusicData>()
private val dataChangeListeners: ConcurrentHashMap<String, MusicDataChangeListener> = ConcurrentHashMap()
init {
AuditionCacheManager.addDataChangeListener(this)
Audition.registerOnAuditionListener(this)
}
fun addDataChangeListener(tag: String, listener: MusicDataChangeListener) {
if (dataChangeListeners.containsKey(tag)) {
return
}
dataChangeListeners[tag] = listener
}
fun removeDataChangeListener(tag: String){
dataChangeListeners.remove(tag)
}
private fun getMusicDataByState(state:PlayState):Pair<Int,MusicData>?{
musicList.forEachIndexed { index, musicData ->
if(musicData.state==state){
return Pair(index,musicData)
}
}
return null
}
fun toggle(musicData: MusicData){
val toggle = Audition.toggle(musicData.path)
val oldData = resetData()
if(toggle){// 播放
musicData.state = PlayState.Playing
dataChangeListeners.forEach {
it.value.updateState(oldData,musicData)
}
}else{// 暂停
musicData.state = PlayState.Pause
dataChangeListeners.forEach {
it.value.updateState(oldData,musicData)
}
}
}
private fun resetData():MusicData?{
var tempRusult:MusicData?=null
musicList.forEach {
if(it.state!=PlayState.None){
tempRusult = it
}
it.state = PlayState.None
}
return tempRusult
}
override fun addOneData(musicDataNew: MusicData) {
musicList.forEachIndexed { index, musicData ->
if (musicDataNew.id==musicData.id) {
musicList[index] = musicDataNew
return
}
}
musicList.add(musicDataNew)
dataChangeListeners.forEach {
it.value.addOneData(musicDataNew)
}
}
public interface MusicDataChangeListener{
fun addOneData(it: MusicData){}
fun updateState(oldData: MusicData?,musicData: MusicData)
fun updatePlayCurrent(currentPlay: Long, duration: Long, second: MusicData){}
fun onMusicCompletion(musicData: MusicData) {}
}
/**
* 音乐播放完毕
*/
override fun onAuditionCompletion(path:String?) {
val oldData = resetData()
if(oldData!=null&&oldData.path==path){
dataChangeListeners.forEach {
it.value.onMusicCompletion(oldData)
}
}else{
musicList.forEach {musicData->
if(musicData.path==path){
dataChangeListeners.forEach {
it.value.onMusicCompletion(musicData)
}
return
}
}
}
}
/**
* 拖动跳转完成
*/
override fun onSeekCompletion(currentPlay: Long) {
}
/**
* 当前进度
*/
override fun onCurrentPosition(currentPlay: Long, duration: Long) {
val musicDataWithIndex = getMusicDataByState(PlayState.Playing)
if (musicDataWithIndex!=null) {
musicDataWithIndex.second.let {musicData->
dataChangeListeners.forEach {
it.value.updatePlayCurrent(currentPlay,duration,musicData)
}
}
}else{
musicList.forEachIndexed { index, musicData ->
if(musicData.path==Audition.oldPath){
dataChangeListeners.forEach {
it.value.updatePlayCurrent(currentPlay,duration,musicData)
}
return
}
}
}
}
fun getNextMusicData(it: MusicData):MusicData {
val indexOf = musicList.indexOf(it)
if(indexOf== musicList.size-1){
return musicList.first()
}else{
return musicList[indexOf+1]
}
}
fun getPreMusicData(it: MusicData): MusicData {
val indexOf = musicList.indexOf(it)
if(indexOf== 0){
return musicList.last()
}else{
return musicList[indexOf-1]
}
}
}

View File

@@ -0,0 +1,36 @@
package com.mogo.och.common.module.manager.auditionmanager
data class MusicDataList(val musics: MutableList<MusicData>)
/**
* 音乐文件
*/
data class MusicData(
val id: String,
val md5:String,
val songName: String,
val songUrl: String,
val songUrlType: String,
val coverHeadImageUrl: String,
val coverBottomImageUrl: String,
val tag: MutableList<String>,
var duration:Long,
var path: String,
var state: PlayState = PlayState.None
){
fun isCloud():Boolean{
return songUrlType=="cloud"
}
}
/**
* None -> Playing - Pause
* | |
* None None
*/
enum class PlayState {
None,
Playing,
Pause,
}

View File

@@ -17,6 +17,7 @@ object OchChainLogManager {
const val EVENT_KEY_INFE_WITH_CHANGE = "event_key_och_common_info_and_changeinfo" const val EVENT_KEY_INFE_WITH_CHANGE = "event_key_och_common_info_and_changeinfo"
const val EVENT_KEY_INFE_WITH_TRAJECTORY = "event_key_och_trajectory_info" const val EVENT_KEY_INFE_WITH_TRAJECTORY = "event_key_och_trajectory_info"
const val EVENT_KEY_INFE_WITH_MUSIC = "event_key_och_music_info"
/** /**
* @param Info 订单详细信息 * @param Info 订单详细信息

View File

@@ -24,6 +24,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListener
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager; import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant; import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant;
import com.mogo.eagle.core.utilcode.util.ActivityUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils; import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.map.overlay.IMoGoOverlayManager; import com.mogo.map.overlay.IMoGoOverlayManager;
import com.mogo.map.overlay.core.Level; import com.mogo.map.overlay.core.Level;
@@ -519,7 +520,7 @@ public class BusFragment extends BaseBusTabFragment<BusFragment, BusPresenter>
} }
if ((int)mSwitchLine.getTag() == 0){//切换路线 if ((int)mSwitchLine.getTag() == 0){//切换路线
Intent intent = new Intent(getContext(), BusSwitchLineActivity.class); Intent intent = new Intent(getContext(), BusSwitchLineActivity.class);
startActivity(intent); ActivityUtils.startActivity(intent);
}else {//结束任务 }else {//结束任务
OCHCommitDialog.Builder builder = new OCHCommitDialog.Builder(); OCHCommitDialog.Builder builder = new OCHCommitDialog.Builder();
OCHCommitDialog closeLineConfirmDialog = builder OCHCommitDialog closeLineConfirmDialog = builder

View File

@@ -276,4 +276,8 @@ public class BusPresenter extends Presenter<BusFragment>
public void onAutopilotDockerInfo(@NonNull String dockerVersion) { public void onAutopilotDockerInfo(@NonNull String dockerVersion) {
} }
@Override
public void onSsmReceiveTimeout(boolean isTimeout) {
}
} }

View File

@@ -781,4 +781,9 @@ public class SweeperCloudTaskModel implements IMoGoSweeperFutianCloudTaskListene
public void onAutopilotDockerInfo(@NonNull String dockerVersion) { public void onAutopilotDockerInfo(@NonNull String dockerVersion) {
} }
@Override
public void onSsmReceiveTimeout(boolean isTimeout) {
}
} }

View File

@@ -462,4 +462,8 @@ public class SweeperOperatePresenter extends Presenter<SweeperOperateFragment>
public void onAutopilotDockerInfo(@NonNull String dockerVersion) { public void onAutopilotDockerInfo(@NonNull String dockerVersion) {
} }
@Override
public void onSsmReceiveTimeout(boolean isTimeout) {
}
} }

View File

@@ -1210,6 +1210,11 @@ public class TaxiModel {
private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener() { private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener() {
@Override
public void onSsmReceiveTimeout(boolean isTimeout) {
}
@Override @Override
public void onAutopilotDockerInfo(@NonNull String dockerVersion) { public void onAutopilotDockerInfo(@NonNull String dockerVersion) {
} }

View File

@@ -0,0 +1,95 @@
package com.mogo.och.taxi.passenger.ui.music
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.mogo.och.common.module.manager.auditionmanager.MusicData
import com.mogo.och.taxi.passenger.R
import com.mogo.och.taxi.passenger.ui.music.list.MusicListView
import kotlinx.android.synthetic.main.taxi_p_music.view.iv_toggle_list_playing
import kotlinx.android.synthetic.main.taxi_p_music.view.mlv_list
import kotlinx.android.synthetic.main.taxi_p_music.view.mpv_playing
class MusicView : ConstraintLayout, MusicViewModel.IMusicViewCallback, MusicListView.CheckListener {
private val TAG = "ItineraryView"
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
context,
attributeSet,
defStyleAttr
)
constructor(
context: Context,
attributeSet: AttributeSet,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attributeSet, defStyleAttr, defStyleRes)
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.taxi_p_music, this, true)
setBackgroundResource(R.drawable.taxt_p_music_bg)
setListener()
}
private fun setListener() {
iv_toggle_list_playing.setOnClickListener {
if (mpv_playing.visibility == VISIBLE && mlv_list.visibility == GONE) {
showMusicList()
} else if (mpv_playing.visibility == GONE && mlv_list.visibility == VISIBLE) {
showMusicPlaying()
}else{
showMusicPlaying()
}
}
mlv_list.setCheckItemListener(this)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(MusicViewModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
init {
try {
initView()
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun showMusicList(){
mpv_playing.visibility = GONE
mlv_list.visibility = View.VISIBLE
iv_toggle_list_playing.setImageResource(R.drawable.taxt_p_go2_playing)
}
private fun showMusicPlaying(){
mpv_playing.visibility = VISIBLE
mlv_list.visibility = GONE
iv_toggle_list_playing.setImageResource(R.drawable.taxt_p_go2_list)
}
override fun checkItem(musicData: MusicData) {
mpv_playing.setData(musicData)
// 详情页显示歌曲
showMusicPlaying()
}
}

View File

@@ -0,0 +1,31 @@
package com.mogo.och.taxi.passenger.ui.music
import androidx.lifecycle.ViewModel
import com.mogo.och.taxi.passenger.callback.IOCHTaxiPassengerOrderStatusCallback
import com.mogo.och.taxi.passenger.model.TaxiPassengerModel
class MusicViewModel: ViewModel(), IOCHTaxiPassengerOrderStatusCallback {
private val TAG = MusicViewModel::class.java.simpleName
private var viewCallback:IMusicViewCallback?=null
init {
}
fun setDistanceCallback(viewCallback:IMusicViewCallback){
this.viewCallback = viewCallback
}
override fun onCleared() {
super.onCleared()
this.viewCallback = null
}
interface IMusicViewCallback{
}
}

View File

@@ -0,0 +1,86 @@
package com.mogo.och.taxi.passenger.ui.music.list
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.och.common.module.manager.auditionmanager.MusicData
import com.mogo.och.common.module.manager.auditionmanager.PlayState
import com.mogo.och.taxi.passenger.R
/**
* Created by adityagohad on 06/06/17.
*/
class MusicListItemAdapter(
private val context: Context,
private val dataList: MutableList<MusicData>,
private val clickListener: ClickListener
) : RecyclerView.Adapter<MusicListItemAdapter.TextVH>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TextVH {
val view: View
val inflater = LayoutInflater.from(context)
view = inflater.inflate(R.layout.taxi_p_music_list_item, parent, false)
return TextVH(view)
}
override fun onBindViewHolder(holder: TextVH, position: Int) {
val musicData = dataList[holder.bindingAdapterPosition]
holder.musicName.text = musicData.songName
holder.itemView.setOnClickListener {
clickListener.clickItem(musicData)
}
if (musicData.state==PlayState.Playing||musicData.state==PlayState.Pause) {
holder.musicPlayState.visibility = View.VISIBLE
}else{
holder.musicPlayState.visibility = View.GONE
}
}
override fun getItemCount(): Int {
return dataList.size
}
fun setNewData(data: MutableList<MusicData>) {
dataList.clear()
dataList.addAll(data)
notifyDataSetChanged()
}
fun addOneData(musicData: MusicData){
dataList.add(musicData)
notifyItemInserted(dataList.size)
}
fun upDateMusicData(oldData: MusicData?,musicData: MusicData) {
dataList.forEachIndexed { index, musicDataIn ->
if (musicDataIn.id==musicData.id) {
musicDataIn.state = musicData.state
notifyItemChanged(index,0)
}
if(oldData?.id==musicDataIn.id){
notifyItemChanged(index,0)
}
}
}
inner class TextVH(itemView: View) : RecyclerView.ViewHolder(itemView) {
var musicName: TextView
var musicPlayState: ImageView
init {
musicName = itemView.findViewById(R.id.tv_song_name)
musicPlayState = itemView.findViewById(R.id.iv_music_playing)
}
}
interface ClickListener {
fun clickItem(musicData: MusicData)
}
}

View File

@@ -0,0 +1,87 @@
package com.mogo.och.taxi.passenger.ui.music.list
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.common.module.manager.auditionmanager.MusicData
import com.mogo.och.taxi.passenger.R
import kotlinx.android.synthetic.main.taxi_p_music_list.view.rv_music_list
import me.jessyan.autosize.utils.AutoSizeUtils
class MusicListView : ConstraintLayout, MusicListViewModel.IMusicListViewCaLillback,
MusicListItemAdapter.ClickListener {
private val TAG = "ItineraryView"
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
private val dataList = mutableListOf<MusicData>()
private lateinit var lineAdapter:MusicListItemAdapter
private var checkListener:CheckListener?=null
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.taxi_p_music_list, this, true)
rv_music_list.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
lineAdapter = MusicListItemAdapter(context,dataList,this)
rv_music_list.adapter = lineAdapter
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(MusicListViewModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
init {
try {
initView()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun addAllData(data: MutableList<MusicData>) {
lineAdapter.setNewData(data)
}
override fun addOneData(it: MusicData) {
lineAdapter.addOneData(it)
}
override fun updateMusicData(oldData: MusicData?,musicData: MusicData) {
lineAdapter.upDateMusicData(oldData,musicData)
CallerLogger.d(TAG,"${Thread.currentThread().name}----更新数据${oldData}-----${musicData}")
}
override fun clickItem(musicData: MusicData) {
// 通知主页面去显示详情
this.checkListener?.checkItem(musicData)
}
fun setCheckItemListener(checkListener:CheckListener) {
this.checkListener = checkListener
}
interface CheckListener {
fun checkItem(musicData: MusicData)
}
}

View File

@@ -0,0 +1,53 @@
package com.mogo.och.taxi.passenger.ui.music.list
import androidx.lifecycle.ViewModel
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.manager.auditionmanager.AuditionManager
import com.mogo.och.common.module.manager.auditionmanager.MusicData
import com.mogo.och.taxi.passenger.callback.IOCHTaxiPassengerOrderStatusCallback
class MusicListViewModel : ViewModel(), IOCHTaxiPassengerOrderStatusCallback,
AuditionManager.MusicDataChangeListener {
private val TAG = MusicListViewModel::class.java.simpleName
private var viewCallback: IMusicListViewCaLillback? = null
init {
}
fun setDistanceCallback(viewCallback: IMusicListViewCaLillback) {
this.viewCallback = viewCallback
viewCallback.addAllData(AuditionManager.musicList)
CallerLogger.d(TAG,"初始化音乐${AuditionManager.musicList.size}")
AuditionManager.addDataChangeListener(TAG,this)
}
override fun onCleared() {
super.onCleared()
this.viewCallback = null
}
interface IMusicListViewCaLillback {
fun addAllData(data:MutableList<MusicData>)
fun addOneData(it: MusicData)
fun updateMusicData(oldData: MusicData?,musicData: MusicData)
}
override fun addOneData(it: MusicData) {
CallerLogger.d(TAG,"添加音乐:${it.songName}--${it.path}")
UiThreadHandler.post({
this.viewCallback?.addOneData(it)
}, UiThreadHandler.MODE.QUEUE)
}
override fun updateState(oldData: MusicData?,musicData: MusicData) {
UiThreadHandler.post({
viewCallback?.updateMusicData(oldData, musicData)
}, UiThreadHandler.MODE.QUEUE)
}
}

View File

@@ -0,0 +1,186 @@
package com.mogo.och.taxi.passenger.ui.music.playing
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.animation.LinearInterpolator
import android.widget.SeekBar
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.TimeTransformUtils
import com.mogo.och.common.module.manager.auditionmanager.MusicData
import com.mogo.och.common.module.manager.auditionmanager.PlayState
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.taxi.passenger.R
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.iv_music_cover
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.iv_music_cover_bg
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.iv_show_next
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.iv_show_pre
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.iv_toggle
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.sb_musuc_progess
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.tv_music_name
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.tv_playing_during
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.tv_playing_time
import kotlinx.android.synthetic.main.taxi_p_music_playing.view.tv_tag
class MusicPlayingView : ConstraintLayout, MusicPlayingViewModel.IMusicPlayingViewCallback {
private val TAG = "ItineraryView"
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
private var viewModel:MusicPlayingViewModel?=null
private var animator:ObjectAnimator?=null
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.taxi_p_music_playing, this, true)
iv_toggle.setOnClickListener {
viewModel?.toggle()
}
iv_show_pre.setOnClickListener {
viewModel?.showPreMusic()
}
iv_show_next.setOnClickListener {
viewModel?.showNextMusic()
}
sb_musuc_progess.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
CallerLogger.d(TAG,"progress:${progress}----fromUser:${fromUser}")
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(MusicPlayingViewModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
viewModel?.showData()
}
}
fun setData(musicData: MusicData) {
viewModel?.setMusicData(musicData)
}
override fun setViewData(musicData: MusicData){
tv_music_name.text = musicData.songName
tv_tag.text = musicData.tag.first()
tv_playing_time.text = DateTimeUtil.second2Time(0)
tv_playing_during.text = TimeTransformUtils.stringForTime(musicData.duration.toInt())
if(musicData.state==PlayState.Playing){
iv_toggle.setImageResource(R.drawable.taxi_p_music_pause)
startAnimal()
}else{
iv_toggle.setImageResource(R.drawable.taxi_p_music_play)
endAnimal()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sb_musuc_progess.setProgress(0,true)
}else{
sb_musuc_progess.progress=0.toInt()
}
Glide.with(context)
.load(musicData.coverHeadImageUrl)
.apply(RequestOptions().placeholder(R.drawable.taxt_p_music_bg_relax_head))
.into(iv_music_cover)
Glide.with(context)
.load(musicData.coverBottomImageUrl)
.apply(RequestOptions().placeholder(R.drawable.taxt_p_music_bg_relax_bottom))
.into(iv_music_cover_bg)
}
private fun startAnimal(){
animator?.let {
if (!it.isRunning) {
animator?.start()
return
}
}
animator = ObjectAnimator.ofFloat(iv_music_cover, "rotation", 0f, 360f)
iv_music_cover.pivotX = (iv_music_cover.getWidth() / 2).toFloat()
iv_music_cover.pivotY = 166f
animator?.duration = 4000
animator?.repeatCount = -1
animator?.repeatMode = ValueAnimator.RESTART
animator?.interpolator = LinearInterpolator()
animator?.start()
}
private fun endAnimal(){
if(animator!=null){
animator?.pause()
}
}
override fun setPlayOrpause(it: MusicData) {
if(it.state==PlayState.Playing){
iv_toggle.setImageResource(R.drawable.taxi_p_music_pause)
startAnimal()
}else{
iv_toggle.setImageResource(R.drawable.taxi_p_music_play)
endAnimal()
}
}
override fun setProgress(currentPlay: Long, duration: Long) {
sb_musuc_progess.max = duration.toInt()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sb_musuc_progess.setProgress(currentPlay.toInt(),true)
}else{
sb_musuc_progess.progress=currentPlay.toInt()
}
tv_playing_time.text = TimeTransformUtils.stringForTime(currentPlay.toInt())
tv_playing_during.text = TimeTransformUtils.stringForTime(duration.toInt())
}
fun listenerPlaying(){
}
init {
try {
initView()
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@@ -0,0 +1,105 @@
package com.mogo.och.taxi.passenger.ui.music.playing
import androidx.lifecycle.ViewModel
import com.elegant.utils.UiThreadHandler
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.common.module.manager.auditionmanager.AuditionManager
import com.mogo.och.common.module.manager.auditionmanager.MusicData
import com.mogo.och.taxi.passenger.callback.IOCHTaxiPassengerOrderStatusCallback
import com.mogo.och.taxi.passenger.model.TaxiPassengerModel
class MusicPlayingViewModel : ViewModel(), AuditionManager.MusicDataChangeListener {
private val TAG = MusicPlayingViewModel::class.java.simpleName
private var viewCallback: IMusicPlayingViewCallback? = null
private var checkMusicData:MusicData?=null
init {
}
fun setDistanceCallback(viewCallback: IMusicPlayingViewCallback) {
this.viewCallback = viewCallback
AuditionManager.addDataChangeListener(TAG,this)
}
override fun onCleared() {
super.onCleared()
this.viewCallback = null
}
fun setMusicData(musicData: MusicData) {
this.checkMusicData = musicData
this.viewCallback?.setViewData(musicData)
}
fun showData() {
if(checkMusicData!=null){
}else{
}
}
fun toggle() {
checkMusicData?.let {
AuditionManager.toggle(it)
}
}
fun showPreMusic() {
checkMusicData?.let {
val nextMusicData = AuditionManager.getPreMusicData(it)
setMusicData(nextMusicData)
}
}
fun showNextMusic() {
checkMusicData?.let {
val nextMusicData = AuditionManager.getNextMusicData(it)
setMusicData(nextMusicData)
}
}
interface IMusicPlayingViewCallback {
fun setViewData(musicData: MusicData)
fun setPlayOrpause(it: MusicData)
fun setProgress(currentPlay: Long, duration: Long)
}
override fun updateState(oldData:MusicData?,musicData: MusicData) {
checkMusicData?.let {
if(it.id==musicData.id){
it.state = musicData.state
UiThreadHandler.post {
viewCallback?.setPlayOrpause(it)
}
}
}
}
override fun updatePlayCurrent(currentPlay: Long, duration: Long, musicData: MusicData){
checkMusicData?.let {
if(it.id==musicData.id){
UiThreadHandler.post {
viewCallback?.setProgress(currentPlay, duration)
}
}
}
}
override fun onMusicCompletion(musicData: MusicData) {
super.onMusicCompletion(musicData)
checkMusicData?.let {
if(it.id==musicData.id){
it.state = musicData.state
UiThreadHandler.post {
viewCallback?.setPlayOrpause(it)
}
}
}
showNextMusic()
toggle()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dp"/>
<solid android:color="@color/taxi_p_488ED0" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dp"/>
<solid android:color="@color/taxi_p_488ED0" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<scale android:scaleWidth="100%">
<shape android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="@color/taxi_p_598CFF" />
</shape>
</scale>
</item>
</layer-list>

View File

@@ -4,6 +4,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<!-- 全览地图 -->
<com.mogo.eagle.core.function.view.OverMapView <com.mogo.eagle.core.function.view.OverMapView
android:id="@+id/overMapView" android:id="@+id/overMapView"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -103,6 +104,8 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:roma_change_dis_color="true" /> app:roma_change_dis_color="true" />
<TextView <TextView
android:id="@+id/rv_location_center" android:id="@+id/rv_location_center"
android:layout_width="@dimen/dp_96" android:layout_width="@dimen/dp_96"
@@ -164,6 +167,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"/>
<com.mogo.och.taxi.passenger.ui.music.MusicView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="@dimen/dp_746"
android:layout_height="@dimen/dp_916"/>
<com.mogo.och.common.module.wigets.ZhiView <com.mogo.och.common.module.wigets.ZhiView
android:id="@+id/aciv_xiaozhi_normal" android:id="@+id/aciv_xiaozhi_normal"

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/dp_746"
android:layout_height="@dimen/dp_916"
android:background="@drawable/taxt_p_music_bg"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<com.mogo.och.taxi.passenger.ui.music.playing.MusicPlayingView
android:id="@+id/mpv_playing"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="@dimen/dp_746"
android:layout_height="@dimen/dp_916"/>
<com.mogo.och.taxi.passenger.ui.music.list.MusicListView
android:id="@+id/mlv_list"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="visible"
android:layout_width="@dimen/dp_630"
android:layout_height="@dimen/dp_800"/>
<ImageView
android:id="@+id/iv_toggle_list_playing"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/taxt_p_go2_playing"
android:layout_marginTop="@dimen/dp_87"
android:layout_marginEnd="@dimen/dp_97"
android:layout_width="@dimen/dp_78"
android:layout_height="@dimen/dp_78"/>
</merge>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/dp_630"
android:layout_height="@dimen/dp_800"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<TextView
tools:text="音乐列表"
android:textColor="@android:color/background_dark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_music_list"
android:layout_marginTop="@dimen/dp_80"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</merge>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/acc_default_txt_color"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<TextView
android:id="@+id/tv_song_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="音乐名称"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv_music_playing"
app:layout_constraintTop_toTopOf="@+id/tv_song_name"
app:layout_constraintBottom_toBottomOf="@+id/tv_song_name"
app:layout_constraintStart_toEndOf="@+id/tv_song_name"
android:src="@drawable/taxi_p_music_list_playing"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="轻柔"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/dp_746"
android:layout_height="@dimen/dp_916"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<ImageView
android:id="@+id/iv_music_cover_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/taxt_p_music_bg_relax_bottom"
android:layout_width="@dimen/dp_746"
android:layout_height="@dimen/dp_916"/>
<ImageView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="@dimen/dp_127"
android:src="@drawable/taxt_p_music_bg_middle"
android:layout_width="@dimen/dp_390"
android:layout_height="@dimen/dp_390"/>
<ImageView
android:id="@+id/iv_music_cover"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="@dimen/dp_127"
android:src="@drawable/taxt_p_music_bg_relax_head"
android:layout_width="@dimen/dp_390"
android:layout_height="@dimen/dp_390"/>
<TextView
android:id="@+id/tv_music_name"
app:layout_constraintTop_toBottomOf="@+id/iv_music_cover"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="@dimen/dp_m_17"
android:textSize="@dimen/dp_38"
tools:text="Current"
android:textColor="@color/taxi_p_303C52"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_author"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_tag"
app:layout_constraintTop_toBottomOf="@+id/tv_music_name"
android:textSize="@dimen/dp_32"
android:textColor="@color/taxi_p_576887"
tools:text="Kokia"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_tag"
app:layout_constraintStart_toEndOf="@+id/tv_author"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="@dimen/dp_16"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_author"
android:textColor="@color/taxi_p_576887"
tools:text="轻柔"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<SeekBar
android:max="100"
android:progress="50"
android:paddingStart="@dimen/dp_0"
android:paddingEnd="@dimen/dp_0"
android:thumb="@null"
android:id="@+id/sb_musuc_progess"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_author"
android:layout_marginTop="@dimen/dp_31"
android:progressDrawable="@drawable/taxt_p_music_seekbar_style"
android:layout_width="@dimen/dp_340"
android:layout_height="@dimen/dp_4"/>
<TextView
android:id="@+id/tv_playing_time"
android:textSize="@dimen/dp_28"
android:includeFontPadding="false"
app:layout_constraintTop_toTopOf="@+id/sb_musuc_progess"
app:layout_constraintBottom_toBottomOf="@+id/sb_musuc_progess"
app:layout_constraintEnd_toStartOf="@+id/sb_musuc_progess"
android:textColor="@color/taxi_p_576887"
android:layout_marginEnd="@dimen/dp_13"
tools:text="02:34"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_playing_during"
android:textSize="@dimen/dp_28"
android:includeFontPadding="false"
app:layout_constraintTop_toTopOf="@+id/sb_musuc_progess"
app:layout_constraintBottom_toBottomOf="@+id/sb_musuc_progess"
app:layout_constraintStart_toEndOf="@+id/sb_musuc_progess"
android:textColor="@color/taxi_p_576887"
android:layout_marginEnd="@dimen/dp_13"
android:layout_marginStart="@dimen/dp_13"
tools:text="05:56"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv_toggle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_109"
android:src="@drawable/taxi_p_music_play"
android:layout_width="@dimen/dp_146"
android:layout_height="@dimen/dp_146"/>
<ImageView
android:id="@+id/iv_show_pre"
app:layout_constraintTop_toTopOf="@+id/iv_toggle"
android:layout_marginTop="@dimen/dp_35"
app:layout_constraintEnd_toStartOf="@+id/iv_toggle"
android:src="@drawable/taxi_p_music_pre"
android:layout_marginEnd="@dimen/dp_61"
android:layout_width="@dimen/dp_60"
android:layout_height="@dimen/dp_60"/>
<ImageView
android:id="@+id/iv_show_next"
app:layout_constraintTop_toTopOf="@+id/iv_toggle"
android:layout_marginTop="@dimen/dp_35"
app:layout_constraintStart_toEndOf="@+id/iv_toggle"
android:src="@drawable/taxi_p_music_next"
android:layout_marginStart="@dimen/dp_61"
android:layout_width="@dimen/dp_60"
android:layout_height="@dimen/dp_60"/>
</merge>

View File

@@ -39,8 +39,11 @@
<color name="taxi_p_A0B3DA">#A0B3DA</color> <color name="taxi_p_A0B3DA">#A0B3DA</color>
<color name="taxi_p_005D6A8C">#005D6A8C</color> <color name="taxi_p_005D6A8C">#005D6A8C</color>
<color name="taxi_p_5D6A8C">#5D6A8C</color> <color name="taxi_p_5D6A8C">#5D6A8C</color>
<color name="taxi_p_576887">#576887</color>
<color name="taxi_p_995D6A8C">#995D6A8C</color> <color name="taxi_p_995D6A8C">#995D6A8C</color>
<color name="taxi_p_B37E90BF">#B37E90BF</color> <color name="taxi_p_B37E90BF">#B37E90BF</color>
<color name="taxi_p_488ED0">#488ED0</color>
<color name="taxi_p_598CFF">#598CFF</color>
<color name="taxi_p_464646">#464646</color> <color name="taxi_p_464646">#464646</color>

View File

@@ -6,6 +6,7 @@ import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.module.status.MogoStatusManager import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.map.AmapNaviToDestinationModel import com.mogo.och.common.module.map.AmapNaviToDestinationModel
import com.mogo.och.taxi.base.BaseViewModel import com.mogo.och.taxi.base.BaseViewModel
@@ -38,7 +39,7 @@ class TaxiRoutingFragmentViewModel : BaseViewModel<TaxiRoutingUiState, TaxiRouti
is TaxiRoutingUiIntent.StartChooseLineAction -> { is TaxiRoutingUiIntent.StartChooseLineAction -> {
DebugView.printInfoMsg("[选择任务] 跳转到选择任务列表") DebugView.printInfoMsg("[选择任务] 跳转到选择任务列表")
val intent = Intent(mContext, TaxiRoutingChooseLineActivity::class.java) val intent = Intent(mContext, TaxiRoutingChooseLineActivity::class.java)
mContext?.startActivity(intent) ActivityUtils.startActivity(intent)
} }
is TaxiRoutingUiIntent.ShowRoutingTask -> { is TaxiRoutingUiIntent.ShowRoutingTask -> {

View File

@@ -149,25 +149,29 @@ android {
buildConfigField 'boolean', 'secure', "true" buildConfigField 'boolean', 'secure', "true"
buildConfigField 'String', 'URLs', "\"${readFileToJson("mogo").replace("\"", "\\\"")}\"" buildConfigField 'String', 'URLs', "\"${readFileToJson("mogo").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("mogo").replace("\"", "\\\"")}\"" buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("mogo").replace("\"", "\\\"")}\""
buildConfigField 'String', 'musicUrlConfig', "\"${readMusicUrlConfigFromJsonFile("mogo").replace("\"", "\\\"")}\""
} }
yantai { yantai {
dimension "project" dimension "project"
buildConfigField 'boolean', 'secure', "false" buildConfigField 'boolean', 'secure', "false"
buildConfigField 'String', 'URLs', "\"${readFileToJson("yantai").replace("\"", "\\\"")}\"" buildConfigField 'String', 'URLs', "\"${readFileToJson("yantai").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("yantai").replace("\"", "\\\"")}\"" buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("yantai").replace("\"", "\\\"")}\""
buildConfigField 'String', 'musicUrlConfig', "\"${readMusicUrlConfigFromJsonFile("yantai").replace("\"", "\\\"")}\""
} }
dali { dali {
dimension "project" dimension "project"
buildConfigField 'boolean', 'secure', "false" buildConfigField 'boolean', 'secure', "true"
buildConfigField 'String', 'URLs', "\"${readFileToJson("dali").replace("\"", "\\\"")}\"" buildConfigField 'String', 'URLs', "\"${readFileToJson("dali").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("dali").replace("\"", "\\\"")}\"" buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("dali").replace("\"", "\\\"")}\""
buildConfigField 'String', 'musicUrlConfig', "\"${readMusicUrlConfigFromJsonFile("dali").replace("\"", "\\\"")}\""
} }
saas { saas {
dimension "project" dimension "project"
buildConfigField 'boolean', 'secure', "true" buildConfigField 'boolean', 'secure', "true"
buildConfigField 'String', 'URLs', "\"${readFileToJson("saas").replace("\"", "\\\"")}\"" buildConfigField 'String', 'URLs', "\"${readFileToJson("saas").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("saas").replace("\"", "\\\"")}\"" buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("saas").replace("\"", "\\\"")}\""
buildConfigField 'String', 'musicUrlConfig', "\"${readMusicUrlConfigFromJsonFile("saas").replace("\"", "\\\"")}\""
} }
// 配置网络环境QA、线上、演示 // 配置网络环境QA、线上、演示
qa { qa {
@@ -426,6 +430,36 @@ Object readMediaUrlConfigFromJsonFile(env){
return null return null
} }
/**
* 读取各车型宣传视频本地配置
* @param env
* @return
*/
Object readMusicUrlConfigFromJsonFile(env){
try {
// 加载config.json 文件
File file = new File("${rootDir}/app/config/MusicUrlConfig.json")
def jsonSlurper = new JsonSlurper()
// 解析json
def config = jsonSlurper.parse(file)
def flavorNames = variantVehicleName()
def jsonOutput = new JsonOutput()
def getKey = flavorNames
config.get(env).each {key, value ->
// 匹配flavor对应的 json
if(flavorNames.toLowerCase().contains(key)){
getKey = key
return true
}
}
return jsonOutput.toJson(config.get(env).get(getKey))
} catch (IOException e) {
e.printStackTrace()
}
return null
}
def variantVehicleName() { def variantVehicleName() {
if(gradle.startParameter.taskNames.size()>0) { if(gradle.startParameter.taskNames.size()>0) {
for (String taskName : gradle.startParameter.taskNames) { for (String taskName : gradle.startParameter.taskNames) {

View File

@@ -1,93 +1,123 @@
{ {
"mogo": { "mogo": {
"taxiunmannedpassengerochdfhq": { "taxipassengerochdfhq": {
"musics": [ "musics": [
{ {
"id": "1",
"md5": "C24399007B8DBAAEAA6EF448A25393CE",
"songName": "钢琴曲", "songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3", "songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local", "songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_05.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_05.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "2",
"md5": "ECA45497D915E0B933E45B5A5411B30E",
"songName": "唯美的梦", "songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718271475/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718199388/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "3",
"md5": "8FA0DE702443CD05BCA6DB1B7E6BE036",
"songName": "有趣的时光", "songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718256470/taxt_p_music_head_03.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718184532/taxt_p_music_bottom_03.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "4",
"md5": "FB1EF41BC69216AAA90323F3FBABDDDF",
"songName": "游乐场", "songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718241926/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718167794/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "5",
"md5": "B721B4FBAE2D472F875A3A539135337A",
"songName": "鼓舞我", "songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718228949/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718149545/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "6",
"md5": "836B99E70B7BC5C2283D602DF60F45F2",
"songName": "假日乐趣", "songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718228949/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718149545/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "7",
"md5": "6B0B9FEF15B0FC8F1A1EAB6793DE5C02",
"songName": "伟大梦想", "songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718228949/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718149545/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "8",
"md5": "3E8EE95E9E838709601D8BB8E2CC6B2A",
"songName": "钢琴映像", "songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718241926/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718167794/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "9",
"md5": "59D695BB96DF67DBC0F5B064D727DA4A",
"songName": "宁静的景色", "songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718271475/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718199388/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
}, },
{ {
"id": "10",
"md5": "1FBFA6AB04AA76168FDFDAFB0E189F4D",
"songName": "困倦小猫", "songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718228949/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718149545/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
@@ -97,91 +127,121 @@
"charterpassengerochm1": { "charterpassengerochm1": {
"musics": [ "musics": [
{ {
"id": "1",
"md5": "C24399007B8DBAAEAA6EF448A25393CE",
"songName": "钢琴曲", "songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3", "songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local", "songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_05.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_05.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "2",
"md5": "ECA45497D915E0B933E45B5A5411B30E",
"songName": "唯美的梦", "songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "3",
"md5": "8FA0DE702443CD05BCA6DB1B7E6BE036",
"songName": "有趣的时光", "songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_03.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_03.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "4",
"md5": "FB1EF41BC69216AAA90323F3FBABDDDF",
"songName": "游乐场", "songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "5",
"md5": "B721B4FBAE2D472F875A3A539135337A",
"songName": "鼓舞我", "songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "6",
"md5": "836B99E70B7BC5C2283D602DF60F45F2",
"songName": "假日乐趣", "songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "7",
"md5": "6B0B9FEF15B0FC8F1A1EAB6793DE5C02",
"songName": "伟大梦想", "songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "8",
"md5": "3E8EE95E9E838709601D8BB8E2CC6B2A",
"songName": "钢琴映像", "songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "9",
"md5": "59D695BB96DF67DBC0F5B064D727DA4A",
"songName": "宁静的景色", "songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
}, },
{ {
"id": "10",
"md5": "1FBFA6AB04AA76168FDFDAFB0E189F4D",
"songName": "困倦小猫", "songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
@@ -190,188 +250,124 @@
} }
}, },
"dali": { "dali": {
"taxiunmannedpassengerochdfhq": {
"musics": [
{
"songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg",
"tag": [
"放松"
]
},
{
"songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg",
"tag": [
"放松"
]
},
{
"songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg",
"tag": [
"欢快"
]
},
{
"songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg",
"tag": [
"欢快"
]
},
{
"songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg",
"tag": [
"动感"
]
},
{
"songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg",
"tag": [
"动感"
]
},
{
"songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg",
"tag": [
"浪漫"
]
},
{
"songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg",
"tag": [
"浪漫"
]
},
{
"songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png",
"tag": [
"静谧"
]
},
{
"songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png",
"tag": [
"静谧"
]
}
]
},
"charterpassengerochm1": { "charterpassengerochm1": {
"musics": [ "musics": [
{ {
"id": "1",
"md5": "C24399007B8DBAAEAA6EF448A25393CE",
"songName": "钢琴曲", "songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3", "songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local", "songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_05.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_05.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "2",
"md5": "ECA45497D915E0B933E45B5A5411B30E",
"songName": "唯美的梦", "songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "3",
"md5": "8FA0DE702443CD05BCA6DB1B7E6BE036",
"songName": "有趣的时光", "songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_03.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_03.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "4",
"md5": "FB1EF41BC69216AAA90323F3FBABDDDF",
"songName": "游乐场", "songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "5",
"md5": "B721B4FBAE2D472F875A3A539135337A",
"songName": "鼓舞我", "songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "6",
"md5": "836B99E70B7BC5C2283D602DF60F45F2",
"songName": "假日乐趣", "songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "7",
"md5": "6B0B9FEF15B0FC8F1A1EAB6793DE5C02",
"songName": "伟大梦想", "songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "8",
"md5": "3E8EE95E9E838709601D8BB8E2CC6B2A",
"songName": "钢琴映像", "songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "9",
"md5": "59D695BB96DF67DBC0F5B064D727DA4A",
"songName": "宁静的景色", "songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
}, },
{ {
"id": "10",
"md5": "1FBFA6AB04AA76168FDFDAFB0E189F4D",
"songName": "困倦小猫", "songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
@@ -380,188 +376,124 @@
} }
}, },
"yantai": { "yantai": {
"taxiunmannedpassengerochdfhq": {
"musics": [
{
"songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg",
"tag": [
"放松"
]
},
{
"songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg",
"tag": [
"放松"
]
},
{
"songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg",
"tag": [
"欢快"
]
},
{
"songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg",
"tag": [
"欢快"
]
},
{
"songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg",
"tag": [
"动感"
]
},
{
"songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg",
"tag": [
"动感"
]
},
{
"songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg",
"tag": [
"浪漫"
]
},
{
"songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg",
"tag": [
"浪漫"
]
},
{
"songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png",
"tag": [
"静谧"
]
},
{
"songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png",
"tag": [
"静谧"
]
}
]
},
"charterpassengerochm1": { "charterpassengerochm1": {
"musics": [ "musics": [
{ {
"id": "1",
"md5": "C24399007B8DBAAEAA6EF448A25393CE",
"songName": "钢琴曲", "songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3", "songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local", "songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_05.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_05.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "2",
"md5": "ECA45497D915E0B933E45B5A5411B30E",
"songName": "唯美的梦", "songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "3",
"md5": "8FA0DE702443CD05BCA6DB1B7E6BE036",
"songName": "有趣的时光", "songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_03.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_03.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "4",
"md5": "FB1EF41BC69216AAA90323F3FBABDDDF",
"songName": "游乐场", "songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "5",
"md5": "B721B4FBAE2D472F875A3A539135337A",
"songName": "鼓舞我", "songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "6",
"md5": "836B99E70B7BC5C2283D602DF60F45F2",
"songName": "假日乐趣", "songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "7",
"md5": "6B0B9FEF15B0FC8F1A1EAB6793DE5C02",
"songName": "伟大梦想", "songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "8",
"md5": "3E8EE95E9E838709601D8BB8E2CC6B2A",
"songName": "钢琴映像", "songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "9",
"md5": "59D695BB96DF67DBC0F5B064D727DA4A",
"songName": "宁静的景色", "songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
}, },
{ {
"id": "10",
"md5": "1FBFA6AB04AA76168FDFDAFB0E189F4D",
"songName": "困倦小猫", "songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
@@ -569,95 +501,125 @@
] ]
} }
}, },
"sass": { "saas": {
"taxiunmannedpassengerochdfhq": { "taxiunmannedpassengerochdfhq": {
"musics": [ "musics": [
{ {
"id": "1",
"md5": "C24399007B8DBAAEAA6EF448A25393CE",
"songName": "钢琴曲", "songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3", "songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local", "songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_05.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_05.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "2",
"md5": "ECA45497D915E0B933E45B5A5411B30E",
"songName": "唯美的梦", "songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "3",
"md5": "8FA0DE702443CD05BCA6DB1B7E6BE036",
"songName": "有趣的时光", "songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_03.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_03.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "4",
"md5": "FB1EF41BC69216AAA90323F3FBABDDDF",
"songName": "游乐场", "songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "5",
"md5": "B721B4FBAE2D472F875A3A539135337A",
"songName": "鼓舞我", "songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "6",
"md5": "836B99E70B7BC5C2283D602DF60F45F2",
"songName": "假日乐趣", "songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "7",
"md5": "6B0B9FEF15B0FC8F1A1EAB6793DE5C02",
"songName": "伟大梦想", "songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "8",
"md5": "3E8EE95E9E838709601D8BB8E2CC6B2A",
"songName": "钢琴映像", "songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "9",
"md5": "59D695BB96DF67DBC0F5B064D727DA4A",
"songName": "宁静的景色", "songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
}, },
{ {
"id": "10",
"md5": "1FBFA6AB04AA76168FDFDAFB0E189F4D",
"songName": "困倦小猫", "songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
@@ -667,91 +629,121 @@
"charterpassengerochm1": { "charterpassengerochm1": {
"musics": [ "musics": [
{ {
"id": "1",
"md5": "C24399007B8DBAAEAA6EF448A25393CE",
"songName": "钢琴曲", "songName": "钢琴曲",
"songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3", "songUrl": "android.resource://com.mogo.launcher.f/raw/piano_music.mp3",
"songUrlType": "local", "songUrlType": "local",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_05.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_05.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "2",
"md5": "ECA45497D915E0B933E45B5A5411B30E",
"songName": "唯美的梦", "songName": "唯美的梦",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523329643/beautiful_dream.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523261936/relax.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"放松" "放松"
] ]
}, },
{ {
"id": "3",
"md5": "8FA0DE702443CD05BCA6DB1B7E6BE036",
"songName": "有趣的时光", "songName": "有趣的时光",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523382842/fun_times.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_03.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_03.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "4",
"md5": "FB1EF41BC69216AAA90323F3FBABDDDF",
"songName": "游乐场", "songName": "游乐场",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523484705/playground_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523427472/lively.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"欢快" "欢快"
] ]
}, },
{ {
"id": "5",
"md5": "B721B4FBAE2D472F875A3A539135337A",
"songName": "鼓舞我", "songName": "鼓舞我",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523537118/uplift_me.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "6",
"md5": "836B99E70B7BC5C2283D602DF60F45F2",
"songName": "假日乐趣", "songName": "假日乐趣",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523604653/summer_fun.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523566881/dynamic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"动感" "动感"
] ]
}, },
{ {
"id": "7",
"md5": "6B0B9FEF15B0FC8F1A1EAB6793DE5C02",
"songName": "伟大梦想", "songName": "伟大梦想",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523656707/dreaming_big.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "8",
"md5": "3E8EE95E9E838709601D8BB8E2CC6B2A",
"songName": "钢琴映像", "songName": "钢琴映像",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523740974/piano_reflections.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523695133/romantic.jpg", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_02.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_02.png",
"tag": [ "tag": [
"浪漫" "浪漫"
] ]
}, },
{ {
"id": "9",
"md5": "59D695BB96DF67DBC0F5B064D727DA4A",
"songName": "宁静的景色", "songName": "宁静的景色",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523785714/serene_view.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_04.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_04.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]
}, },
{ {
"id": "10",
"md5": "1FBFA6AB04AA76168FDFDAFB0E189F4D",
"songName": "困倦小猫", "songName": "困倦小猫",
"songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3", "songUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523857450/sleepy_cat.mp3",
"songUrlType": "cloud", "songUrlType": "cloud",
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709523814937/quiet.png", "coverHeadImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718285436/taxt_p_music_head_01.png",
"coverBottomImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1709718213773/taxt_p_music_bottom_01.png",
"tag": [ "tag": [
"静谧" "静谧"
] ]

View File

@@ -48,6 +48,7 @@ object ConfigStartUp {
FunctionBuildConfig.unableLaunchAutopilotGear = BuildConfig.UNABLE_LAUNCH_AUTOPILOT_GEAR FunctionBuildConfig.unableLaunchAutopilotGear = BuildConfig.UNABLE_LAUNCH_AUTOPILOT_GEAR
// 各车型宣传视频本地配置json // 各车型宣传视频本地配置json
FunctionBuildConfig.mediaUrlConfig = BuildConfig.mediaUrlConfig FunctionBuildConfig.mediaUrlConfig = BuildConfig.mediaUrlConfig
FunctionBuildConfig.musicUrlConfig = BuildConfig.musicUrlConfig
//是否支持Patch升级 //是否支持Patch升级
FunctionBuildConfig.isSupportPatchUpgrade = BuildConfig.IS_SUPPORT_PATCH_UPGRADE FunctionBuildConfig.isSupportPatchUpgrade = BuildConfig.IS_SUPPORT_PATCH_UPGRADE

View File

@@ -225,13 +225,13 @@ ext {
btrace : "com.bytedance.btrace:rhea-core:2.0.0", btrace : "com.bytedance.btrace:rhea-core:2.0.0",
mofang_runtime : "com.mogo.eagle.core.mofang:runtime:2.0.11", mofang_runtime : "com.mogo.eagle.core.mofang:runtime:2.0.11",
log_runtime : "com.mogo.eagle.core.log.record:runtime:1.0.30", log_runtime : "com.mogo.eagle.core.log.record:runtime:1.0.50",
// 安全证书 // 安全证书
passport_secret : "com.zhidaoauto:sdk-java:1.0.6-SNAPSHOT", passport_secret : "com.zhidaoauto:sdk-java:1.0.6-SNAPSHOT",
// 主线程卡顿监测 // 主线程卡顿监测
block_detector : "com.mogo.eagle.core.block:runtime:20.0.5", block_detector : "com.mogo.eagle.core.block:runtime:20.0.10",
//======================== google auto-service =============== //======================== google auto-service ===============
google_auto_service : "com.google.auto.service:auto-service:1.0-rc7", google_auto_service : "com.google.auto.service:auto-service:1.0-rc7",

View File

@@ -15,10 +15,12 @@ class DataCenterProvider: IDataCenterProvider {
override val functionName: String override val functionName: String
get() = "DataCenterProvider" get() = "DataCenterProvider"
private var mContext:Context? = null
override fun init(context: Context?) { override fun init(context: Context?) {
MoGoLocationDispatcher.initListener() MoGoLocationDispatcher.initListener()
mContext = context
context?.let { mContext?.let {
CallerMsgBoxManager.queryAllMessages(it) CallerMsgBoxManager.queryAllMessages(it)
TrafficLightDispatcher.INSTANCE.initServer(it) TrafficLightDispatcher.INSTANCE.initServer(it)
SpeedLimitDispatcher.INSTANCE.initLimit(it) SpeedLimitDispatcher.INSTANCE.initLimit(it)

View File

@@ -135,13 +135,19 @@ object DataManager {
MsgBoxType.VOICE -> { MsgBoxType.VOICE -> {
CallerMsgBoxListenerManager.invokeListener(MsgCategory.VOICE_INFO, msg) CallerMsgBoxListenerManager.invokeListener(MsgCategory.VOICE_INFO, msg)
} }
MsgBoxType.OBU, MsgBoxType.NOTICE, MsgBoxType.OPERATION, MsgBoxType.AUTOPILOT -> { MsgBoxType.AUTOPILOT -> {// 不存数据库
CallerMsgBoxListenerManager.invokeListener(MsgCategory.NOTICE, msg)
}
MsgBoxType.SSMINFO -> {// 不存数据库
CallerMsgBoxListenerManager.invokeListener(MsgCategory.SYS_INFO, msg)
}
MsgBoxType.OBU, MsgBoxType.NOTICE, MsgBoxType.OPERATION -> {
synchronized(this) { synchronized(this) {
notifyList.add(msg) notifyList.add(msg)
} }
CallerMsgBoxListenerManager.invokeListener(MsgCategory.NOTICE, msg) CallerMsgBoxListenerManager.invokeListener(MsgCategory.NOTICE, msg)
} }
MsgBoxType.REPORT, MsgBoxType.SSMINFO -> { MsgBoxType.REPORT -> {
synchronized(this) { synchronized(this) {
sysInfoList.add(msg) sysInfoList.add(msg)
} }

View File

@@ -39,6 +39,7 @@ import com.tencent.matrix.trace.config.TraceConfig
import com.zhjt.mogo_core_function_devatools.apm.* import com.zhjt.mogo_core_function_devatools.apm.*
import com.mogo.eagle.core.function.api.upgrade.* import com.mogo.eagle.core.function.api.upgrade.*
import com.mogo.weak.network.SdtManager import com.mogo.weak.network.SdtManager
import com.zhjt.mogo_core_function_devatools.adas.PowerOffManager
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.binding.* import com.zhjt.mogo_core_function_devatools.binding.*
@@ -305,6 +306,63 @@ class DevaToolsProvider : IDevaToolsProvider {
BadCaseManager.showBadCaseManagerWindow(context) BadCaseManager.showBadCaseManagerWindow(context)
} }
/**
* 启动调用SSM停服命令超时检测
*/
override fun startCommandWaitCountDown() {
PowerOffManager.startCommandWaitCountDown()
}
/**
* 停止调用SSM停服命令超时检测
*/
override fun stopCommandWaitCountDown() {
PowerOffManager.stopCommandWaitCountDown()
}
/**
* 开始车辆下电等待倒计时
*/
override fun startPowerDownCountDown() {
PowerOffManager.startPowerDownCountDown()
}
/**
* 结束车辆下电等待倒计时
*/
override fun stopPowerDownCountDown() {
PowerOffManager.stopPowerDownCountDown()
}
/**
* 状态按钮变更倒计时
*/
override fun statusChangeCountDown(isSuccess: Boolean) {
PowerOffManager.statusChangeCountDown(isSuccess)
}
/**
* 结束状态按钮变更倒计时
*/
override fun stopStatusCountDown() {
PowerOffManager.stopStatusCountDown()
}
/**
* 设置停服状态
*/
override fun setPowerOffStatus(status: Int) {
PowerOffManager.setPowerOffStatus(status)
}
/**
* 获取停服状态
*/
override fun getPowerOffStatus(): Int {
return PowerOffManager.getPowerOffStatus()
}
override fun showReportListWindow(context: Context, isShow: Boolean) { override fun showReportListWindow(context: Context, isShow: Boolean) {
iPCReportManager.showReportListWindow(context, isShow) iPCReportManager.showReportListWindow(context, isShow)
} }

View File

@@ -0,0 +1,119 @@
package com.zhjt.mogo_core_function_devatools.adas
import android.os.CountDownTimer
import com.mogo.eagle.core.function.call.devatools.CallerPowerOffManager
/**
* 停止域控服务管理类
*/
object PowerOffManager {
private var commandWaitCountDownTimer: CountDownTimer ?= null
private var powerDownCountDownTimer: CountDownTimer ?= null
private var statusChangeCountDownTimer: CountDownTimer ?= null
private var powerDownNum = 60
/**
* 停止域控服务状态
* 0准备停服 1停服命令下发成功 2停服命令下发失败 3停服命令下发超时
* 4停服中 5停服成功 6停服成功不可点击
*/
private var powerOffStatus: Int = 0
/**
* 启动调用SSM停服命令超时检测
*/
fun startCommandWaitCountDown(){
commandWaitCountDownTimer = object: CountDownTimer(10000,10000){
override fun onTick(millisUntilFinished: Long) {
}
override fun onFinish() {
CallerPowerOffManager.invokeCommandTimeout()
}
}
commandWaitCountDownTimer?.start()
}
/**
* 停止调用SSM停服命令超时检测
*/
fun stopCommandWaitCountDown(){
if(commandWaitCountDownTimer != null){
commandWaitCountDownTimer?.cancel()
commandWaitCountDownTimer = null
}
}
/**
* 开始车辆下电等待倒计时
*/
fun startPowerDownCountDown(){
powerDownNum = 60
powerDownCountDownTimer = object: CountDownTimer(60000,1000){
override fun onTick(millisUntilFinished: Long) {
if(powerDownNum > 0){
CallerPowerOffManager.invokePowerDownTick(powerDownNum--)
}
}
override fun onFinish() {
powerDownNum = 0
CallerPowerOffManager.invokePowerDownFinish()
}
}
powerDownCountDownTimer?.start()
}
/**
* 结束车辆下电等待倒计时
*/
fun stopPowerDownCountDown(){
if(powerDownCountDownTimer != null){
powerDownCountDownTimer?.cancel()
powerDownCountDownTimer = null
}
}
/**
* 状态按钮变更倒计时
*/
fun statusChangeCountDown(isSuccess: Boolean){
statusChangeCountDownTimer = object: CountDownTimer(1000,1000){
override fun onTick(millisUntilFinished: Long) {
}
override fun onFinish() {
CallerPowerOffManager.invokeStatusChange(isSuccess)
}
}
statusChangeCountDownTimer?.start()
}
/**
* 结束状态按钮变更倒计时
*/
fun stopStatusCountDown(){
if(statusChangeCountDownTimer != null){
statusChangeCountDownTimer?.cancel()
statusChangeCountDownTimer = null
}
}
/**
* 设置停服状态
*/
fun setPowerOffStatus(status: Int){
powerOffStatus = status
}
/**
* 获取停服状态
*/
fun getPowerOffStatus(): Int{
return powerOffStatus
}
}

View File

@@ -123,7 +123,9 @@ class ApmEnvProviderImpl: IApmEnvProvider, CoroutineScope {
launch(Dispatchers.Main) { launch(Dispatchers.Main) {
Toast.makeText(Utils.getApp(), "发现系统环境不一致,正在重启...", Toast.LENGTH_SHORT).show() Toast.makeText(Utils.getApp(), "发现系统环境不一致,正在重启...", Toast.LENGTH_SHORT).show()
delay(50) delay(50)
Utils.getApp().startActivity(Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName)) Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName)?.also {
ActivityUtils.startActivity(it)
}
Process.killProcess(Process.myPid()) Process.killProcess(Process.myPid())
} }
} }

View File

@@ -47,30 +47,7 @@ internal class MoGoBlockProviderImpl: IMoGoBlockProvider, IBlockListener {
Log.d("BLOCK", "--- onBlockReport ---: ${info.frames.size}") Log.d("BLOCK", "--- onBlockReport ---: ${info.frames.size}")
val map = mutableMapOf<String, List<String>>() val map = mutableMapOf<String, List<String>>()
map["frames"] = info.frames.map { "$it" } map["frames"] = info.frames.map { "$it" }
BlockDetector.recorder().dump(object: OnDumpListener { dump(map)
override fun OnDumped(data: Map<Int, List<String>>) {
map["history"] = data[0] ?: emptyList()
map["pending"] = data[1] ?: emptyList()
val cpu = CallerDevaToolsManager.usage()?.dump()
if (!cpu.isNullOrEmpty()) {
val mainThreadUsage = cpu.remove("MainThreadUsage")
val processUsage = cpu.remove("ProcessUsage")
if (mainThreadUsage != null && processUsage != null) {
map["cpu"] = ArrayList<String>().also {
it.add("main-thread: ${ "%.2f".format(mainThreadUsage * 1.0f * 100 / processUsage) }% ($mainThreadUsage, $processUsage)")
for (e in cpu.entries.sortedByDescending { e -> e.value }) {
it.add("${e.key}: ${ "%.2f".format(e.value * 1.0f * 100 / processUsage) }% (${e.value}, $processUsage)")
}
}
}
}
try {
VLogUtils.w("BLOCK", GsonUtils.toJson(map))
} catch (t: Throwable) {
t.printStackTrace()
}
}
})
} }
override fun monitor(window: Window) { override fun monitor(window: Window) {
@@ -102,4 +79,33 @@ internal class MoGoBlockProviderImpl: IMoGoBlockProvider, IBlockListener {
override fun recorder(): IMessageRecorder { override fun recorder(): IMessageRecorder {
return BlockDetector.recorder() return BlockDetector.recorder()
} }
override fun dump(extra: Map<String, List<String>>?) {
val map = mutableMapOf<String, List<String>>()
extra?.takeIf { it.isNotEmpty() }?.also { map.putAll(it) }
BlockDetector.recorder().dump(object: OnDumpListener {
override fun OnDumped(data: Map<Int, List<String>>) {
map["history"] = data[0] ?: emptyList()
map["pending"] = data[1] ?: emptyList()
val cpu = CallerDevaToolsManager.usage()?.dump()
if (!cpu.isNullOrEmpty()) {
val mainThreadUsage = cpu.remove("MainThreadUsage")
val processUsage = cpu.remove("ProcessUsage")
if (mainThreadUsage != null && processUsage != null) {
map["cpu"] = ArrayList<String>().also {
it.add("main-thread: ${ "%.2f".format(mainThreadUsage * 1.0f * 100 / processUsage) }% ($mainThreadUsage, $processUsage)")
for (e in cpu.entries.sortedByDescending { e -> e.value }) {
it.add("${e.key}: ${ "%.2f".format(e.value * 1.0f * 100 / processUsage) }% (${e.value}, $processUsage)")
}
}
}
}
try {
VLogUtils.w("BLOCK", GsonUtils.toJson(map))
} catch (t: Throwable) {
t.printStackTrace()
}
}
})
}
} }

View File

@@ -0,0 +1,11 @@
package com.zhjt.mogo_core_function_devatools.block.observer
import com.mogo.core.log.record.config.checker.ILogcatChecker
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
class AnrLogcatObserver: ILogcatChecker.ILogcatCheckObserver {
override fun onGet() {
CallerDevaToolsManager.block()?.dump()
}
}

View File

@@ -7,6 +7,7 @@ import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.EnvConfig import com.mogo.eagle.core.data.EnvConfig
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.commons.storage.SharedPrefsMgr import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.util.Utils import com.mogo.eagle.core.utilcode.util.Utils
@@ -85,7 +86,9 @@ object EnvChangeManager {
} }
private fun restartApp() { private fun restartApp() {
Utils.getApp().startActivity(Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName)) Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName)?.also {
ActivityUtils.startActivity(it)
}
Process.killProcess(Process.myPid()) Process.killProcess(Process.myPid())
} }

View File

@@ -10,12 +10,12 @@ import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
import com.mogo.commons.AbsMogoApplication import com.mogo.commons.AbsMogoApplication
import com.mogo.core.log.record.* import com.mogo.core.log.record.*
import com.mogo.core.log.record.config.* import com.mogo.core.log.record.config.*
import com.mogo.core.log.record.config.crash.*
import com.mogo.core.log.record.config.state.IStateProvider import com.mogo.core.log.record.config.state.IStateProvider
import com.mogo.core.log.record.model.UploadError import com.mogo.core.log.record.model.UploadError
import com.mogo.eagle.core.data.app.AppConfigInfo import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.function.api.devatools.logcat.* import com.mogo.eagle.core.function.api.devatools.logcat.*
import com.zhidao.loglib.bean.RemoteLogPushContent import com.zhidao.loglib.bean.RemoteLogPushContent
import com.zhjt.mogo_core_function_devatools.logcat.checker.AnrLogChecker
import com.zhjt.mogo_core_function_devatools.logcat.config.LogRecordConfig import com.zhjt.mogo_core_function_devatools.logcat.config.LogRecordConfig
import com.zhjt.mogo_core_function_devatools.logcat.uploader.* import com.zhjt.mogo_core_function_devatools.logcat.uploader.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
@@ -99,17 +99,12 @@ internal class MoGoLogRecordProviderImpl: IMoGoLogRecordProvider,
itx["协议版本号"] = AppConfigInfo.protocolVersionNumber itx["协议版本号"] = AppConfigInfo.protocolVersionNumber
itx["${divider}-7"] = divider itx["${divider}-7"] = divider
itx["角色"] = AppConfigInfo.role itx["角色"] = AppConfigInfo.role
} }
} }
}) })
.crashConfig(CrashConfig.Builder() .ignoreTags(" OpenGLRenderer")
.enabled(false) .systemTags(" ActivityManager")
.crashDir(File(context.getExternalFilesDir(null), "logcat/crash")) .checker(AnrLogChecker())
.javaCrash(true)
.anr(true)
.nativeCrash(true)
.build())
.uploader(LogRecordUploader())) .uploader(LogRecordUploader()))
scope.launch { scope.launch {
try { try {

View File

@@ -0,0 +1,24 @@
package com.zhjt.mogo_core_function_devatools.logcat.checker
import com.mogo.core.log.record.config.checker.ILogcatChecker
import com.zhjt.mogo_core_function_devatools.block.observer.AnrLogcatObserver
import okio.ByteString.Companion.encodeUtf8
import okio.Source
import okio.buffer
class AnrLogChecker: ILogcatChecker {
companion object {
private const val TAG = "AnrLogChecker"
}
private val anrByteString by lazy { "ANR in com.mogo.launcher.f".encodeUtf8() }
override fun check(data: Source): Boolean {
return data.buffer().indexOf(anrByteString) >= 0
}
override fun observer(): ILogcatChecker.ILogcatCheckObserver {
return AnrLogcatObserver()
}
}

View File

@@ -43,6 +43,9 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
private val report: Int = 4 private val report: Int = 4
private val summary: Int = 5 private val summary: Int = 5
private val fm: Int = 6 private val fm: Int = 6
private val ssm: Int = 7
private val autopilot: Int = 8
private val none: Int = 9
private var changeViewListener: ChangeViewListener?=null private var changeViewListener: ChangeViewListener?=null
@@ -91,6 +94,14 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_fm,parent,false) val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_fm,parent,false)
return BubbleFmHolder(view) return BubbleFmHolder(view)
} }
ssm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_ssm,parent,false)
return BubbleSsmHolder(view)
}
autopilot -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_autopilot,parent,false)
return BubbleAutopilotHolder(view)
}
else -> { else -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_v2x,parent,false) val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_v2x,parent,false)
return BubbleV2XHolder(view) return BubbleV2XHolder(view)
@@ -262,6 +273,24 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
} }
} }
} }
//SSM连接消息
is BubbleSsmHolder ->{
data?.let {
val ssmMsg = it[position].msgBoxBean.bean as SSMMsg
holder.tvSsmTitle.text = ssmMsg.title
holder.tvSsmContent.text= ssmMsg.content
holder.tvSsmTime.text = TimeUtils.millis2String(ssmMsg.timestamp,getHourMinFormat())
}
}
//域控制器连接消息
is BubbleAutopilotHolder ->{
data?.let {
val autopilotMsg = it[position].msgBoxBean.bean as AutopilotMsg
holder.tvAutopilotTitle.text = autopilotMsg.title
holder.tvAutopilotContent.text = autopilotMsg.content
holder.tvAutopilotTime.text = TimeUtils.millis2String(autopilotMsg.timestamp,getHourMinFormat())
}
}
} }
val msgBoxBean: MsgBoxCountDownBean = data!![position] val msgBoxBean: MsgBoxCountDownBean = data!![position]
@@ -311,7 +340,11 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
summary summary
}else if(data!![position].msgBoxBean.type == MsgBoxType.FMINFO){ }else if(data!![position].msgBoxBean.type == MsgBoxType.FMINFO){
fm fm
} else{ }else if(data!![position].msgBoxBean.type == MsgBoxType.SSMINFO){
ssm
}else if(data!![position].msgBoxBean.type == MsgBoxType.AUTOPILOT){
autopilot
} else {
v2x v2x
} }
} }
@@ -378,6 +411,22 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
var tvBubbleFmTime: TextView = itemView.findViewById(R.id.tvBubbleFmTime) var tvBubbleFmTime: TextView = itemView.findViewById(R.id.tvBubbleFmTime)
} }
//SSM连接消息
class BubbleSsmHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivSsmImage: ImageView = itemView.findViewById(R.id.ivSsmImage)
var tvSsmTitle: TextView = itemView.findViewById(R.id.tvSsmTitle)
var tvSsmTime: TextView = itemView.findViewById(R.id.tvSsmTime)
var tvSsmContent: TextView = itemView.findViewById(R.id.tvSsmContent)
}
//域控制器连接状态消息
class BubbleAutopilotHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivAutopilotImage: ImageView = itemView.findViewById(R.id.ivAutopilotImage)
var tvAutopilotTitle: TextView = itemView.findViewById(R.id.tvAutopilotTitle)
var tvAutopilotTime: TextView = itemView.findViewById(R.id.tvAutopilotTime)
var tvAutopilotContent: TextView = itemView.findViewById(R.id.tvAutopilotContent)
}
fun setChangeListener(listener: ChangeViewListener){ fun setChangeListener(listener: ChangeViewListener){
changeViewListener = listener changeViewListener = listener
} }

View File

@@ -45,7 +45,12 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
private val fm: Int = 4 //FM信息 private val fm: Int = 4 //FM信息
private val report: Int = 5 //系统信息 private val report: Int = 5 //系统信息
private val record: Int = 6 //录包 private val record: Int = 6 //录包
private val summary: Int = 8 private val summary: Int = 8 //汇总消息
private val ssm: Int = 9 //SSM连接消息
private val autopilot = 20 //工控机连接消息
private val none = -1
//Error //Error
private val RESULT_AUTOPILOT_DISABLE = "RESULT_AUTOPILOT_DISABLE" private val RESULT_AUTOPILOT_DISABLE = "RESULT_AUTOPILOT_DISABLE"
@@ -116,6 +121,16 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
.inflate(R.layout.item_msg_box_summary, parent, false) .inflate(R.layout.item_msg_box_summary, parent, false)
return MsgBoxSummary(view) return MsgBoxSummary(view)
} }
ssm -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_box_ssm,parent,false)
return MsgBoxSsm(view)
}
autopilot -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_box_autopilot,parent,false)
return MsgBoxAutopilot(view)
}
else -> { else -> {
val view = LayoutInflater.from(parent.context) val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_box_v2x, parent, false) .inflate(R.layout.item_msg_box_v2x, parent, false)
@@ -648,6 +663,7 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
} }
} }
} }
//汇总消息
is MsgBoxSummary -> { is MsgBoxSummary -> {
data?.let { data?.let {
val summaryMsg = it[position].bean as V2XMsg val summaryMsg = it[position].bean as V2XMsg
@@ -656,6 +672,24 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
holder.tvSummaryContent.text = summaryMsg.content holder.tvSummaryContent.text = summaryMsg.content
} }
} }
//SSM连接状态消息
is MsgBoxSsm -> {
data?.let {
val ssmMsg = it[position].bean as SSMMsg
holder.tvSsmTitle.text = ssmMsg.title
holder.tvSsmContent.text = ssmMsg.content
holder.tvSsmTime.text = TimeUtils.millis2String(ssmMsg.timestamp,getHourMinFormat())
}
}
//域控制器连接状态消息
is MsgBoxAutopilot ->{
data?.let {
val autopilotMsg = it[position].bean as AutopilotMsg
holder.tvAutopilotTitle.text = autopilotMsg.title
holder.tvAutopilotContent.text = autopilotMsg.content
holder.tvAutopilotTime.text = TimeUtils.millis2String(autopilotMsg.timestamp,getHourMinFormat())
}
}
} }
} }
@@ -692,9 +726,14 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
record record
} else if(data!![position].type == MsgBoxType.FMINFO){ } else if(data!![position].type == MsgBoxType.FMINFO){
fm fm
} } else if(data!![position].type == MsgBoxType.SSMINFO){
else { ssm
} else if(data!![position].type == MsgBoxType.AUTOPILOT){
autopilot
} else if(data!![position].type == MsgBoxType.V2X || data!![position].type == MsgBoxType.OBU){
v2x v2x
} else {
none
} }
} }
@@ -791,5 +830,20 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
var tvSummaryTime: TextView = itemView.findViewById(R.id.tvSummaryTime) var tvSummaryTime: TextView = itemView.findViewById(R.id.tvSummaryTime)
} }
//SSM连接状态
class MsgBoxSsm(itemView: View) : RecyclerView.ViewHolder(itemView){
var ivSsmImage: ImageView = itemView.findViewById(R.id.ivSsmImage)
var tvSsmTitle: TextView = itemView.findViewById(R.id.tvSsmTitle)
var tvSsmTime: TextView = itemView.findViewById(R.id.tvSsmTime)
var tvSsmContent: TextView = itemView.findViewById(R.id.tvSsmContent)
}
//域控制器连接状态
class MsgBoxAutopilot(itemView: View) : RecyclerView.ViewHolder(itemView){
var ivAutopilotImage: ImageView = itemView.findViewById(R.id.ivAutopilotImage)
var tvAutopilotTitle: TextView = itemView.findViewById(R.id.tvAutopilotTitle)
var tvAutopilotTime: TextView = itemView.findViewById(R.id.tvAutopilotTime)
var tvAutopilotContent: TextView = itemView.findViewById(R.id.tvAutopilotContent)
}
} }

View File

@@ -2168,7 +2168,7 @@ internal class DebugSettingView @JvmOverloads constructor(
Intent(Intent.ACTION_MAIN).apply { Intent(Intent.ACTION_MAIN).apply {
addCategory(Intent.CATEGORY_HOME) addCategory(Intent.CATEGORY_HOME)
flags = Intent.FLAG_ACTIVITY_NEW_TASK flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(this) ActivityUtils.startActivity(this)
Process.killProcess(Process.myPid()) Process.killProcess(Process.myPid())
exitProcess(0) exitProcess(0)
} }
@@ -2247,8 +2247,9 @@ internal class DebugSettingView @JvmOverloads constructor(
} }
private fun restartApp() { private fun restartApp() {
Utils.getApp() Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName)?.also {
.startActivity(Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName)) ActivityUtils.startActivity(it)
}
Process.killProcess(Process.myPid()) Process.killProcess(Process.myPid())
} }

View File

@@ -24,6 +24,7 @@ import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.utils.KeyBoardUtil import com.mogo.eagle.core.function.hmi.ui.utils.KeyBoardUtil
import com.mogo.eagle.core.function.msgbox.MsgBoxConfig import com.mogo.eagle.core.function.msgbox.MsgBoxConfig
import com.mogo.eagle.core.utilcode.kotlin.onClick import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.service_biz.BizConfig import com.zhjt.service_biz.BizConfig
@@ -263,7 +264,7 @@ internal class AutoPilotAndCheckView @JvmOverloads constructor(
Intent(Intent.ACTION_MAIN).apply { Intent(Intent.ACTION_MAIN).apply {
addCategory(Intent.CATEGORY_HOME) addCategory(Intent.CATEGORY_HOME)
flags = Intent.FLAG_ACTIVITY_NEW_TASK flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(this) ActivityUtils.startActivity(this)
Process.killProcess(Process.myPid()) Process.killProcess(Process.myPid())
exitProcess(0) exitProcess(0)
} }

View File

@@ -1,37 +1,64 @@
package com.mogo.eagle.core.function.hmi.ui.widget package com.mogo.eagle.core.function.hmi.ui.widget
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.animation.LinearInterpolator
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI import androidx.core.content.ContextCompat
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoReceiveReceivedAckListener
import com.mogo.eagle.core.function.api.devatools.IPowerOffListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.function.call.autopilot.CallerReceiveReceivedAckListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.devatools.CallerPowerOffManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.notification.WarningFloat
import com.mogo.eagle.core.function.hmi.ui.tools.DockerRebootDialog import com.mogo.eagle.core.function.hmi.ui.tools.DockerRebootDialog
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.util.ThreadUtils import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo.adas.common.MessageType
import com.zhjt.mogo.adas.data.AdasConstants import com.zhjt.mogo.adas.data.AdasConstants
import com.zhjt.mogo.adas.data.bean.ReceivedAck
import kotlinx.android.synthetic.main.view_check_system.view.* import kotlinx.android.synthetic.main.view_check_system.view.*
class CheckSystemView @JvmOverloads constructor( class CheckSystemView @JvmOverloads constructor(
context: Context, context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener { ) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener,
IPowerOffListener, IMoGoReceiveReceivedAckListener {
companion object { companion object {
const val TAG = "CheckSystemView" const val TAG = "CheckSystemView"
} }
//重启系统对话框
private var dockerRebootDialog: DockerRebootDialog? = null private var dockerRebootDialog: DockerRebootDialog? = null
private var downloadStatus: String = "" //下载状态 private var connectStatus: Boolean = false //与工控机的连接状态
private var upgradeStatus: String = "" //升级状态 private var isExecutingPowerOff: Boolean = false //是否正在下发一键停服命令
private var isPowerOffCountDown: Boolean = false //一键停服是否处于1分钟倒计时
private var powerOffMsgId: Long = -1 //一键停服命令下发Id
private var progressAnimator: ObjectAnimator ?= null //一键停服命令倒计时
/**
* 停止域控服务状态
* 0准备停服 1停服命令下发中 2停服命令下发成功 3停服命令下发失败
* 4停服命令下发超时 5停服中 6停服成功 7停服成功不可点击
*/
private var powerOffStatus: Int = 0
init { init {
LayoutInflater.from(context).inflate(R.layout.view_check_system, this, true) LayoutInflater.from(context).inflate(R.layout.view_check_system, this, true)
@@ -39,85 +66,386 @@ class CheckSystemView @JvmOverloads constructor(
} }
private fun initView() { private fun initView() {
//一键停服
viewCheckShutDown.setOnClickListener { viewCheckShutDown.setOnClickListener {
//dialog powerOff()
// showSystemOperationWindow()
} }
tvCheckShutDown.setOnClickListener {
powerOff()
}
//重启系统
viewCheckReboot.setOnClickListener { viewCheckReboot.setOnClickListener {
//dialog showRebootDialog()
if (dockerRebootDialog == null) { }
dockerRebootDialog = DockerRebootDialog(context) tvCheckReboot.setOnClickListener {
dockerRebootDialog?.setClickListener(object : DockerRebootDialog.ClickListener { showRebootDialog()
override fun confirm() { }
if (CallerAutoPilotStatusListenerManager.getState() == 2) { CallerDevaToolsManager.getPowerOffStatus()?.let {
//当前处于自动驾驶状态不可进行重启Toast提示 powerOffStatus = it
ToastUtils.showShort("请先退出自动驾驶状态") }
} when(powerOffStatus){
//准备停服
// else if (AdUpgradeStateHelper.showCannotReboot( 0->{
// downloadStatus, viewCheckShutDown.setImageDrawable(
// upgradeStatus ContextCompat.getDrawable(
// ) context,
// ) { R.drawable.icon_shut_down
// //当工控机处于下载或者升级状态,需要先进行升级 )
// ToastUtils.showShort("请先完成新自动驾驶系统的下载/升级") )
// } viewCheckShutDown.isClickable = true
}
else { //停服命令下发中
//确认重启 1->{
CallerLogger.d("$M_HMI$TAG", "reboot confirm") isExecutingPowerOff = true
CallerAutoPilotControlManager.sendIpcReboot() }
ToastUtils.showLong("重启命令已发送") //停服命令下发成功
} 2->{
} viewProgressBackground.visibility = View.VISIBLE
viewProgress.visibility = View.VISIBLE
override fun cancel() { tvCountDown.visibility = View.VISIBLE
//取消重启 tvCountDownUnit.visibility = View.VISIBLE
CallerLogger.d("$M_HMI$TAG", "reboot cancel") //开始旋转动画
} if(progressAnimator == null){
progressAnimator = ObjectAnimator.ofFloat(viewProgress,"rotation", 0f, 360f)
}) }
} progressAnimator?.interpolator = LinearInterpolator()
dockerRebootDialog?.showUpgradeDialog() progressAnimator?.repeatCount = ValueAnimator.INFINITE //无限循环
progressAnimator?.duration = 6000 //设置持续时间
progressAnimator?.startDelay = 0
progressAnimator?.start()
//一键停服倒计时中
isPowerOffCountDown = true
}
//停服命令下发失败
3->{
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_fail
)
)
}
//停服命令下发超时
4->{
//将图标改为失败
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_fail
)
)
}
//停服中
5->{
isPowerOffCountDown = true
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_background
)
)
viewProgressBackground.visibility = View.VISIBLE
viewProgress.visibility = View.VISIBLE
tvCountDown.visibility = View.VISIBLE
tvCountDownUnit.visibility = View.VISIBLE
//开始旋转动画
if(progressAnimator == null){
progressAnimator = ObjectAnimator.ofFloat(viewProgress,"rotation", 0f, 360f)
}
progressAnimator?.interpolator = LinearInterpolator()
progressAnimator?.repeatCount = ValueAnimator.INFINITE //无限循环
progressAnimator?.duration = 6000 //设置持续时间
progressAnimator?.startDelay = 0
progressAnimator?.start()
}
//停服成功
6->{
//停止一键停服进度属性动画
progressAnimator?.cancel()
//隐藏一键停服进度视图
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//一键停服命令倒计时结束变为成功状态并且发送1s倒计时
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_success
)
)
isPowerOffCountDown = false
}
//停服成功不可点击
7->{
//将倒计时内容隐藏
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//停服成功,将按钮置为不可点击状态
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_complete
)
)
viewCheckShutDown.isClickable = false
isPowerOffCountDown = false
}
} }
} }
fun setAdUpgradeStatus(downloadStatus: String, upgradeStatus: String) { /**
this.downloadStatus = downloadStatus * 一键停服
this.upgradeStatus = upgradeStatus */
private fun powerOff() {
if (!connectStatus) {
ToastUtils.showShort("尚未连接工控机,无法下发一键停服命令")
return
}
if (isExecutingPowerOff) {
//一键停服命令下发执行中
ToastUtils.showShort("一键停服命令下发中,请勿重复点击")
return
}
if (isPowerOffCountDown) {
//系统停服中
ToastUtils.showShort("系统停服中,请勿重复点击")
return
}
//将是否正在下发一键停服命令标签改为true
isExecutingPowerOff = true
CallerDevaToolsManager.setPowerOffStatus(1)
//系统命令请求 关机
powerOffMsgId = CallerAutoPilotControlManager.sendIpcPowerOff()
//开始执行10秒等待倒计时
CallerDevaToolsManager.startCommandWaitCountDown()
} }
private fun showSystemOperationWindow(view: View) { /**
WarningFloat.with(context).setGravity(Gravity.CENTER).setLayout(view) * 展示系统重启确认窗
.setImmersionStatusBar(true).show() */
private fun showRebootDialog() {
if (!connectStatus) {
ToastUtils.showShort("尚未连接工控机,无法重启系统")
return
}
//dialog
if (dockerRebootDialog == null) {
dockerRebootDialog = DockerRebootDialog(context)
dockerRebootDialog?.setClickListener(object : DockerRebootDialog.ClickListener {
override fun confirm() {
if (CallerAutoPilotStatusListenerManager.getState() == 2) {
//当前处于自动驾驶状态不可进行重启Toast提示
ToastUtils.showShort("请先退出自动驾驶状态")
} else {
//确认重启
CallerLogger.d("$M_HMI$TAG", "reboot confirm")
CallerAutoPilotControlManager.sendIpcReboot()
ToastUtils.showLong("重启命令已发送")
}
}
override fun cancel() {
//取消重启
CallerLogger.d("$M_HMI$TAG", "reboot cancel")
}
})
}
dockerRebootDialog?.showUpgradeDialog()
} }
override fun onAttachedToWindow() { override fun onAttachedToWindow() {
super.onAttachedToWindow() super.onAttachedToWindow()
CallerAutoPilotStatusListenerManager.addListener(TAG, this) CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerPowerOffManager.addListener(TAG, this)
CallerReceiveReceivedAckListenerManager.addListener(TAG, this)
} }
override fun onDetachedFromWindow() { override fun onDetachedFromWindow() {
super.onDetachedFromWindow() super.onDetachedFromWindow()
CallerAutoPilotStatusListenerManager.removeListener(TAG) CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerPowerOffManager.removeListener(TAG)
CallerReceiveReceivedAckListenerManager.removeListener(TAG)
} }
override fun onAutopilotIpcConnectStatusChanged(status: AdasConstants.IpcConnectionStatus, reason: String?) { override fun onAutopilotIpcConnectStatusChanged(
status: AdasConstants.IpcConnectionStatus,
reason: String?
) {
super.onAutopilotIpcConnectStatusChanged(status, reason) super.onAutopilotIpcConnectStatusChanged(status, reason)
ThreadUtils.runOnUiThread { ThreadUtils.runOnUiThread {
setViewStatus(status == AdasConstants.IpcConnectionStatus.CONNECTED) setViewStatus(status == AdasConstants.IpcConnectionStatus.CONNECTED)
} }
} }
private fun setViewStatus(connectInfo:Boolean) { private fun setViewStatus(connectInfo: Boolean) {
if (connectInfo) { connectStatus = connectInfo
viewCheckShutDown.requestFocus() //下发一键停服命令后又和域控重新连接
if((powerOffStatus == 6 || powerOffStatus == 7) && connectStatus){
CallerDevaToolsManager.setPowerOffStatus(0)
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down
)
)
viewCheckShutDown.isClickable = true viewCheckShutDown.isClickable = true
viewCheckReboot.requestFocus() }
viewCheckReboot.isClickable = true }
} else {
/**
* 一键停服调用SSM停服命令超时
*/
override fun commandTimeout() {
//停止命令超时倒计时
CallerDevaToolsManager.stopCommandWaitCountDown()
/**
* 如果点击一键停服按钮10秒后是否正在执行命令的标签仍为true代表域控未返回执行结果
* 此时应该将按钮状态短暂置为失败之后再置为常态并将此标签置为false
*/
if (isExecutingPowerOff) {
//更改标签状态
isExecutingPowerOff = false
CallerDevaToolsManager.setPowerOffStatus(4)
//将图标改为失败
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_fail
)
)
//执行1秒倒计时命令
CallerDevaToolsManager.statusChangeCountDown(false)
}
}
/**
* 一键停服车辆下电等待倒计时
*/
override fun powerDownTick(second: Int) {
tvCountDown.text = second.toString()
CallerDevaToolsManager.setPowerOffStatus(5)
}
/**
* 一键停服车辆下电等待倒计时结束
*/
override fun powerDownFinish() {
CallerDevaToolsManager.setPowerOffStatus(6)
//停止一键停服进度属性动画
progressAnimator?.cancel()
//隐藏一键停服进度视图
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//一键停服命令倒计时结束变为成功状态并且发送1s倒计时
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_success
)
)
isPowerOffCountDown = false
//执行1秒倒计时命令
CallerDevaToolsManager.statusChangeCountDown(true)
}
/**
* 一键停服状态按钮变更通知
*/
override fun statusChange(isSuccess: Boolean) {
CallerDevaToolsManager.stopStatusCountDown()
if (isSuccess) {
//将倒计时内容隐藏
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//停服成功,将按钮置为不可点击状态
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_complete
)
)
viewCheckShutDown.isClickable = false viewCheckShutDown.isClickable = false
viewCheckReboot.isClickable = false CallerDevaToolsManager.setPowerOffStatus(7)
} else {
//停服命令下发失败,将按钮置为常态,可点击
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down
)
)
viewCheckShutDown.isClickable = true
}
}
/**
* 命令下发回执
*/
override fun onReceiveReceivedAck(receivedAck: ReceivedAck) {
ThreadUtils.runOnUiThread {
if (receivedAck.messageType == MessageType.TYPE_SEND_SYSTEM_CMD_REQ && receivedAck.msgId == powerOffMsgId) {
isExecutingPowerOff = false
//停止命令超时倒计时
CallerDevaToolsManager.stopCommandWaitCountDown()
if ( receivedAck.status == ReceivedAck.Status.NORMAL) {
//一键停服命令回执成功则正常进入停服阶段中1分钟倒计时并且TTS和消息盒子提示
CallerDevaToolsManager.setPowerOffStatus(2)
AIAssist.getInstance(context).speakTTSVoice("请等待1分钟再执行车辆下电")
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X, V2XMsg(
EventTypeEnumNew.TYPE_POWER_OFF_TIP.poiType,
EventTypeEnumNew.TYPE_POWER_OFF_TIP.content,
EventTypeEnumNew.TYPE_POWER_OFF_TIP.tts
)
)
)
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_background
)
)
viewProgressBackground.visibility = View.VISIBLE
viewProgress.visibility = View.VISIBLE
tvCountDown.visibility = View.VISIBLE
tvCountDownUnit.visibility = View.VISIBLE
//开始旋转动画
if(progressAnimator == null){
progressAnimator = ObjectAnimator.ofFloat(viewProgress,"rotation", 0f, 360f)
}
progressAnimator?.interpolator = LinearInterpolator()
progressAnimator?.repeatCount = ValueAnimator.INFINITE //无限循环
progressAnimator?.duration = 6000 //设置持续时间
progressAnimator?.startDelay = 0
progressAnimator?.start()
//开始60S倒计时
CallerDevaToolsManager.startPowerDownCountDown()
//一键停服倒计时中
isPowerOffCountDown = true
} else {
//一键停服命令回执失败,则走失败流程
CallerDevaToolsManager.setPowerOffStatus(3)
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_shut_down_fail
)
)
//执行1秒倒计时命令
CallerDevaToolsManager.statusChangeCountDown(false)
}
}
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dp_804"
android:layout_height="@dimen/dp_160"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/bg_msg_box_v2x"
android:layout_gravity="center_horizontal"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp">
<ImageView
android:id="@+id/ivAutopilotImage"
android:layout_width="110dp"
android:layout_height="110dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_margin="25dp"
android:src="@drawable/icon_warning_take_over"
/>
<TextView
android:id="@+id/tvAutopilotTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvAutopilotContent"
app:layout_constraintLeft_toRightOf="@id/ivAutopilotImage"
android:layout_marginStart="@dimen/dp_15"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/dp_32"
/>
<TextView
android:id="@+id/tvAutopilotTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvAutopilotTitle"
app:layout_constraintBottom_toBottomOf="@id/tvAutopilotTitle"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginEnd="25dp"
android:textColor="#80FFFFFF"
android:textSize="24dp"
/>
<TextView
android:id="@+id/tvAutopilotContent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvAutopilotTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/tvAutopilotTitle"
app:layout_constraintRight_toRightOf="@id/tvAutopilotTime"
android:textColor="#B3FFFFFF"
android:textSize="@dimen/dp_28"
android:maxLines="2"
android:ellipsize="end"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dp_804"
android:layout_height="@dimen/dp_160"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/bg_msg_box_v2x"
android:layout_gravity="center_horizontal"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp">
<ImageView
android:id="@+id/ivSsmImage"
android:layout_width="110dp"
android:layout_height="110dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_margin="25dp"
android:src="@drawable/icon_warning_take_over"
/>
<TextView
android:id="@+id/tvSsmTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvSsmContent"
app:layout_constraintLeft_toRightOf="@id/ivSsmImage"
android:layout_marginStart="@dimen/dp_15"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/dp_32"
/>
<TextView
android:id="@+id/tvSsmTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvSsmTitle"
app:layout_constraintBottom_toBottomOf="@id/tvSsmTitle"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginEnd="25dp"
android:textColor="#80FFFFFF"
android:textSize="24dp"
/>
<TextView
android:id="@+id/tvSsmContent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvSsmTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/tvSsmTitle"
app:layout_constraintRight_toRightOf="@id/tvSsmTime"
android:textColor="#B3FFFFFF"
android:textSize="@dimen/dp_28"
android:maxLines="2"
android:ellipsize="end"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/clAutopilotLayout"
android:layout_width="@dimen/dp_804"
android:layout_height="@dimen/dp_160"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/bg_msg_box_v2x"
android:layout_gravity="center_horizontal"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"
>
<ImageView
android:id="@+id/ivAutopilotImage"
android:layout_width="110dp"
android:layout_height="110dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_margin="25dp"
android:src="@drawable/icon_warning_take_over"
/>
<TextView
android:id="@+id/tvAutopilotTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvAutopilotContent"
app:layout_constraintLeft_toRightOf="@id/ivAutopilotImage"
android:layout_marginStart="@dimen/dp_15"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/dp_32"
/>
<TextView
android:id="@+id/tvAutopilotTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvAutopilotTitle"
app:layout_constraintBottom_toBottomOf="@id/tvAutopilotTitle"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginEnd="25dp"
android:textColor="#80FFFFFF"
android:textSize="24dp"
/>
<TextView
android:id="@+id/tvAutopilotContent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvAutopilotTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/tvAutopilotTitle"
app:layout_constraintRight_toRightOf="@id/tvAutopilotTime"
android:textColor="#B3FFFFFF"
android:textSize="@dimen/dp_28"
android:maxLines="2"
android:ellipsize="end"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/clSsmLayout"
android:layout_width="@dimen/dp_804"
android:layout_height="@dimen/dp_160"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/bg_msg_box_v2x"
android:layout_gravity="center_horizontal"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"
>
<ImageView
android:id="@+id/ivSsmImage"
android:layout_width="110dp"
android:layout_height="110dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_margin="25dp"
android:src="@drawable/icon_warning_take_over"
/>
<TextView
android:id="@+id/tvSsmTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvSsmContent"
app:layout_constraintLeft_toRightOf="@id/ivSsmImage"
android:layout_marginStart="@dimen/dp_15"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/dp_32"
/>
<TextView
android:id="@+id/tvSsmTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvSsmTitle"
app:layout_constraintBottom_toBottomOf="@id/tvSsmTitle"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginEnd="25dp"
android:textColor="#80FFFFFF"
android:textSize="24dp"
/>
<TextView
android:id="@+id/tvSsmContent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvSsmTitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/tvSsmTitle"
app:layout_constraintRight_toRightOf="@id/tvSsmTime"
android:textColor="#B3FFFFFF"
android:textSize="@dimen/dp_28"
android:maxLines="2"
android:ellipsize="end"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -7,50 +7,96 @@
<ImageView <ImageView
android:id="@+id/viewCheckShutDown" android:id="@+id/viewCheckShutDown"
android:layout_width="150dp" android:layout_width="@dimen/dp_150"
android:layout_height="150dp" android:layout_height="@dimen/dp_150"
android:layout_marginStart="113dp" android:layout_marginStart="@dimen/dp_142"
android:clickable="true" android:src="@drawable/icon_shut_down"
android:src="@drawable/check_shut_down"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"/> android:contentDescription="@string/check_system_shut_down" />
<ImageView
android:id="@+id/viewProgressBackground"
android:layout_width="@dimen/dp_84"
android:layout_height="@dimen/dp_84"
app:layout_constraintTop_toTopOf="@id/viewCheckShutDown"
app:layout_constraintBottom_toBottomOf="@id/viewCheckShutDown"
app:layout_constraintStart_toStartOf="@id/viewCheckShutDown"
app:layout_constraintEnd_toEndOf="@id/viewCheckShutDown"
android:src="@drawable/icon_shut_down_progress_background"
android:visibility="gone"
/>
<ImageView
android:id="@+id/viewProgress"
android:layout_width="@dimen/dp_84"
android:layout_height="@dimen/dp_84"
app:layout_constraintTop_toTopOf="@id/viewCheckShutDown"
app:layout_constraintBottom_toBottomOf="@id/viewCheckShutDown"
app:layout_constraintStart_toStartOf="@id/viewCheckShutDown"
app:layout_constraintEnd_toEndOf="@id/viewCheckShutDown"
android:src="@drawable/icon_shut_down_progress"
android:visibility="gone"
/>
<TextView
android:id="@+id/tvCountDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/viewCheckShutDown"
app:layout_constraintBottom_toBottomOf="@id/viewCheckShutDown"
app:layout_constraintStart_toStartOf="@id/viewCheckShutDown"
app:layout_constraintEnd_toEndOf="@id/viewCheckShutDown"
android:textColor="@color/white"
android:textSize="@dimen/sp_28"
android:visibility="gone"
/>
<TextView
android:id="@+id/tvCountDownUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@id/tvCountDown"
app:layout_constraintStart_toEndOf="@id/tvCountDown"
android:textSize="@dimen/sp_20"
android:textColor="#B2FFFFFF"
android:text="s"
android:visibility="gone"
/>
<TextView <TextView
android:id="@+id/tvCheckShutDown" android:id="@+id/tvCheckShutDown"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="156dp" android:layout_marginTop="@dimen/dp_23"
android:layout_marginTop="23dp"
android:gravity="center" android:gravity="center"
android:text="@string/check_system_shut_down" android:text="@string/check_system_shut_down"
android:textColor="@color/color_FFA7B6F0" android:textColor="@color/color_FFA7B6F0"
android:textSize="32dp" android:textSize="@dimen/sp_32"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/viewCheckShutDown" app:layout_constraintTop_toBottomOf="@id/viewCheckShutDown"
android:visibility="gone"/> app:layout_constraintLeft_toLeftOf="@id/viewCheckShutDown"
app:layout_constraintRight_toRightOf="@id/viewCheckShutDown"
/>
<ImageView <ImageView
android:id="@+id/viewCheckReboot" android:id="@+id/viewCheckReboot"
android:layout_width="150dp" android:layout_width="@dimen/dp_150"
android:layout_height="150dp" android:layout_height="@dimen/dp_150"
android:layout_marginStart="@dimen/dp_142" android:layout_marginStart="@dimen/dp_142"
android:clickable="true"
android:src="@drawable/check_reboot" android:src="@drawable/check_reboot"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintLeft_toRightOf="@id/viewCheckShutDown"
app:layout_constraintTop_toTopOf="parent" /> android:contentDescription="@string/check_system_reboot" />
<TextView <TextView
android:id="@+id/tvCheckReboot" android:id="@+id/tvCheckReboot"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="23dp" android:layout_marginTop="@dimen/dp_23"
android:gravity="center" android:gravity="center"
android:text="@string/check_system_reboot" android:text="@string/check_system_reboot"
android:textColor="@color/color_FFA7B6F0" android:textColor="@color/color_FFA7B6F0"
android:textSize="32dp" android:textSize="@dimen/sp_32"
app:layout_constraintLeft_toLeftOf="@id/viewCheckReboot" app:layout_constraintLeft_toLeftOf="@id/viewCheckReboot"
app:layout_constraintRight_toRightOf="@id/viewCheckReboot" app:layout_constraintRight_toRightOf="@id/viewCheckReboot"
app:layout_constraintTop_toBottomOf="@id/viewCheckReboot" /> app:layout_constraintTop_toBottomOf="@id/viewCheckReboot" />

View File

@@ -28,7 +28,7 @@
<string name="check_vehicle_speed_setting">车速设置</string> <string name="check_vehicle_speed_setting">车速设置</string>
<string name="bus_operation_title">账户信息</string> <string name="bus_operation_title">账户信息</string>
<string name="check_system_operation">系统运行</string> <string name="check_system_operation">系统运行</string>
<string name="check_system_shut_down">关机</string> <string name="check_system_shut_down">一键停服</string>
<string name="check_system_reboot">重启系统</string> <string name="check_system_reboot">重启系统</string>
<string name="check_system_reboot_title">重启提示</string> <string name="check_system_reboot_title">重启提示</string>
<string name="check_system_reboot_content">是否重启自动驾驶系统?</string> <string name="check_system_reboot_content">是否重启自动驾驶系统?</string>

View File

@@ -21,8 +21,6 @@ import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.commons.utils.MogoAnalyticUtils import com.mogo.commons.utils.MogoAnalyticUtils
import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_INIT import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_INIT
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_PASSPORT_AUTH_FAILED
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_PASSPORT_AUTH_OK
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_PASSPORT_TOKEN import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_PASSPORT_TOKEN
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_RECONNECT import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_CLOUD_RECONNECT
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_HTTP_DNS_ERROR_REASON import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_HTTP_DNS_ERROR_REASON
@@ -30,12 +28,12 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_SOURCE_
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_STATUS import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_STATUS
import com.mogo.eagle.core.data.map.MogoLocation import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.api.cloud.IMoGoCloudListener
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.call.cloud.CallerCloudCertManager
import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.startup.stageone.secret.IPassportSecret
import com.mogo.eagle.core.function.startup.stageone.secret.PassPortSecret
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAIN import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAIN
import com.mogo.eagle.core.utilcode.util.AppUtils import com.mogo.eagle.core.utilcode.util.AppUtils
@@ -47,7 +45,7 @@ import com.rousetime.android_startup.AndroidStartup
import com.zhjt.service.chain.ChainLog import com.zhjt.service.chain.ChainLog
import kotlin.properties.Delegates import kotlin.properties.Delegates
class HttpDnsStartUp : AndroidStartup<Boolean>() { class HttpDnsStartUp : AndroidStartup<Boolean>(), IMoGoCloudListener {
companion object { companion object {
private const val TAG = "HttpDnsStartUp" private const val TAG = "HttpDnsStartUp"
@@ -108,6 +106,8 @@ class HttpDnsStartUp : AndroidStartup<Boolean>() {
} }
private fun preparePassportEnvironment() { private fun preparePassportEnvironment() {
//监听cert文件下载
CallerCloudListenerManager.addListener(TAG,this)
// 设置网络环境HTTP_DNS_ENV_QA、HTTP_DNS_ENV_RELEASE、HTTP_DNS_ENV_DEV // 设置网络环境HTTP_DNS_ENV_QA、HTTP_DNS_ENV_RELEASE、HTTP_DNS_ENV_DEV
when (DebugConfig.getNetMode()) { when (DebugConfig.getNetMode()) {
DebugConfig.NET_MODE_DEV -> clientConfig.netMode = DebugConfig.NET_MODE_DEV -> clientConfig.netMode =
@@ -229,8 +229,8 @@ class HttpDnsStartUp : AndroidStartup<Boolean>() {
if (!gotToken) { if (!gotToken) {
CallerLogger.d("$M_MAIN$TAG", "onTokenGot token : $token , sn :$sn") CallerLogger.d("$M_MAIN$TAG", "onTokenGot token : $token , sn :$sn")
CallerCloudListenerManager.invokeCloudTokenGot(token, sn) CallerCloudListenerManager.invokeCloudTokenGot(token, sn)
// 异步初始化NetConfig // 开启cert download && 异步初始化NetConfig
asyncInit(sn) asyncInit()
startSocketService(sn) startSocketService(sn)
// 开启每5s/次定位上报 // 开启每5s/次定位上报
uploadLocPerFiveSecond() uploadLocPerFiveSecond()
@@ -248,7 +248,11 @@ class HttpDnsStartUp : AndroidStartup<Boolean>() {
/** /**
* 异步初始化 * 异步初始化
*/ */
private fun asyncInit(sn: String) { private fun asyncInit() {
// cert file下载
CallerCloudCertManager.certFileDownLoad{
logError(getPrReason("PassPortSecret-onFailed , $it"))
}
ThreadPoolService.execute { ThreadPoolService.execute {
// 初始化网络配置 // 初始化网络配置
NetConfigUtils.init() NetConfigUtils.init()
@@ -259,65 +263,13 @@ class HttpDnsStartUp : AndroidStartup<Boolean>() {
mStartParams["app_flavor"] = DebugConfig.getProductFlavor() mStartParams["app_flavor"] = DebugConfig.getProductFlavor()
mStartParams["app_identity_mode"] = FunctionBuildConfig.appIdentityMode mStartParams["app_identity_mode"] = FunctionBuildConfig.appIdentityMode
MogoAnalyticUtils.track("app_start_time", mStartParams) MogoAnalyticUtils.track("app_start_time", mStartParams)
}
}
if (FunctionBuildConfig.isSecure) { override fun authCrtFile(device: String, root: String) {
context?.let { super.authCrtFile(device, root)
val authStatus = handler.post {
SharedPrefsMgr.getInstance() clientConfig.securityKey = device
.getBoolean("securityKeyStatus-${DebugConfig.getNetMode()}", false)
if (authStatus) {
// clientConfig设置auth值并带入header
clientConfig.authPubKey = SharedPrefsMgr.getInstance()
.getString("securityKey-${DebugConfig.getNetMode()}", "")
return@let
}
// 安全校验
try {
PassPortSecret.getInstance().init(sn, it.filesDir.path, object :
IPassportSecret {
@ChainLog(
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = CHAIN_SOURCE_CLOUD,
nodeAliasCode = CHAIN_CODE_CLOUD_PASSPORT_AUTH_OK,
paramIndexes = [0,1]
)
override fun onSuccess(securityKey: String, rootKey: String) {
CallerLogger.d(
"$M_MAIN$TAG",
"onSuccess securityKey:$securityKey , thread:${Thread.currentThread().name}"
)
clientConfig.securityKey = securityKey
SharedPrefsMgr.getInstance()
.putString(
"securityKey-${DebugConfig.getNetMode()}",
securityKey
)
SharedPrefsMgr.getInstance()
.putBoolean("securityKeyStatus-${DebugConfig.getNetMode()}", true)
CallerCloudListenerManager.invokeCloudCrtFile(securityKey, rootKey)
}
@ChainLog(
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = CHAIN_SOURCE_CLOUD,
nodeAliasCode = CHAIN_CODE_CLOUD_PASSPORT_AUTH_FAILED,
paramIndexes = [0, 1]
)
override fun onFailed(errorCode: Int, errorMsg: String) {
logError(
getPrReason(
"PassPortSecret-onFailed , errorCode:$errorCode,errorMsg:$errorMsg"
)
)
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
}
} }
} }

View File

@@ -0,0 +1,114 @@
package com.mogo.eagle.core.function.startup.stageone.secret
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.commons.debug.DebugConfig
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.function.api.cloud.IMoGoCertProvider
import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ThreadPoolService
import com.zhjt.service.chain.ChainLog
import java.util.concurrent.atomic.AtomicBoolean
@Route(path = MogoServicePaths.PATH_CERT_DOWN_LOAD_PROVIDER)
class CertFileManager : IMoGoCertProvider {
private var context: Context? = null
private val securityKeyTAG = "securityKey-${DebugConfig.getNetMode()}"
private val securityRootTAG = "securityRoot-${DebugConfig.getNetMode()}"
private val securityKeyStatus = "securityKeyStatus-${DebugConfig.getNetMode()}"
private val certStatus = AtomicBoolean(false)
@Volatile
private var deviceCrtFile: String? = null
@Volatile
private var rootCrtFile: String? = null
companion object {
private const val TAG = "CertFileManager"
}
override fun init(context: Context?) {
this.context = context
}
override fun certificateDownLoad(onError: ((String) -> Unit)?) {
if (FunctionBuildConfig.isSecure) {
context?.let {
val authStatus = SharedPrefsMgr.getInstance().getBoolean(securityKeyStatus, false)
if (authStatus) {
deviceCrtFile = SharedPrefsMgr.getInstance().getString(securityKeyTAG, "")
rootCrtFile = SharedPrefsMgr.getInstance().getString(securityRootTAG, "")
CallerCloudListenerManager.invokeCloudCrtFile(deviceCrtFile!!, rootCrtFile!!)
return@let
}
if (certStatus.get()) {
onError?.invoke("正在下载证书,请稍后再试")
return@let
}
// 安全校验
try {
ThreadPoolService.execute {
PassPortSecret.getInstance()
.init(SharedPrefsMgr.getInstance().sn, it.filesDir.path, object :
IPassportSecret {
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_CLOUD,
nodeAliasCode = ChainConstant.CHAIN_CODE_CLOUD_PASSPORT_AUTH_OK,
paramIndexes = [0, 1]
)
override fun onSuccess(securityKey: String, rootKey: String) {
CallerLogger.d(
"${SceneConstant.M_D_C}$TAG",
"onSuccess securityKey:$securityKey , thread:${Thread.currentThread().name}"
)
certStatus.set(true)
deviceCrtFile = securityKey
rootCrtFile = rootKey
SharedPrefsMgr.getInstance().putString(securityKeyTAG, securityKey)
SharedPrefsMgr.getInstance().putString(securityRootTAG, rootKey)
SharedPrefsMgr.getInstance().putBoolean(securityKeyStatus, true)
CallerCloudListenerManager.invokeCloudCrtFile(
securityKey,
rootKey
)
}
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_CLOUD,
nodeAliasCode = ChainConstant.CHAIN_CODE_CLOUD_PASSPORT_AUTH_FAILED,
paramIndexes = [0, 1]
)
override fun onFailed(errorCode: Int, errorMsg: String) {
CallerLogger.d("${SceneConstant.M_D_C}$TAG", "onFailed code:$errorCode, msg:$errorMsg")
certStatus.set(true)
onError?.invoke("证书下载失败, code:$errorCode, msg:$errorMsg")
}
})
}
} catch (e: Exception) {
e.printStackTrace()
}
}
} else {
onError?.invoke("当前环境id:${FunctionBuildConfig.urlJson.secureProductId} 不支持密钥下载")
}
}
override fun getDeviceCrtF(): String? {
return deviceCrtFile?:SharedPrefsMgr.getInstance().getString(securityKeyTAG, "")
}
override fun getRootCrtF(): String? {
return rootCrtFile?:SharedPrefsMgr.getInstance().getString(securityRootTAG, "")
}
}

View File

@@ -127,6 +127,14 @@ object FunctionBuildConfig {
@JvmField @JvmField
var mediaUrlConfig = "" var mediaUrlConfig = ""
/**
* 各车型宣传音频本地配置
* 广告json
*/
@Volatile
@JvmField
var musicUrlConfig = ""
/** /**
* 配置连接工控机的IP地址 * 配置连接工控机的IP地址

View File

@@ -97,6 +97,8 @@ public class MogoServicePaths {
@Keep @Keep
public static final String PATH_DATA_CENTER_MODULE = "/data_center/api"; public static final String PATH_DATA_CENTER_MODULE = "/data_center/api";
@Keep
public static final String PATH_CERT_DOWN_LOAD_PROVIDER = "/cert_file/api";
@Keep @Keep
public static final String PATH_VISUAL_ANGLE = "/map/angle_change"; public static final String PATH_VISUAL_ANGLE = "/map/angle_change";

View File

@@ -590,6 +590,13 @@ enum class EventTypeEnumNew(
"详情%s" "详情%s"
), ),
TYPE_POWER_OFF_TIP("POWER_OFF_TIP",
"一键停服",
"请等待1分钟再执行车辆下电",
R.drawable.icon_warning_take_over,
"请等待1分钟再执行车辆下电",
"请等待1分钟再执行车辆下电"),
TYPE_VIP_IDENTIFICATION_PASS("20022", "VIP通行", "", R.drawable.icon_warning_v2x_vip_turn_light, "VIP车辆优先通行已为您变为绿灯", "VIP车辆优先通行已为您变为绿灯"), TYPE_VIP_IDENTIFICATION_PASS("20022", "VIP通行", "", R.drawable.icon_warning_v2x_vip_turn_light, "VIP车辆优先通行已为您变为绿灯", "VIP车辆优先通行已为您变为绿灯"),
TYPE_VIP_IDENTIFICATION_EXTEND("20023", "VIP通行", "", R.drawable.icon_warning_v2x_vip_turn_light, "VIP车辆优先通行已为您延长绿灯", "VIP车辆优先通行已为您延长绿灯"), TYPE_VIP_IDENTIFICATION_EXTEND("20023", "VIP通行", "", R.drawable.icon_warning_v2x_vip_turn_light, "VIP车辆优先通行已为您延长绿灯", "VIP车辆优先通行已为您延长绿灯"),
TYPE_VIP_ERROR_IDENTIFICATION("20024", "VIP通行", "", R.drawable.icon_warning_v2x_vip_turn_light, "请求失败,", "请求失败,稍后重试"), TYPE_VIP_ERROR_IDENTIFICATION("20024", "VIP通行", "", R.drawable.icon_warning_v2x_vip_turn_light, "请求失败,", "请求失败,稍后重试"),
@@ -947,6 +954,10 @@ enum class EventTypeEnumNew(
TYPE_DEVICE_STATUS_ABNORMAL.poiType ->{ TYPE_DEVICE_STATUS_ABNORMAL.poiType ->{
TYPE_DEVICE_STATUS_ABNORMAL.poiTypeStr TYPE_DEVICE_STATUS_ABNORMAL.poiTypeStr
} }
//一键停服
TYPE_POWER_OFF_TIP.poiType ->{
TYPE_POWER_OFF_TIP.poiTypeStr
}
//机动车 //机动车
TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType ->{ TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType ->{
TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiTypeStr TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiTypeStr
@@ -1266,6 +1277,10 @@ enum class EventTypeEnumNew(
TYPE_DEVICE_STATUS_ABNORMAL.poiType->{ TYPE_DEVICE_STATUS_ABNORMAL.poiType->{
R.drawable.icon_default R.drawable.icon_default
} }
//一键停服
TYPE_POWER_OFF_TIP.poiType->{
R.drawable.icon_warning_take_over
}
//机动车 //机动车
TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType -> { TYPE_USECASE_ID_VRUCW_MOTOR_VEHICLES.poiType -> {
R.drawable.icon_warning_v2x_motorcycle_collision R.drawable.icon_warning_v2x_motorcycle_collision

View File

@@ -0,0 +1,11 @@
package com.mogo.eagle.core.function.api.cloud
import com.alibaba.android.arouter.facade.template.IProvider
interface IMoGoCertProvider:IProvider {
fun certificateDownLoad(onError: ((String) -> Unit)? = null)
fun getDeviceCrtF():String?
fun getRootCrtF(): String?
}

View File

@@ -3,7 +3,7 @@ package com.mogo.eagle.core.function.api.cloud
import com.mogo.eagle.core.data.v2x.V2XEvent import com.mogo.eagle.core.data.v2x.V2XEvent
interface IMoGoCloudListener{ interface IMoGoCloudListener{
//单独线程
fun authCrtFile(device:String, root:String){} fun authCrtFile(device:String, root:String){}
fun tokenGot(token: String, sn: String){} fun tokenGot(token: String, sn: String){}

View File

@@ -128,6 +128,46 @@ interface IDevaToolsProvider : IProvider {
*/ */
fun showBadCaseManagerView(context: Context) fun showBadCaseManagerView(context: Context)
/**
* 启动调用SSM停服命令超时检测
*/
fun startCommandWaitCountDown()
/**
* 停止调用SSM停服命令超时检测
*/
fun stopCommandWaitCountDown()
/**
* 开始车辆下电等待倒计时
*/
fun startPowerDownCountDown()
/**
* 结束车辆下电等待倒计时
*/
fun stopPowerDownCountDown()
/**
* 状态按钮变更倒计时
*/
fun statusChangeCountDown(isSuccess: Boolean)
/**
* 结束状态按钮变更倒计时
*/
fun stopStatusCountDown()
/**
* 设置停服状态
*/
fun setPowerOffStatus(status: Int)
/**
* 获取停服状态
*/
fun getPowerOffStatus(): Int
/** /**
* 工控机异常上报列表 * 工控机异常上报列表
*/ */

View File

@@ -0,0 +1,25 @@
package com.mogo.eagle.core.function.api.devatools
interface IPowerOffListener {
/**
* 调用SSM停服命令超时
*/
fun commandTimeout()
/**
* 车辆下电等待倒计时
*/
fun powerDownTick(second: Int)
/**
* 车辆下电等待倒计时结束
*/
fun powerDownFinish()
/**
* 状态按钮变更通知
*/
fun statusChange(isSuccess: Boolean)
}

View File

@@ -25,4 +25,6 @@ interface IMoGoBlockProvider {
fun stop() fun stop()
fun recorder(): IMessageRecorder fun recorder(): IMessageRecorder
fun dump(extra: Map<String, List<String>>? = null)
} }

View File

@@ -2,8 +2,13 @@ package com.mogo.eagle.core.function.call.autopilot
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo
import com.mogo.eagle.core.data.msgbox.AutopilotMsg
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.SSMMsg
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.base.CallerBase import com.mogo.eagle.core.function.call.base.CallerBase
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.call.trace.CallerTrace import com.mogo.eagle.core.function.call.trace.CallerTrace
import com.mogo.eagle.core.utilcode.util.GsonUtils import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.zhjt.mogo.adas.data.AdasConstants import com.zhjt.mogo.adas.data.AdasConstants
@@ -212,6 +217,14 @@ object CallerAutoPilotStatusListenerManager : CallerBase<IMoGoAutopilotStatusLis
val listener = it.value val listener = it.value
listener.onAutopilotIpcConnectStatusChanged(status, reason) listener.onAutopilotIpcConnectStatusChanged(status, reason)
} }
when (status) {
AdasConstants.IpcConnectionStatus.DISCONNECTED -> {
CallerMsgBoxManager.saveMsgBox(MsgBoxBean(MsgBoxType.AUTOPILOT, AutopilotMsg(0, "连接异常", "域控未连接或主动断开连接", System.currentTimeMillis())))
}
AdasConstants.IpcConnectionStatus.CONNECT_EXCEPTION -> {
CallerMsgBoxManager.saveMsgBox(MsgBoxBean(MsgBoxType.AUTOPILOT, AutopilotMsg(0, "连接异常", "域控连接异常:$reason", System.currentTimeMillis())))
}
}
} }
/** /**
@@ -224,6 +237,11 @@ object CallerAutoPilotStatusListenerManager : CallerBase<IMoGoAutopilotStatusLis
val listener = it.value val listener = it.value
listener.onSsmReceiveTimeout(isTimeout) listener.onSsmReceiveTimeout(isTimeout)
} }
if (isTimeout) {
CallerMsgBoxManager.saveMsgBox(MsgBoxBean(MsgBoxType.SSMINFO, SSMMsg(0, "连接超时", "ssm超时无响应", System.currentTimeMillis())))
} else {
CallerMsgBoxManager.saveMsgBox(MsgBoxBean(MsgBoxType.SSMINFO, SSMMsg(0, "连接恢复", "ssm连接恢复", System.currentTimeMillis())))
}
} }
/** /**

View File

@@ -10,9 +10,6 @@ import com.zhjt.mogo.adas.data.bean.ReceivedAck
*/ */
object CallerReceiveReceivedAckListenerManager : CallerBase<IMoGoReceiveReceivedAckListener>() { object CallerReceiveReceivedAckListenerManager : CallerBase<IMoGoReceiveReceivedAckListener>() {
/**
* 金旅M1
*/
fun invokeReceiveReceivedAck(receivedAck: ReceivedAck) { fun invokeReceiveReceivedAck(receivedAck: ReceivedAck) {
M_LISTENERS.forEach { M_LISTENERS.forEach {
val listener = it.value val listener = it.value

View File

@@ -0,0 +1,26 @@
package com.mogo.eagle.core.function.call.cloud
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.function.api.cloud.IMoGoCertProvider
import com.mogo.eagle.core.function.call.base.CallerBase
object CallerCloudCertManager {
private val certProviderApi: IMoGoCertProvider
get() = CallerBase.getApiInstance(
IMoGoCertProvider::class.java,
MogoServicePaths.PATH_CERT_DOWN_LOAD_PROVIDER
)
fun certFileDownLoad(onError: ((String) -> Unit)? = null) {
certProviderApi.certificateDownLoad(onError)
}
fun getDeviceCrtF(): String? {
return certProviderApi.getDeviceCrtF()
}
fun getRootCrtF(): String? {
return certProviderApi.getRootCrtF()
}
}

View File

@@ -12,12 +12,6 @@ object CallerCloudListenerManager : CallerBase<IMoGoCloudListener>() {
@Volatile @Volatile
private var sn: String? = null private var sn: String? = null
@Volatile
private var deviceCrtFile: String? = null
@Volatile
private var rootCrtFile: String? = null
override fun doSomeAfterAddListener(tag: String, listener: IMoGoCloudListener) { override fun doSomeAfterAddListener(tag: String, listener: IMoGoCloudListener) {
super.doSomeAfterAddListener(tag, listener) super.doSomeAfterAddListener(tag, listener)
if (!token.isNullOrEmpty() && !sn.isNullOrEmpty()) { if (!token.isNullOrEmpty() && !sn.isNullOrEmpty()) {
@@ -25,17 +19,7 @@ object CallerCloudListenerManager : CallerBase<IMoGoCloudListener>() {
} }
} }
fun getRootCrtF(): String? {
return rootCrtFile
}
fun getDeviceCrtF(): String? {
return deviceCrtFile
}
fun invokeCloudCrtFile(deviceCrtFile: String, rootCrtFile: String) { fun invokeCloudCrtFile(deviceCrtFile: String, rootCrtFile: String) {
this.deviceCrtFile = deviceCrtFile
this.rootCrtFile = rootCrtFile
M_LISTENERS.forEach { M_LISTENERS.forEach {
val listener = it.value val listener = it.value
listener.authCrtFile(deviceCrtFile, rootCrtFile) listener.authCrtFile(deviceCrtFile, rootCrtFile)

View File

@@ -170,6 +170,62 @@ object CallerDevaToolsManager {
devaToolsProviderApi?.showBadCaseManagerView(context) devaToolsProviderApi?.showBadCaseManagerView(context)
} }
/**
* 启动调用SSM停服命令超时检测
*/
fun startCommandWaitCountDown(){
devaToolsProviderApi?.startCommandWaitCountDown()
}
/**
* 停止调用SSM停服命令超时检测
*/
fun stopCommandWaitCountDown(){
devaToolsProviderApi?.stopCommandWaitCountDown()
}
/**
* 开始车辆下电等待倒计时
*/
fun startPowerDownCountDown(){
devaToolsProviderApi?.startPowerDownCountDown()
}
/**
* 结束车辆下电等待倒计时
*/
fun stopPowerDownCountDown(){
devaToolsProviderApi?.stopPowerDownCountDown()
}
/**
* 状态按钮变更倒计时
*/
fun statusChangeCountDown(isSuccess: Boolean){
devaToolsProviderApi?.statusChangeCountDown(isSuccess)
}
/**
* 结束状态按钮变更倒计时
*/
fun stopStatusCountDown(){
devaToolsProviderApi?.stopStatusCountDown()
}
/**
* 设置停服状态
*/
fun setPowerOffStatus(status: Int){
devaToolsProviderApi?.setPowerOffStatus(status)
}
/**
* 获取停服状态
*/
fun getPowerOffStatus(): Int? {
return devaToolsProviderApi?.getPowerOffStatus()
}
/** /**
* 工控机异常上报列表 * 工控机异常上报列表
*/ */

View File

@@ -0,0 +1,48 @@
package com.mogo.eagle.core.function.call.devatools
import com.mogo.eagle.core.function.api.devatools.IPowerOffListener
import com.mogo.eagle.core.function.call.base.CallerBase
object CallerPowerOffManager : CallerBase<IPowerOffListener>() {
/**
* 一键停服调用SSM停服命令超时
*/
fun invokeCommandTimeout(){
M_LISTENERS.forEach{
val listener = it.value
listener.commandTimeout()
}
}
/**
* 一键停服车辆下电等待倒计时
*/
fun invokePowerDownTick(second: Int){
M_LISTENERS.forEach{
val listener = it.value
listener.powerDownTick(second)
}
}
/**
* 一键停服车辆下电等待倒计时结束
*/
fun invokePowerDownFinish(){
M_LISTENERS.forEach{
val listener = it.value
listener.powerDownFinish()
}
}
/**
* 一键停服状态按钮变更通知
*/
fun invokeStatusChange(isSuccess: Boolean){
M_LISTENERS.forEach{
val listener = it.value
listener.statusChange(isSuccess)
}
}
}

View File

@@ -8,6 +8,7 @@
<dimen name="dp_m_30">-30dp</dimen> <dimen name="dp_m_30">-30dp</dimen>
<dimen name="dp_m_27">-27dp</dimen> <dimen name="dp_m_27">-27dp</dimen>
<dimen name="dp_m_20">-20dp</dimen> <dimen name="dp_m_20">-20dp</dimen>
<dimen name="dp_m_17">-17dp</dimen>
<dimen name="dp_m_12">-12dp</dimen> <dimen name="dp_m_12">-12dp</dimen>
<dimen name="dp_m_10">-10dp</dimen> <dimen name="dp_m_10">-10dp</dimen>
<dimen name="dp_m_8">-8dp</dimen> <dimen name="dp_m_8">-8dp</dimen>

View File

@@ -56,4 +56,32 @@ object DownloadUtils {
} }
.launchIn(scope) .launchIn(scope)
} }
fun downLoadNoUi(ctx: Context?, url: String, savePath: String, fileName: String, listener: IDownloadListener?) { // FileBean fileBean = new FileBean(0, savePath, fileName, url, 0);
val context = ctx ?: Utils.getApp() ?: throw AssertionError("context must not be null.")
if (!Downloader.hasInit()) {
Downloader.init(context)
Downloader.setLoggable(BuildConfig.DEBUG)
}
Downloader.setNetStatePoller(poller)
Downloader.download(url, File(savePath, fileName))
.onEach {
when(it) {
is DownloadStart ->
UiThreadHandler.post { listener?.onStart(url) }
is Downloading -> {
UiThreadHandler.post { listener?.onProgress(url, it.downloaded, it.total) }
}
is DownloadSuccess -> {
UiThreadHandler.post { listener?.onFinished(url, it.path)}
}
is DownloadFailed -> {
UiThreadHandler.post { listener?.onError(url, it.msg) }
}
}
}
.filter {
it.isComplete()
}
.launchIn(scope)
}
} }

View File

@@ -12,6 +12,8 @@ import android.util.Log;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import com.mogo.eagle.core.utilcode.util.ActivityUtils;
/** /**
* 长时间后台运行权限检查 * 长时间后台运行权限检查
@@ -41,8 +43,7 @@ public class BackgrounderPermission {
public void showPermissionLongBackgroundRunningDialog(Context context) { public void showPermissionLongBackgroundRunningDialog(Context context) {
Intent intent = new Intent(context, PermissionLongBackgroundRunningDialog.class); Intent intent = new Intent(context, PermissionLongBackgroundRunningDialog.class);
context.startActivity(intent); ActivityUtils.startActivity(intent);
} }
void onBackgrounderPermission(boolean isBackgrounderPermission) { void onBackgrounderPermission(boolean isBackgrounderPermission) {

View File

@@ -54,7 +54,7 @@ class ApkInstaller {
val intent = Intent(context, InstallApkSessionApi::class.java) val intent = Intent(context, InstallApkSessionApi::class.java)
intent.putExtra("APK_FILE_PATH", apkFile.absolutePath) intent.putExtra("APK_FILE_PATH", apkFile.absolutePath)
block?.also { InstallApkSessionApi.listener = it } block?.also { InstallApkSessionApi.listener = it }
context.startActivity(intent) ActivityUtils.startActivity(intent)
} }
} }
@@ -161,7 +161,9 @@ class InstallApkSessionApi: AppCompatActivity() {
Log.i(TAG, "--- InstallApkSessionApi -- confirm --") Log.i(TAG, "--- InstallApkSessionApi -- confirm --")
// This test app isn't privileged, so the user has to confirm the install. // This test app isn't privileged, so the user has to confirm the install.
val confirmIntent = extras[Intent.EXTRA_INTENT] as? Intent val confirmIntent = extras[Intent.EXTRA_INTENT] as? Intent
startActivity(confirmIntent) confirmIntent?.also {
ActivityUtils.startActivity(it)
}
finish() finish()
} }
STATUS_SUCCESS -> { STATUS_SUCCESS -> {

View File

@@ -125,19 +125,7 @@ public class ReceivedAck {
this.receivedAck = receivedAck; this.receivedAck = receivedAck;
} }
/**
* 确认是否收到回执
*
* @param msgId 下发的消息id
* @return 是否收到回执
*/
public boolean isReceiptReceived(long msgId) {
Log.i("ReceivedAck", "消息=" + msgId + " 结果=" + toString());
if (status == Status.NORMAL) {
return this.msgId == msgId;
}
return false;
}
@Override @Override
public String toString() { public String toString() {

View File

@@ -17,6 +17,7 @@ enum LightState {
STATE_YELLOW = 2; STATE_YELLOW = 2;
STATE_GREEN = 3; STATE_GREEN = 3;
STATE_FLASH = 4;//闪烁 STATE_FLASH = 4;//闪烁
STATE_OFF_FUSION = 5;
} }
message TrafficLight { message TrafficLight {
@@ -24,6 +25,7 @@ message TrafficLight {
optional LightType type = 2 [default = TYPE_DEFAULT];//灯所处的车道类型 optional LightType type = 2 [default = TYPE_DEFAULT];//灯所处的车道类型
optional LightState state = 3 [default = STATE_OFF];//灯态 optional LightState state = 3 [default = STATE_OFF];//灯态
optional float duration = 4; // seconds since the last state changed optional float duration = 4; // seconds since the last state changed
optional LightState next_state = 5 [default = STATE_OFF_FUSION];
} }
//触发方式120m以内会有信号但远的时候可能不准越近越准 //触发方式120m以内会有信号但远的时候可能不准越近越准
@@ -35,4 +37,7 @@ message TrafficLights {
optional TrafficLight left = 3;//左转灯 optional TrafficLight left = 3;//左转灯
optional TrafficLight right = 4;//右转灯 optional TrafficLight right = 4;//右转灯
optional TrafficLight u_turn = 5;//掉头灯 optional TrafficLight u_turn = 5;//掉头灯
optional bool shield = 6 [default = false];//wheather the traffic lights are shield
optional uint32 source = 7 [default = 0]; // 0: vehicle, 1:V2I, 2: V2N
} }