Merge remote-tracking branch 'origin/dev_merge_shunyi_vr_map' into dev_merge_shunyi_vr_map

# Conflicts:
#	modules/mogo-module-service/src/main/java/com/mogo/module/service/location/MogoRTKLocation.java
This commit is contained in:
wangcongtao
2020-12-18 10:55:59 +08:00
72 changed files with 1784 additions and 251 deletions

View File

@@ -3,9 +3,18 @@
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" withSubpackages="false" static="false" />
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
<package name="io.ktor" withSubpackages="true" static="false" />
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
</JetCodeStyleSettings>

5
.idea/misc.xml generated
View File

@@ -4,10 +4,7 @@
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="SuppressionsComponent">
<option name="suppComments" value="[]" />
</component>
</project>

View File

@@ -4,6 +4,7 @@
package="com.mogo.launcher">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application
android:name=".MogoApplication"

View File

@@ -32,6 +32,7 @@ import com.mogo.utils.ProcessUtils;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.logger.LogLevel;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.storage.SharedPrefsMgr;
import com.squareup.leakcanary.LeakCanary;
import com.zhidao.boot.persistent.lib.PersistentManager;
import com.zhidao.mogo.module.left.panel.LeftPanelConst;
@@ -141,7 +142,7 @@ public class MogoApplication extends AbsMogoApplication {
DebugConfig.setNeedLoadGuideModule( BuildConfig.IS_NEED_LOAD_GUIDE_MODULE );
DebugConfig.setNeedHideAdasWhenShare( BuildConfig.IS_NEED_HIDE_ADAS_WHEN_SHARE );
DebugConfig.setNeedUploadCoordinatesInTime( BuildConfig.IS_NEED_UPLOAD_COORDINATES_IN_TIME );
// DebugConfig.setObuType( BuildConfig.OBU_TYPE );
DebugConfig.setObuType(SharedPrefsMgr.getInstance(this).getInt("OBU_TYPE", DebugConfig.OBU_TYPE_CIDI));
}
@Override

View File

@@ -90,6 +90,11 @@ public class DebugConfig {
*/
public static final int OBU_TYPE_HUALI = 2;
/**
* 大唐高鸿obu 11.11国展
*/
public static final int OBU_TYPE_GOHIGH = 3;
/**
* 获取网络环境类型
*

View File

@@ -3,6 +3,10 @@ package com.mogo.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import androidx.annotation.Nullable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -107,4 +111,17 @@ public class NetworkUtils {
return matcher.matches();
}
public static int netStrengthLevel = 0;
public static void listenNetStrength(Context context) {
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
manager.listen(new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
netStrengthLevel = signalStrength.getLevel();
}
}, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
}

View File

@@ -0,0 +1,141 @@
package com.mogo.module.common.animation;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import androidx.core.content.ContextCompat;
import com.mogo.module.common.R;
import java.util.Random;
public class BezierAnimationView extends RelativeLayout implements View.OnClickListener {
private String TAG = "BezierAnimationView";
private Context context;
private int[] animation_drawable = {
R.drawable.icon_common_heart_animation_vr00,
R.drawable.icon_heart_unchoose_other,
R.drawable.icon_map_marker_living};
private Random random = new Random();
private int width = 500, height = 210;
private int drawableWidth, drawableHeight;
public BezierAnimationView(Context context) {
this(context, null);
}
public BezierAnimationView(Context context, AttributeSet attributes) {
this(context, attributes, 0);
}
public BezierAnimationView(Context context, AttributeSet attributes, int defStyleAttr) {
super(context, attributes, defStyleAttr);
this.context = context;
//3、设置点击事件
setOnClickListener(this);
//4、获取点赞图片的宽高
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.icon_common_heart_animation_vr02);
drawableWidth = drawable.getIntrinsicWidth();
drawableHeight = drawable.getIntrinsicHeight();
}
@Override
public void onClick(View view) {
Log.d("执行点赞动画", "ppp");
bezierAnimation();
}
private void bezierAnimation() {
final ImageView imageView = new ImageView(context);
imageView.setBackgroundResource(animation_drawable[random.nextInt(animation_drawable.length - 1)]);
RelativeLayout.LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(ALIGN_BOTTOM);
params.addRule(CENTER_HORIZONTAL);
imageView.setLayoutParams(params);
addView(imageView);
/*
* 开始执行点赞效果
* */
AnimatorSet animatorSet = getAnimatorSet(imageView);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//3、动画执行后移除View
removeView(imageView);
}
});
animatorSet.start();
}
private AnimatorSet getAnimatorSet(ImageView imageView) {
AnimatorSet enter = new AnimatorSet();
/*
* 缩放动画
* */
AnimatorSet scaleAnimator = new AnimatorSet();
ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView, "alpha", 0.8f, 1f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 0.8f, 1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 0.8f, 1f);
scaleAnimator.setDuration(500);
scaleAnimator.playTogether(alpha, scaleX, scaleY);
/*
* 贝塞尔动画
* */
ValueAnimator bezierAnimator = getBezierValueAnimator(imageView);
/*
* 两个动画按顺序播放
* */
enter.playSequentially(scaleAnimator, bezierAnimator);
return enter;
}
/**
* 获取贝塞尔曲线动画
*
* @param target
* @return
*/
private ValueAnimator getBezierValueAnimator(View target) {
//初始化一个BezierEvaluator
BezierEvaluator evaluator = new BezierEvaluator(getPointF(1), getPointF(1));
// 起点固定,终点随机
ValueAnimator animator = ValueAnimator.ofObject(evaluator, new PointF((width - 40) / 2, height - 80),
new PointF(random.nextInt(getWidth()), 0));
animator.addUpdateListener(new BezierListener(target));
animator.setTarget(target);
animator.setDuration(3000);
return animator;
}
/**
* 获取一条路径的两个控制点
*
* @param scale
*/
private PointF getPointF(int scale) {
PointF pointF = new PointF();
//减去100 是为了控制 x轴活动范围
pointF.x = random.nextInt((width));
//再Y轴上 为了确保第二个控制点 在第一个点之上,我把Y分成了上下两半
pointF.y = random.nextInt((height)) / scale;
return pointF;
}
}

View File

@@ -0,0 +1,45 @@
package com.mogo.module.common.animation;
import android.animation.TypeEvaluator;
import android.graphics.PointF;
/**
* 贝塞尔曲线估值器:计算动画的执行轨迹
*
* @params 传入贝塞尔曲线需要的四个点
* @return 通过计算返回贝塞尔曲线的坐标
*/
public class BezierEvaluator implements TypeEvaluator<PointF> {
private PointF pointF1;
private PointF pointF2;
public BezierEvaluator(PointF point1, PointF point2) {
this.pointF1 = point1;
this.pointF2 = point2;
}
@Override
public PointF evaluate(float time, PointF startValue, PointF endValue) {
float timeLeft = 1.0f - time;
//结果
PointF point = new PointF();
PointF point0 = (PointF)startValue;//起点
PointF point3 = (PointF)endValue;//终点
// 贝塞尔公式
point.x = timeLeft * timeLeft * timeLeft * (point0.x)
+ 3 * timeLeft * timeLeft * time * (pointF1.x)
+ 3 * timeLeft * time * time * (pointF2.x)
+ time * time * time * (point3.x);
point.y = timeLeft * timeLeft * timeLeft * (point0.y)
+ 3 * timeLeft * timeLeft * time * (pointF1.y)
+ 3 * timeLeft * time * time * (pointF2.y)
+ time * time * time * (point3.y);
return point;
}
}

View File

@@ -0,0 +1,24 @@
package com.mogo.module.common.animation;
import android.animation.ValueAnimator;
import android.graphics.PointF;
import android.view.View;
public class BezierListener implements ValueAnimator.AnimatorUpdateListener {
private View target;
public BezierListener(View target) {
this.target = target;
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//这里获取到贝塞尔曲线计算出来的的x y值 赋值给view 这样就能让爱心随着曲线走啦
PointF pointF = (PointF) animation.getAnimatedValue();
target.setX(pointF.x);
target.setY(pointF.y);
// 这里偷个懒,顺便做一个alpha动画,这样alpha渐变也完成啦
target.setAlpha(1 - animation.getAnimatedFraction());
}
}

View File

@@ -0,0 +1,18 @@
package com.mogo.module.common.constants;
/**
* 用于内部标识红绿灯颜色
*
* @author tongchenfei
*/
public class TrafficLightConst {
public static final int TRAFFIC_LIGHT_COLOR_GRAY = 0;
public static final int TRAFFIC_LIGHT_COLOR_RED = 1;
public static final int TRAFFIC_LIGHT_COLOR_YELLOW = 2;
public static final int TRAFFIC_LIGHT_COLOR_GREEN = 3;
public static final int TRAFFIC_LIGHT_DIRECTION_TURN_AROUND = 0;
public static final int TRAFFIC_LIGHT_DIRECTION_TURN_LEFT = 1;
public static final int TRAFFIC_LIGHT_DIRECTION_STRAIGHT = 2;
public static final int TRAFFIC_LIGHT_DIRECTION_TURN_RIGHT = 3;
}

View File

@@ -0,0 +1,67 @@
package com.mogo.module.common.drawer.marker;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.ModuleNames;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.R;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerShareMusic;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.common.marker.PoiWrapper;
import com.mogo.module.common.utils.CloudPoiManager;
import com.mogo.utils.logger.Logger;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-0619:55
* desc : 地图Marker图标带文本信息
* version: 1.0
*/
public class MapCameraInfoView extends MapMarkerBaseView {
private String TAG = "MapCameraInfoView";
private ImageView mCameraImage;
public MapCameraInfoView(Context context ) {
super( context );
}
public MapCameraInfoView(Context context, @Nullable AttributeSet attrs ) {
super( context, attrs );
}
public MapCameraInfoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr ) {
super( context, attrs, defStyleAttr );
}
public MapCameraInfoView(Context context, MogoMarkerOptions options ) {
super( context );
mOptions = options;
}
@Override
protected void initView( Context context ) {
LayoutInflater.from( context ).inflate( R.layout.modudle_camera_layout_info, this );
mCameraImage = findViewById( R.id.iv_camera_traffic);
}
@Override
public void updateView( MarkerShowEntity markerShowEntity ) {
}
}

View File

@@ -3,6 +3,8 @@ package com.mogo.module.common.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
@@ -19,11 +21,10 @@ import com.mogo.skin.support.helper.MogoSkinCompatBackgroundHelperDelegate;
* desc :
* version: 1.0
*/
public class RoundLayout extends RelativeLayout implements IMogoSkinCompatSupportable {
public class RoundLayout extends RelativeLayout {
private float roundLayoutRadius = 14f;
private Path roundPath;
private RectF rectF;
private MogoSkinCompatBackgroundHelperDelegate mBackgroundTintHelper;
public RoundLayout(Context context) {
this(context, null);
@@ -41,9 +42,6 @@ public class RoundLayout extends RelativeLayout implements IMogoSkinCompatSuppor
typedArray.recycle();
init();
mBackgroundTintHelper = new MogoSkinCompatBackgroundHelperDelegate(this);
mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
}
@@ -75,16 +73,10 @@ public class RoundLayout extends RelativeLayout implements IMogoSkinCompatSuppor
@Override
public void draw(Canvas canvas) {
if (roundLayoutRadius > 0f) {
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
canvas.clipPath(roundPath);
}
super.draw(canvas);
}
@Override
public void applySkin() {
if (mBackgroundTintHelper != null) {
mBackgroundTintHelper.applySkin();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="1px"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<ImageView
android:id="@+id/iv_camera_traffic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/module_camera_real_time_traffic" />
</LinearLayout>

View File

@@ -4,15 +4,18 @@ import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -207,6 +210,8 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
private TextView seekHelpNum;
private View debugPanel;
private AdasNoticeHelper adasNoticeHelper = new AdasNoticeHelper();
private CameraLiveNoticeHelper mCameraLiveNoticeHelper = new CameraLiveNoticeHelper();
@@ -234,6 +239,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
seekHelpGroup = findViewById(R.id.module_ext_id_seek_help_notice_group);
seekHelpNum = findViewById(R.id.module_ext_id_seek_help_notice_number);
debugPanel = findViewById(R.id.debugPanel);
NoMapTopViewShaderHelper.getInstance().initShaderView(findViewById(R.id.module_ext_id_top_container_shader));
@@ -472,20 +478,41 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
}
});
debugPanel.setOnClickListener(view -> {
if (SystemClock.elapsedRealtime() - lastDebugPanelClickTime > 1000) {
debugPanelClickCount = 1;
}else{
debugPanelClickCount++;
}
lastDebugPanelClickTime = SystemClock.elapsedRealtime();
if (debugPanelClickCount == 10) {
// show panel
debugPanelGroup.setVisibility(View.VISIBLE);
}
});
initDebugPanel();
}
private int debugPanelClickCount = 0;
private long lastDebugPanelClickTime = 0;
private EditText etTimes;
private Group groupFix;
private void enterVrMode(){
tvEnterVrMode.setVisibility(View.GONE);
// tvEnterVrMode.setVisibility(View.GONE);
mMove2CurrentLocation.setVisibility(View.GONE);
mUploadRoadCondition.setVisibility(View.GONE);
mWeatherContainer.setVisibility(View.GONE);
mMsgContainer.setVisibility(View.GONE);
groupUserHead.setVisibility(View.GONE);
tvExitVrMode.setVisibility(View.VISIBLE);
// tvExitVrMode.setVisibility(View.VISIBLE);
TopViewAnimHelper.getInstance().enterVrMode();
TopViewNoLinkageAnimHelper.getInstance().enterVrMode();
mNaviInfo = vrModeNavInfoView;
@@ -497,14 +524,14 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
private void exitVrMode(){
EntranceViewHolder.getInstance().forceHideNoticeView();
tvEnterVrMode.setVisibility(View.VISIBLE);
// tvEnterVrMode.setVisibility(View.VISIBLE);
mMove2CurrentLocation.setVisibility(View.VISIBLE);
mUploadRoadCondition.setVisibility(View.VISIBLE);
groupUserHead.setVisibility(View.VISIBLE);
// mWeatherContainer.setVisibility(View.VISIBLE);
// mMsgContainer.setVisibility(View.VISIBLE);
tvExitVrMode.setVisibility(View.GONE);
// tvExitVrMode.setVisibility(View.GONE);
TopViewAnimHelper.getInstance().exitVrMode();
TopViewNoLinkageAnimHelper.getInstance().exitVrMode();
mNaviInfo = animNavInfoView;
@@ -1219,4 +1246,68 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
public void onLocationChanged(MogoLocation location) {
vrModeNavInfoView.refreshCurrentSpeed((int) (location.getSpeed() * 3.6F));
}
private Group debugPanelGroup;
private ImageButton ibDebugPanelClose;
private Button btnOpenLog,btnCloseLog,btnOpenV2XPanel;
private RadioButton rbCidi,rbHuali, rbGohigh;
private void initDebugPanel() {
debugPanelGroup = findViewById(R.id.groupDebugPanel);
ibDebugPanelClose = findViewById(R.id.ibDebugPanelClose);
btnOpenLog = findViewById(R.id.btnOpenLog);
btnCloseLog = findViewById(R.id.btnCloseLog);
btnOpenV2XPanel = findViewById(R.id.btnOpenV2xPanel);
rbCidi = findViewById(R.id.rbCidiObu);
rbHuali = findViewById(R.id.rbHualiObu);
rbGohigh = findViewById(R.id.rbGoHighObu);
ibDebugPanelClose.setOnClickListener(v -> debugPanelGroup.setVisibility(View.GONE));
btnOpenLog.setOnClickListener(v->{
Intent intent = new Intent("com.mogo.ACTION");
intent.putExtra("oper", 1);
getContext().sendBroadcast(intent);
debugPanelGroup.setVisibility(View.GONE);
});
btnCloseLog.setOnClickListener(v -> {
Intent intent = new Intent("com.mogo.ACTION");
intent.putExtra("oper", 2);
getContext().sendBroadcast(intent);
debugPanelGroup.setVisibility(View.GONE);
});
btnOpenV2XPanel.setOnClickListener(v -> {
Intent intent = new Intent("com.v2x.test_panel_control");
intent.putExtra("TextPanelOpenStatus", true);
getContext().sendBroadcast(intent);
debugPanelGroup.setVisibility(View.GONE);
});
switch (DebugConfig.getObuType()) {
case DebugConfig.OBU_TYPE_CIDI:
rbCidi.setChecked(true);
break;
case DebugConfig.OBU_TYPE_HUALI:
rbHuali.setChecked(true);
break;
default:
rbGohigh.setChecked(true);
break;
}
rbCidi.setOnClickListener(v -> exchangeObuType(DebugConfig.OBU_TYPE_CIDI));
rbHuali.setOnClickListener(v -> exchangeObuType(DebugConfig.OBU_TYPE_HUALI));
rbGohigh.setOnClickListener(v -> exchangeObuType(DebugConfig.OBU_TYPE_GOHIGH));
}
private void exchangeObuType(int obuType) {
SharedPrefsMgr.getInstance(getContext()).putInt("OBU_TYPE", obuType);
DebugConfig.setObuType(obuType);
Intent intent = new Intent("com.mogo.launcher.v2x.action.EXCHANGE_OBU_TYPE");
intent.putExtra("obuType", obuType);
getContext().sendBroadcast(intent);
}
}

View File

@@ -113,7 +113,7 @@ public class CameraLiveGSYVideoView extends LiveRoundLayout implements IMogoSkin
private void playLiveVideo(String liveUrl) {
try {
if (mLivePlayer != null) {
mLivePlayer.startPlay(liveUrl, TXLivePlayer.PLAY_TYPE_LIVE_RTMP);
mLivePlayer.startPlay(liveUrl, TXLivePlayer.PLAY_TYPE_LIVE_FLV);
mLivePlayer.setPlayListener(new ITXLivePlayListener() {
@Override
public void onPlayEvent(int event, Bundle bundle) {

View File

@@ -0,0 +1,33 @@
package com.mogo.module.extensions.live;
import android.content.Context;
import android.view.View;
import com.mogo.map.marker.IMogoInfoWindowAdapter;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.drawer.marker.IMarkerView;
import com.mogo.module.common.drawer.marker.MapCameraInfoView;
import com.mogo.module.common.drawer.marker.MapMarkerAdapter;
import com.mogo.module.common.drawer.marker.MapMarkerView;
import com.mogo.module.common.entity.MarkerShowEntity;
/**
* @author lixiaopeng
* @since 2020/12/16
* 描述
*/
public class CameraWindow3DAdapter implements IMogoInfoWindowAdapter {
private Context mContext;
private MogoMarkerOptions mOptions;
public CameraWindow3DAdapter(Context context, MogoMarkerOptions options) {
this.mContext = context;
this.mOptions = options;
}
@Override
public View getInfoWindow(IMogoMarker marker) {
return new MapCameraInfoView(mContext, mOptions);
}
}

View File

@@ -88,6 +88,9 @@ public class VrModeNavInfoView extends BaseNaviInfoView implements Handler.Callb
}
}
private int[] lightArray = new int[4];
private String[] surplusTimeArray = new String[4];
/**
* 刷新红绿灯显示状态
*
@@ -95,10 +98,22 @@ public class VrModeNavInfoView extends BaseNaviInfoView implements Handler.Callb
* @param surplusTime 固定数组长度为4的剩余时长数组从0-3依次代表 掉头,左转,执行,右转
*/
public void refreshTrafficLightStatus(int[] laneLight, String[] surplusTime) {
lightArray = laneLight;
surplusTimeArray = surplusTime;
turnAroundLight.setTrafficLightStatus(laneLight[0], surplusTime[0]);
turnLeftLight.setTrafficLightStatus(laneLight[1], surplusTime[1]);
straightLight.setTrafficLightStatus(laneLight[2], surplusTime[2]);
turnRightLight.setTrafficLightStatus(laneLight[3], surplusTime[3]);
// todo 再根据当前所在车道,置灰不需关注的灯
}
/**
* 根据所在车道,控制红绿灯展示
*/
public void refreshLaneStatus(){
}
@Override

View File

@@ -0,0 +1,26 @@
package com.mogo.module.extensions.net;
import com.mogo.commons.data.BaseData;
import java.util.Map;
import io.reactivex.Observable;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
/**
* 时延验证相关接口
*
* @author tongchenfei
*/
public interface DelayCheckApiServices {
@GET("/")
Observable<BaseData> emptyInterface();
@POST("/")
@FormUrlEncoded
Observable<BaseData> uploadDelayCheckData(@FieldMap Map<String, String> params);
}

View File

@@ -21,6 +21,7 @@ import com.mogo.service.connection.IMogoOnWebSocketMessageListener;
import com.mogo.service.connection.WebSocketMsgType;
import com.mogo.utils.logger.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
/**
@@ -33,9 +34,9 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
private static final String TAG = "AdasNoticeHelper";
private static final int MSG_HIDE_TRAFFIC_LIGHT_BY_OBU = 1001;
private static final int MSG_HIDE_TRAFFIC_LIGHT_BY_CLOUD = 1002;
// private static final int MSG_HIDE_TRAFFIC_LIGHT_BY_CLOUD = 1002; 先去掉云端下发红绿灯信息
private static final int MSG_HIDE_LIMIT_SPEED = 1003;
private static final int MSG_REFRESH_CAR_STRATEGY = 1004;
// private static final int MSG_REFRESH_CAR_STRATEGY = 1004;
private static final long HIDE_TRAFFIC_LIGHT_DELAY = 2_000L;
private static final long HIDE_LIMIT_SPEED_DELAY = 10_000L;
@@ -53,23 +54,14 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
private VrModeNavInfoView vrModeNavInfoView;
private Handler handler = new Handler(this);
private boolean isObuLightData = false;
private boolean lightCenter = true;
private final Handler handler = new Handler(this);
public void init(Context context) {
this.context = context;
if (!lightCenter) {
}
Logger.d(TAG, "init====");
}
public void initView(VrModeNavInfoView vrModeNavInfoView) {
if (lightCenter) {
}
this.vrModeNavInfoView = vrModeNavInfoView;
}
@@ -84,10 +76,9 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
context.registerReceiver(adasReceiver, filter);
MogoApisHandler.getInstance().getApis().getAdasControllerApi().addAdasWarnMessageCallback(this);
MogoApisHandler.getInstance().getApis().getRegisterCenterApi().registerMogoLocationListener(TAG, this);
MogoApisHandler.getInstance().getApis().getWebSocketManagerApi(context).registerOnWebSocketMessageListener(this);
if (!lightCenter) {
handler.sendEmptyMessageDelayed(MSG_REFRESH_CAR_STRATEGY, STRATEGY_DELAY);
}
// 先不监听服务端下发消息
// MogoApisHandler.getInstance().getApis().getWebSocketManagerApi(context).registerOnWebSocketMessageListener(this);
}
}
@@ -96,11 +87,9 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
if (isVrMode) {
isVrMode = false;
MogoApisHandler.getInstance().getApis().getAdasControllerApi().showADAS();
handler.removeMessages(MSG_REFRESH_CAR_STRATEGY);
MogoApisHandler.getInstance().getApis().getAdasControllerApi().removeAdasWarnMessageCallback(this);
MogoApisHandler.getInstance().getApis().getRegisterCenterApi().unregisterMogoLocationListener(TAG);
MogoApisHandler.getInstance().getApis().getWebSocketManagerApi(context).unregisterOnWebSocketMessageListener(this);
// MogoApisHandler.getInstance().getApis().getWebSocketManagerApi(context).unregisterOnWebSocketMessageListener(this);
context.unregisterReceiver(adasReceiver);
}
}
@@ -129,44 +118,15 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
return;
}
currentSpeed = (int) (location.getSpeed() * 3.6F);
if (lightCenter) {
}
}
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_REFRESH_CAR_STRATEGY:
// todo 暂时不采用此种渲染方式
// 自车速度
// todo 设置字体颜色、背景颜色、leftDrawable
switch (lightStatus) {
case "Y":
// 黄灯
break;
case "R":
// 红灯
break;
default:
// 默认绿灯
break;
}
if (isVrMode) {
handler.sendEmptyMessageDelayed(MSG_REFRESH_CAR_STRATEGY, STRATEGY_DELAY);
}
return true;
case MSG_HIDE_LIMIT_SPEED:
limitSpeed = -1;
return true;
case MSG_HIDE_TRAFFIC_LIGHT_BY_CLOUD:
if (!isObuLightData && !handler.hasMessages(MSG_HIDE_TRAFFIC_LIGHT_BY_OBU)) {
}
return true;
case MSG_HIDE_TRAFFIC_LIGHT_BY_OBU:
isObuLightData = false;
if (!handler.hasMessages(MSG_HIDE_TRAFFIC_LIGHT_BY_CLOUD)) {
}
return true;
default:
return false;
@@ -209,7 +169,17 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
String lightStatus = jsonObject.optString("lightStatus");
String surplusTime = jsonObject.optString("surplusTime");
if (!lightStatus.isEmpty() && !surplusTime.isEmpty()) {
handleObuTrafficLightInfo(lightStatus, surplusTime);
// String strArray = jsonObject.getString("lightArray");
// Logger.d(TAG, "strArray: " + strArray);
JSONArray lightJsonArray = jsonObject.getJSONArray("lightArray");
JSONArray timeJsonArray = jsonObject.getJSONArray("surplusTimeArray");
int[] lightArray = new int[4];
String[] surplusTimeArray = new String[4];
for (int i = 0; i < 4; i++) {
lightArray[i] = lightJsonArray.getInt(i);
surplusTimeArray[i] = timeJsonArray.getString(i);
}
handleObuTrafficLightInfo(lightArray, surplusTimeArray);
} else {
Logger.d(TAG, "红绿灯必要信息都为空,不做展示");
}
@@ -224,22 +194,8 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
}
}
private void handleObuTrafficLightInfo(String lightStatus, String surplusTime) {
isObuLightData = true;
}
private void handleCloudTrafficLight(CloudRoadData roadData) {
if (isObuLightData) {
handler.removeMessages(MSG_HIDE_TRAFFIC_LIGHT_BY_CLOUD);
return;
}
}
private void drawTrafficLight(String lightStatus, String surplusTime) {
this.lightStatus = lightStatus;
this.surplusTime = surplusTime;
if (lightCenter) {
}
private void handleObuTrafficLightInfo(int[] lightArray,String[] surplusTimeArray) {
vrModeNavInfoView.refreshTrafficLightStatus(lightArray, surplusTimeArray);
}
@Override
@@ -254,14 +210,6 @@ public class AdasNoticeHelper implements IMogoAdasWarnMessageCallback, IMogoLoca
@Override
public void onMsgReceived(MogoSnapshotSetData obj) {
Logger.d(TAG, "收到大而全数据: " + obj);
CloudRoadData roadData = obj.getTrafficLight();
if (roadData != null) {
Logger.d(TAG, "收到红绿灯数据");
handleCloudTrafficLight(roadData);
} else {
handler.sendEmptyMessage(MSG_HIDE_TRAFFIC_LIGHT_BY_CLOUD);
}
}
}
}

View File

@@ -4,15 +4,20 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.map.marker.IMogoInfoWindowAdapter;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.drawer.marker.RoadConditionInfoWindow3DAdapter;
import com.mogo.module.common.entity.CloudRoadData;
import com.mogo.module.common.entity.MogoSnapshotSetData;
import com.mogo.module.extensions.R;
import com.mogo.module.extensions.live.CameraLiveManager;
import com.mogo.module.extensions.live.CameraWindow3DAdapter;
import com.mogo.module.extensions.live.ExtensionServiceManager;
import com.mogo.module.extensions.live.PushDataType;
import com.mogo.service.connection.IMogoOnWebSocketMessageListener;
@@ -23,28 +28,18 @@ import com.mogo.utils.logger.Logger;
/**
* vr模式下红绿灯消息 AdasNoticeHelper
*
*/
public class CameraLiveNoticeHelper implements IMogoOnWebSocketMessageListener<MogoSnapshotSetData> {
private static final String TAG = "liyz";
private Context mContext;
private static IMogoMarker mMogoMarker;
private CloudRoadData mCloudRoadData;
private boolean isFirst;
public void init(Context context) {
Logger.d(TAG, "init ======= ");
mContext = context;
//test
// UiThreadHandler.postDelayed( () -> {
// mCloudRoadData = new CloudRoadData();
// mCloudRoadData.setRtmpUrl("rtmp://58.200.131.2:1935/livetv/hunantv");
// mCloudRoadData.setLat(40.200353);
// mCloudRoadData.setLon(116.745467);
//// CameraLiveManager.getInstance().init(mCloudRoadData);
// addCameraMarker(mCloudRoadData);
// }, 2_000 );
}
public void enterVrMode() {
@@ -64,16 +59,35 @@ public class CameraLiveNoticeHelper implements IMogoOnWebSocketMessageListener<M
return false;
}
});
// if (!isFirst) {
// isFirst = true;
// UiThreadHandler.postDelayed(() -> {
// mCloudRoadData = new CloudRoadData();
//// mCloudRoadData.setRtmpUrl("rtmp://58.200.131.2:1935/livetv/hunantv");
// mCloudRoadData.setRtmpUrl("http://video.zhidaozhixing.com/live/rec_12_22.flv");
//
// mCloudRoadData.setLat(39.969089);
// mCloudRoadData.setLon(116.418009);
//
//// CameraLiveManager.getInstance().init(mCloudRoadData);
// addCameraMarker(mCloudRoadData);
// }, 2_000);
// }
}
public void exitVrMode() {
Logger.d(TAG, "退出vr模式===");
// removeCameraMarker();
// isFirst = false;
MogoApisHandler.getInstance().getApis().getWebSocketManagerApi(mContext).unregisterOnWebSocketMessageListener(this);
}
/**
* PushRoadConditionDrawer
*
* @param roadData
*/
private void addCameraMarker(CloudRoadData roadData) {
@@ -84,12 +98,13 @@ public class CameraLiveNoticeHelper implements IMogoOnWebSocketMessageListener<M
.longitude(roadData.getLon());
options.anchor(0.5f, 0.5f);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.module_camera_real_time_traffic, null);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_space, null);
options.icon(bitmap);
mMogoMarker = ExtensionServiceManager.getMapService().getMarkerManager(mContext)
.addMarker(PushDataType.TYPE_PUSH_CAMERA_DATA, options);
.addMarker(PushDataType.TYPE_PUSH_CAMERA_DATA, options);
if (mMogoMarker != null) {
mMogoMarker.setInfoWindowAdapter(new CameraWindow3DAdapter(AbsMogoApplication.getApp(), mMogoMarker.getMogoMarkerOptions()));
mMogoMarker.showInfoWindow();
mMogoMarker.setOwner(PushDataType.TYPE_PUSH_CAMERA_DATA);
}
}
@@ -114,18 +129,16 @@ public class CameraLiveNoticeHelper implements IMogoOnWebSocketMessageListener<M
private double mCurrentlon;
/**
*
* @param obj
*/
@Override
public void onMsgReceived(MogoSnapshotSetData obj) {
Logger.d(TAG, "onMsgReceived cameralive : " + obj);
// Logger.d(TAG, "onMsgReceived cameralive : " + obj);
if (obj != null) { //如果多个点,如何处理,点击的时候
mCloudRoadData = obj.getCamera();
if (mCloudRoadData != null) {
Log.d(TAG, "onMsgReceived getRtmpUrl = " + mCloudRoadData.getRtmpUrl());
Log.d(TAG, "mCurrentlat = " + mCurrentlat + "--mCurrentlon = " +mCurrentlon);
Log.d(TAG, "mCloudRoadData.getLat() = " + mCloudRoadData.getLat() + "--mCloudRoadData.getLon() = " + mCloudRoadData.getLon());
Log.d(TAG, "mCurrentlat = " + mCurrentlat + "--mCurrentlon = " + mCurrentlon + "---mCloudRoadData.getLat() = " + mCloudRoadData.getLat() + "--mCloudRoadData.getLon() = " + mCloudRoadData.getLon());
if (mCurrentlat == mCloudRoadData.getLat() && mCurrentlon == mCloudRoadData.getLon()) {
//TODO
} else {
@@ -136,10 +149,10 @@ public class CameraLiveNoticeHelper implements IMogoOnWebSocketMessageListener<M
}
} else {
//删除marker
Logger.e(TAG, "onMsgReceived mCloudRoadData == null " );
UiThreadHandler.postDelayed( () -> {
Logger.e(TAG, "onMsgReceived mCloudRoadData == null ");
UiThreadHandler.postDelayed(() -> {
removeCameraMarker();
}, 1_000 );
}, 1_000);
}
} else {
Log.e(TAG, "onMsgReceived obj == null ");

View File

@@ -0,0 +1,121 @@
package com.mogo.module.extensions.utils;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import com.mogo.commons.data.BaseData;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.extensions.net.DelayCheckApiServices;
import com.mogo.module.extensions.net.DztHttpConstant;
import com.mogo.utils.NetworkUtils;
import com.mogo.utils.network.RequestOptions;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.schedulers.Schedulers;
/**
* 延时验证工具类
*
* @author tongchenfei
*/
public class DelayCheckUtil implements Handler.Callback {
private final Handler handler = new Handler(this);
private static final int MSG_CHECK_NET_CONNECT_STATUS = 1001;
private static final long CHECK_NET_CONNECT_STATUS_DELAY = 5000L;
private static final int MSG_START_DELAY_CHECK = 1002;
private static final long DELAY_CHECK_DELAY = 10 * 60 * 1000;
private Context context;
public DelayCheckUtil(Context context) {
this.context = context;
}
/**
* 每5s检查一下网络状态网络状态为连接状态时开始空接口请求以及后续的参数上报
*/
public void waitingForCheck() {
handler.sendEmptyMessageDelayed(MSG_CHECK_NET_CONNECT_STATUS, CHECK_NET_CONNECT_STATUS_DELAY);
}
private long requestTime, netDelay;
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_CHECK_NET_CONNECT_STATUS:
if (NetworkUtils.isConnected(context)) {
handler.sendEmptyMessage(MSG_START_DELAY_CHECK);
} else {
handler.sendEmptyMessageDelayed(MSG_CHECK_NET_CONNECT_STATUS, CHECK_NET_CONNECT_STATUS_DELAY);
}
return true;
case MSG_START_DELAY_CHECK:
// 请求空接口
startEmptyRequest();
return true;
default:
return false;
}
}
private void startEmptyRequest() {
requestTime = SystemClock.elapsedRealtime();
MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(DelayCheckApiServices.class, DztHttpConstant.getBaseUrl())
.emptyInterface().subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
.subscribe(new SubscribeImpl<BaseData>(RequestOptions.create(context)) {
@Override
public void onSuccess(BaseData o) {
super.onSuccess(o);
netDelay = SystemClock.elapsedRealtime() - requestTime;
startUpload();
}
@Override
public void onError(Throwable e) {
super.onError(e);
}
@Override
public void onError(String message, int code) {
super.onError(message, code);
}
});
}
private void startUpload(){
Map<String, String> params = new HashMap<>();
MogoApisHandler.getInstance().getApis().getNetworkApi()
.create(DelayCheckApiServices.class, DztHttpConstant.getBaseUrl())
.uploadDelayCheckData(params).observeOn(Schedulers.io()).subscribeOn(Schedulers.io())
.subscribe(new SubscribeImpl<BaseData>(RequestOptions.create(context)) {
@Override
public void onSuccess(BaseData o) {
super.onSuccess(o);
handler.sendEmptyMessageDelayed(MSG_START_DELAY_CHECK, DELAY_CHECK_DELAY);
}
@Override
public void onError(String message, int code) {
super.onError(message, code);
}
@Override
public void onError(Throwable e) {
super.onError(e);
}
});
}
}

View File

@@ -13,12 +13,18 @@ import androidx.annotation.IntDef;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Group;
import com.mogo.module.common.constants.TrafficLightConst;
import com.mogo.module.extensions.R;
import com.mogo.utils.logger.Logger;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static com.mogo.module.common.constants.TrafficLightConst.TRAFFIC_LIGHT_COLOR_GRAY;
import static com.mogo.module.common.constants.TrafficLightConst.TRAFFIC_LIGHT_COLOR_GREEN;
import static com.mogo.module.common.constants.TrafficLightConst.TRAFFIC_LIGHT_COLOR_RED;
import static com.mogo.module.common.constants.TrafficLightConst.TRAFFIC_LIGHT_COLOR_YELLOW;
/**
* vr模式下的纵向显示的红绿灯封装
*
@@ -26,10 +32,6 @@ import java.lang.annotation.RetentionPolicy;
*/
public class VerticalTrafficLightView extends ConstraintLayout {
private static final String TAG = "VerticalTrafficLightView";
public static final int TRAFFIC_LIGHT_COLOR_GRAY = 0;
public static final int TRAFFIC_LIGHT_COLOR_RED = 1;
public static final int TRAFFIC_LIGHT_COLOR_YELLOW = 2;
public static final int TRAFFIC_LIGHT_COLOR_GREEN = 3;
private ImageView ivTrafficLight, ivNoLeftTime;
private TextView tvLeftTime, tvLeftTimeUnit;
@@ -90,7 +92,7 @@ public class VerticalTrafficLightView extends ConstraintLayout {
/**
* 设置红绿灯的颜色,根据颜色来展示不同的效果
*
* @param color 红绿灯颜色{@link #TRAFFIC_LIGHT_COLOR_GRAY},{@link #TRAFFIC_LIGHT_COLOR_RED}等四个颜色
* @param color 红绿灯颜色{@link TrafficLightConst#TRAFFIC_LIGHT_COLOR_GRAY},{@link TrafficLightConst#TRAFFIC_LIGHT_COLOR_RED}等四个颜色
*/
private void setTrafficLightColor(@TrafficLightColor int color) {
if (iconRes == null) {
@@ -123,7 +125,7 @@ public class VerticalTrafficLightView extends ConstraintLayout {
/**
* 设置红绿灯状态,需设置颜色及时长
*
* @param color 红绿灯颜色,使用{@link #TRAFFIC_LIGHT_COLOR_RED}等四个值
* @param color 红绿灯颜色,使用{@link TrafficLightConst#TRAFFIC_LIGHT_COLOR_RED}等四个值
* @param leftTime 剩余时长null或者empty表示没有时长数据
*/
public void setTrafficLightStatus(@TrafficLightColor int color, String leftTime) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

View File

@@ -0,0 +1,139 @@
<?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"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<View
android:id="@+id/debugPanelBg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#88000000" />
<ImageButton
android:id="@+id/ibDebugPanelClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:background="@drawable/module_common_close_selector"
app:layout_constraintRight_toRightOf="@id/debugPanelBg"
app:layout_constraintTop_toTopOf="@id/debugPanelBg" />
<TextView
android:id="@+id/tvLogSetTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:text="LOG SET"
android:textColor="#fff"
android:textSize="30sp"
app:layout_constraintLeft_toLeftOf="@id/debugPanelBg"
app:layout_constraintTop_toTopOf="@id/debugPanelBg" />
<Button
android:id="@+id/btnOpenLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="打开日志"
android:textColor="#fff"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="@id/tvLogSetTitle"
app:layout_constraintTop_toBottomOf="@id/tvLogSetTitle" />
<Button
android:id="@+id/btnCloseLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:text="关闭日志"
android:textColor="#fff"
android:textSize="20sp"
app:layout_constraintLeft_toRightOf="@id/btnOpenLog"
app:layout_constraintTop_toBottomOf="@id/tvLogSetTitle" />
<TextView
android:id="@+id/tvV2xSetTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="V2X SET"
android:textColor="#fff"
android:textSize="30sp"
app:layout_constraintLeft_toLeftOf="@id/tvLogSetTitle"
app:layout_constraintTop_toBottomOf="@id/btnOpenLog" />
<Button
android:id="@+id/btnOpenV2xPanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="打开V2X面板"
android:textColor="#fff"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="@id/tvV2xSetTitle"
app:layout_constraintTop_toBottomOf="@id/tvV2xSetTitle" />
<TextView
android:id="@+id/tvObuSetTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="OBU SET (设置完成后需要重启)"
android:textColor="#fff"
app:layout_constraintLeft_toLeftOf="@id/btnOpenV2xPanel"
app:layout_constraintTop_toBottomOf="@id/btnOpenV2xPanel"
android:textSize="30sp" />
<RadioGroup
android:id="@+id/rgObuSet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="horizontal"
app:layout_constraintLeft_toLeftOf="@id/tvObuSetTitle"
app:layout_constraintTop_toBottomOf="@id/tvObuSetTitle">
<RadioButton
android:id="@+id/rbCidiObu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="Cidi\n(北小营)"
android:textColor="#fff"
android:textSize="20sp" />
<Space
android:layout_width="20dp"
android:layout_height="wrap_content" />
<RadioButton
android:id="@+id/rbHualiObu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="华砺智行\n(苏州)"
android:textColor="#fff"
android:textSize="20sp" />
<Space
android:layout_width="20dp"
android:layout_height="wrap_content" />
<RadioButton
android:id="@+id/rbGoHighObu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="大唐高鸿\n(11.11国展)"
android:textColor="#fff"
android:textSize="20sp" />
</RadioGroup>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/groupDebugPanel"
android:visibility="gone"
app:constraint_referenced_ids="btnCloseLog,btnOpenLog,btnOpenV2xPanel,tvObuSetTitle,tvLogSetTitle,tvV2xSetTitle,rgObuSet,ibDebugPanelClose,debugPanelBg" />
</merge>

View File

@@ -39,7 +39,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/module_ext_navi_in_vr_speed_margin_start"
android:text="78"
android:text="--"
android:textColor="#fff"
android:textSize="@dimen/module_ext_navi_in_vr_speed_text_size"
app:layout_constraintBottom_toTopOf="@id/module_ext_id_navi_in_vr_traffic_bg"

View File

@@ -219,6 +219,7 @@
android:layout_marginBottom="@dimen/module_ext_enter_vr_mode_margin_bottom"
android:background="@drawable/module_ext_dw_upload_road_condition_bkg"
android:gravity="center"
android:visibility="gone"
android:text="VR"
android:textColor="#fff"
android:textSize="@dimen/module_ext_enter_vr_mode_text_size"
@@ -352,4 +353,9 @@
android:visibility="gone"
app:constraint_referenced_ids="etTimes,btnFix" />
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/include_debug_panel" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -295,4 +295,8 @@
android:visibility="gone"
app:constraint_referenced_ids="btnShowDrawableTipNoSize,btnShowDrawableTip,btnShowTextTip,btnDebugCtrlNaviView,btnDebugCtrlSubView,btnDebugCtrlTopView,btnDebugAddBottomLayerView" />
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/include_debug_panel" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -8,15 +8,15 @@
android:id="@+id/module_ext_id_weather_container"
android:layout_width="wrap_content"
android:layout_height="@dimen/module_ext_height"
android:layout_marginStart="@dimen/module_ext_weather_margin_start"
android:background="@drawable/module_ext_shadow_bkg"
android:gravity="center"
android:paddingStart="@dimen/module_ext_weather_container_paddingLeft"
android:paddingEnd="@dimen/module_ext_weather_container_paddingRight"
android:visibility="invisible"
app:layout_goneMarginLeft="@dimen/module_ext_notice_margin_start"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/module_ext_id_msg"
android:layout_marginStart="@dimen/module_ext_weather_margin_start"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginLeft="@dimen/module_ext_notice_margin_start"
tools:visibility="visible">
<ImageView
@@ -61,9 +61,9 @@
android:id="@+id/module_ext_id_msg_counter"
android:layout_width="@dimen/module_ext_msg_counter_width"
android:layout_height="@dimen/module_ext_msg_counter_height"
android:layout_alignParentRight="true"
android:background="@drawable/module_ext_drawable_msg_bkg"
android:gravity="center"
android:layout_alignParentRight="true"
android:textColor="#FFFFFF"
android:textSize="@dimen/module_ext_msg_counter_textSize"
tools:text="···" />
@@ -73,26 +73,35 @@
android:id="@+id/ivUserHeadBoard"
android:layout_width="@dimen/module_ext_user_avator_board_size"
android:layout_height="@dimen/module_ext_user_avator_board_size"
android:background="@drawable/model_ext_default_user_head_board"
android:layout_marginRight="@dimen/module_common_shadow_width_pos"
android:layout_marginTop="@dimen/module_common_shadow_width_pos"
android:layout_marginRight="@dimen/module_common_shadow_width_pos"
android:background="@drawable/model_ext_default_user_head_board"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/ivUserHeadImg"
android:layout_width="@dimen/module_ext_user_avator_size"
android:layout_height="@dimen/module_ext_user_avator_size"
android:src="@drawable/model_ext_default_user_head"
tools:visibility="visible"
app:layout_constraintBottom_toBottomOf="@id/ivUserHeadBoard"
app:layout_constraintLeft_toLeftOf="@id/ivUserHeadBoard"
app:layout_constraintTop_toTopOf="@id/ivUserHeadBoard"
app:layout_constraintRight_toRightOf="@id/ivUserHeadBoard"
app:layout_constraintBottom_toBottomOf="@id/ivUserHeadBoard"/>
app:layout_constraintTop_toTopOf="@id/ivUserHeadBoard"
tools:visibility="visible" />
<androidx.constraintlayout.widget.Group
android:id="@+id/groupUserHead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/groupUserHead"
app:constraint_referenced_ids="ivUserHeadBoard,ivUserHeadImg" />
<View
android:id="@+id/debugPanel"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="@dimen/dp_200"
android:background="#00000000"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</merge>

View File

@@ -214,8 +214,8 @@
<!-- 仅在vr模式下有此内容仅增加了xhdpi对应的大小 -->
<dimen name="module_ext_navi_in_vr_width">464px</dimen>
<dimen name="module_ext_navi_in_vr_height">304px</dimen>
<dimen name="module_ext_navi_in_vr_margin_start">20px</dimen>
<dimen name="module_ext_navi_in_vr_margin_top">8px</dimen>
<dimen name="module_ext_navi_in_vr_margin_start">40px</dimen>
<dimen name="module_ext_navi_in_vr_margin_top">28px</dimen>
<dimen name="module_ext_navi_in_vr_navi_icon_size">100px</dimen>
<dimen name="module_ext_navi_in_vr_next_info_txt_size">60px</dimen>
<dimen name="module_ext_navi_in_vr_next_info_unit_size">48px</dimen>

View File

@@ -34,6 +34,7 @@ import com.mogo.service.fragmentmanager.IMogoFragmentManager;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.skin.support.SkinMode;
import com.mogo.utils.NetworkUtils;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.logger.Logger;
import com.zhidao.adasconfig.api.AdasConfigApiController;
@@ -140,6 +141,8 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
super.onCreate( savedInstanceState );
ContextHolderUtil.holdContext(this);
mPresenter.postLoadModuleMsg();
NetworkUtils.listenNetStrength(this);
}
private void init() {

View File

@@ -26,6 +26,38 @@ import java.util.List;
public class Utils {
/**
* 将px值转换为dip或dp值保证尺寸大小不变
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 将dip或dp值转换为px值保证尺寸大小不变
*/
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
/**
* 将px值转换为sp值保证文字大小不变
*/
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 将sp值转换为px值保证文字大小不变
*/
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
/**
* 验证手机格式
*/

View File

@@ -0,0 +1,219 @@
package com.mogo.module.media.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import com.mogo.module.media.R;
import com.mogo.module.media.utils.Utils;
/**
* @author lixiaopeng
* @description
* @since 2020/12/15
*/
public class CircleNumberProgress extends View {
/** 进度条画笔的宽度dp */
private int paintProgressWidth = 4;
/** 文字百分比的字体大小sp */
private int paintTextSize = 20;
/** 未完成进度条的颜色 */
// private int paintUndoneColor = 0xffaaaaaa;
private int paintUndoneColor;
/** 已完成进度条的颜色 */
// private int paintDoneColor = 0xff67aae4;
private int paintDoneColor;
/** 百分比文字的颜色 */
private int paintTextColor = 0xffff0077;
/** 设置进度条画笔的宽度(px) */
private int paintProgressWidthPx;
/** 文字画笔的尺寸(px) */
private int paintTextSizePx;
/** Context上下文环境 */
private Context context;
/** 调用者设置的进程 0 - 100 */
private int progress;
/** 画未完成进度圆弧的画笔 */
private Paint paintUndone = new Paint();
/** 画已经完成进度条的画笔 */
private Paint paintDone = new Paint();
/** 画文字的画笔 */
// private Paint paintText = new Paint();
/** 包围进度条圆弧的矩形 */
private RectF rectF = new RectF();
/** 包围文字所在路径圆弧的矩形,比上一个矩形略小 */
private RectF rectF2 = new RectF();
/** 进度文字所在的路径 */
private Path path = new Path();
/** 文字所在路径圆弧的半径 */
private int radiusText;
/** 是否进行过了测量 */
private boolean isMeasured = false;
public CircleNumberProgress(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PercentageRing);
//中间圆的背景颜色 默认为浅紫色
paintUndoneColor = typedArray.getColor(R.styleable.PercentageRing_circleBackground, 0xffafb4db);
//外圆环的颜色 默认为深紫色
paintDoneColor = typedArray.getColor(R.styleable.PercentageRing_ringColor, 0xff6950a1);
// 构造器中初始化数据
initData();
}
/** 初始化数据 */
private void initData() {
// 设置进度条画笔的宽度
paintProgressWidthPx = Utils.dip2px(context, paintProgressWidth);
// 设置文字画笔的尺寸(px)
paintTextSizePx = Utils.sp2px(context, paintTextSize);
// 未完成进度圆环的画笔的属性
paintUndone.setColor(paintUndoneColor);
paintUndone.setStrokeWidth(paintProgressWidthPx);
paintUndone.setAntiAlias(true);
paintUndone.setStyle(Paint.Style.STROKE);
// 已经完成进度条的画笔的属性
paintDone.setColor(paintDoneColor);
paintDone.setStrokeWidth(paintProgressWidthPx);
paintDone.setAntiAlias(true);
paintDone.setStyle(Paint.Style.STROKE);
// 文字的画笔的属性
// paintText.setColor(paintTextColor);
// paintText.setTextSize(paintTextSizePx);
// paintText.setAntiAlias(true);
// paintText.setStyle(Paint.Style.STROKE);
// paintText.setTypeface(Typeface.DEFAULT_BOLD);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!isMeasured) {
getWidthAndHeight();
isMeasured = true;
}
}
/** 得到视图等的高度宽度尺寸数据 */
private void getWidthAndHeight() {
// 得到自定义视图的高度
int viewHeight;
// 得到自定义视图的宽度
int viewWidth;
// 得到自定义视图的X轴中心点
int viewCenterX;
// 得到自定义视图的Y轴中心点
int viewCenterY;
viewHeight = getMeasuredHeight();
viewWidth = getMeasuredWidth();
viewCenterX = viewWidth / 2;
viewCenterY = viewHeight / 2;
// 取本View长宽较小者的一半为整个圆环部分包括圆环和文字最外侧的半径
int minLenth = viewHeight > viewWidth ? viewWidth / 2 : viewHeight / 2;
// 比较文字高度和圆环宽度,如果文字高度较大,那么文字将突破圆环,否则,圆环会把文字包裹在内部
Rect rect = new Rect();
// paintText.getTextBounds("100%", 0, "100%".length(), rect);
int textHeight = rect.height();
// 得到圆环的中间半径(外径和内径平均值)
int radiusArc = minLenth - (paintProgressWidthPx > textHeight ? paintProgressWidthPx / 2 : textHeight / 2);
rectF.left = viewCenterX - radiusArc;
rectF.top = viewCenterY - radiusArc;
rectF.right = viewCenterX + radiusArc;
rectF.bottom = viewCenterY + radiusArc;
// 文字所依赖路径圆弧的半径
radiusText = radiusArc - textHeight / 2;
rectF2.left = viewCenterX - radiusText;
rectF2.top = viewCenterY - radiusText;
rectF2.right = viewCenterX + radiusText;
rectF2.bottom = viewCenterY + radiusText;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 画未完成进度的圆环
canvas.drawArc(rectF, 0, 360, false, paintUndone);
// 画已经完成进度的圆弧 从-90度开始即从圆环顶部开始
canvas.drawArc(rectF, -90, progress / 100.0f * 360, false, paintDone);
// 为文字所在路径添加一段圆弧轨迹进度为0%-9%时应该最短进度为10%-99%时应该边长进度为100%时应该最长
// 这样才能保证文字和圆弧的进度一致,不会出现超前或者滞后的情况
// 要画的文字
String text = progress + "%";
// 存储字符所有字符所占宽度的数组
float[] widths = new float[text.length()];
// 得到所有字符所占的宽度
// paintText.getTextWidths(text, 0, text.length(), widths);
// 所有字符所占宽度之和
float textWidth = 0;
for (float f : widths) {
textWidth += f;
}
// 根据长度得到路径对应的扫过的角度
// width = sweepAngle * 2 * π * R / 360 ; sweepAngle = width * 360 / 2 /
// π / R
float sweepAngle = (float) (textWidth * 360 / 2 / Math.PI / radiusText);
// 添加路径
path.addArc(rectF2, progress * 3.6f - 90.0f - sweepAngle / 2.0f, sweepAngle);
// 绘制进度的文字
// canvas.drawTextOnPath(text, path, 0, 0, paintText);
// 重置路径
path.reset();
}
/**
* @param progress 外部传进来的当前进度,强制重绘
*/
public void setProgress(int progress) {
this.progress = progress;
invalidate();
}
}

View File

@@ -26,6 +26,7 @@ import com.mogo.module.media.presenter.PresenterFactory;
import com.mogo.module.media.utils.Utils;
import com.mogo.module.media.view.IMusicView;
import com.mogo.module.media.widget.AnimCircleImageView;
import com.mogo.module.media.widget.CircleNumberProgress;
import com.mogo.module.media.widget.PercentageRingView;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
@@ -66,7 +67,7 @@ public class MediaWindow2 implements IMusicView , IMogoStatusChangedListener {
private boolean mIsCallChatWindowVisible;
private ICallProviderResponse mCallProviderResponse;
private PercentageRingView mPercentageRingView;
private CircleNumberProgress mPercentageRingView;
private ImageView mPauseImage;
private AnimCircleImageView mAnimCircleImageView;
@@ -312,10 +313,10 @@ public class MediaWindow2 implements IMusicView , IMogoStatusChangedListener {
GlideApp.with(mContext).asBitmap().apply(options).load(mMediaInfoData.getMediaImg()).into(new SkinAbleBitmapTarget(mAnimCircleImageView, options));
// GlideApp.with(mContext).applyDefaultRequestOptions(options).load(mMediaInfoData.getMediaImg()).into(new SkinAbleBitmapTarget(mCircleImg, options));
}else{
Logger.e(TAG, "mMediaInfoData == null ");
mAnimCircleImageView.setImageResource(R.drawable.module_media_default_music_img);
}
}
} else {
if (mScrollText != null) {
mScrollText.setText(mMediaInfoData.getMediaName());
@@ -344,7 +345,6 @@ public class MediaWindow2 implements IMusicView , IMogoStatusChangedListener {
if(mMediaInfoData!=null&&mMediaInfoData.getMediaImg()!=null&&!mMediaInfoData.getMediaImg().isEmpty()) {
int size =
mContext.getResources().getDimensionPixelSize(R.dimen.module_media_pop_window_anim_img_size);
Logger.d(TAG, "overload: " + size);
com.bumptech.glide.request.RequestOptions options =
new com.bumptech.glide.request.RequestOptions()
.placeholder(R.drawable.module_media_default_music_img).error(R.drawable.module_media_default_music_img).override(size, size);
@@ -458,8 +458,8 @@ public class MediaWindow2 implements IMusicView , IMogoStatusChangedListener {
(int) ((current * 1.0f * 100) / (total * 1.0f));
if (mPercentageRingView != null) {
mPercentageRingView.setVisibility(View.VISIBLE);
// Log.d(TAG, "progress vr = " + progress);
mPercentageRingView.setTargetPercent(progress);
Log.d(TAG, "progress vr = " + progress);
mPercentageRingView.setProgress(progress);
}
} catch (Exception e) {
e.printStackTrace();

View File

@@ -5,17 +5,28 @@
android:layout_width="@dimen/module_media_pop_window_size"
android:layout_height="@dimen/module_media_pop_window_size">
<com.mogo.module.media.widget.PercentageRingView
<com.mogo.module.media.widget.CircleNumberProgress
android:id="@+id/window_circle_bg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:circleBackground="@color/modules_media_music_bg_color"
app:radius="100"
app:ringColor="@color/modules_media_music_circle_color" />
app:ringColor="@color/modules_media_music_circle_color"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- <com.mogo.module.media.widget.PercentageRingView-->
<!-- android:id="@+id/window_circle_bg"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- app:circleBackground="@color/modules_media_music_bg_color"-->
<!-- app:radius="100"-->
<!-- app:ringColor="@color/modules_media_music_circle_color" />-->
<com.mogo.module.media.widget.AnimCircleImageView
android:id="@+id/window_circle_img_new"

View File

@@ -69,7 +69,7 @@
<dimen name="module_media_pop_window_inner_height">112px</dimen>
<dimen name="module_media_pop_window_inner_padding">30px</dimen>
<dimen name="module_media_pop_window_anim_img_size">80px</dimen>
<dimen name="module_media_pop_window_anim_img_size_new">90px</dimen>
<dimen name="module_media_pop_window_anim_img_size_new">101px</dimen>
<dimen name="module_media_pop_window_pause">60px</dimen>
<dimen name="module_media_pop_window_size">116px</dimen>
<dimen name="module_media_pop_window_text_width">230px</dimen>

View File

@@ -3,5 +3,5 @@
<color name="modules_media_music_title_text_color">#fff</color>
<color name="modules_media_music_time_text_color">#7affffff</color>
<color name="modules_media_music_bg_color">#444E6E</color>
<color name="modules_media_music_circle_color">#B63737</color>
<color name="modules_media_music_circle_color">#80ffffff</color>
</resources>

View File

@@ -70,7 +70,7 @@
<dimen name="module_media_pop_window_inner_height">60px</dimen>
<dimen name="module_media_pop_window_inner_padding">18px</dimen>
<dimen name="module_media_pop_window_anim_img_size">44px</dimen>
<dimen name="module_media_pop_window_anim_img_size_new">55px</dimen>
<dimen name="module_media_pop_window_anim_img_size_new">60px</dimen>
<dimen name="module_media_pop_window_pause">60px</dimen>
<dimen name="module_media_pop_window_text_width">123px</dimen>
<dimen name="module_media_pop_window_text_margin">10px</dimen>

View File

@@ -45,7 +45,7 @@ class MockUtil:Handler.Callback {
if (msg.what == 1001) {
Logger.d(TAG,"准备添加调试view")
val api = ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation(context) as IMogoServiceApis
api.windowManagerApi.addView(view, 1000, 600, false)
api.windowManagerApi.addView(view, 500, 300, false)
}
return false
}

View File

@@ -20,18 +20,22 @@ class ObuManager {
private lateinit var obu: IObu
private lateinit var context: Context
private var listener:IObuCallback? = null
fun init(context: Context) {
Logger.d(TAG, "init=======")
Logger.d(TAG, "init=======${DebugConfig.getObuType()}")
this.context = context
obu = if (DebugConfig.getObuType() == DebugConfig.OBU_TYPE_CIDI) {
CidiObu()
} else {
HualiObu()
obu = when (DebugConfig.getObuType()) {
DebugConfig.OBU_TYPE_CIDI -> CidiObu()
DebugConfig.OBU_TYPE_HUALI -> HualiObu()
else -> NetCarObu()
}
obu.init()
obu.init(context)
}
fun registerObuDataChangedListener(listener: IObuCallback?) {
this.listener = listener
if (listener != null) {
obu.registerObuCallback(listener)
if(DebugConfig.isUseMockObuData() ) {
@@ -41,5 +45,9 @@ class ObuManager {
}
}
fun resetObuType(obuType: Int) {
Logger.d(TAG, "resetObuType: $obuType")
obu.release()
}
}

View File

@@ -1,11 +1,16 @@
package com.zhidao.mogo.module.obu.obu
import android.content.Context
abstract class BaseObu : IObu {
var callback: IObuCallback? = null
override fun init() {
override fun init(context: Context) {
}
override fun registerObuCallback(callback: IObuCallback) {
this.callback = callback
}
override fun release() {
}
}

View File

@@ -1,5 +1,6 @@
package com.zhidao.mogo.module.obu.obu
import android.content.Context
import android.os.Handler
import android.os.Message
import com.mogo.commons.debug.DebugConfig
@@ -26,8 +27,8 @@ class CidiObu : BaseObu(), Handler.Callback, OnMessageReceiveListener {
}
private val handler = Handler(this)
override fun init() {
super.init()
override fun init(context: Context) {
super.init(context)
// 初始化sdk注册数据回调等信息
V2xController.getInstance().setMessageReceiveListener(this)
V2xController.getInstance().init()
@@ -120,4 +121,11 @@ class CidiObu : BaseObu(), Handler.Callback, OnMessageReceiveListener {
}
return false
}
override fun release() {
super.release()
handler.removeMessages(MSG_MONITOR_OBU_STATUS)
V2xController.getInstance().setMessageReceiveListener(null)
V2xController.getInstance().release()
}
}

View File

@@ -1,5 +1,6 @@
package com.zhidao.mogo.module.obu.obu
import android.content.Context
import android.os.Handler
import android.os.SystemClock
import android.util.ArrayMap
@@ -62,8 +63,8 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
private val handler = Handler()
override fun init() {
super.init()
override fun init(context: Context) {
super.init(context)
socketManager.connect(IP_ADDRESS, PORT)
Logger.d(TAG, "init")
}
@@ -308,4 +309,9 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
private fun convertTwoUnSignInt(byteArray: ByteArray): Int =
(byteArray[0].toInt() shl 24) or (byteArray[1].toInt() and 0xFF) or (byteArray[2].toInt() shl 8) or (byteArray[3].toInt() and 0xFF)
override fun release() {
super.release()
socketManager.release()
}
}

View File

@@ -1,5 +1,7 @@
package com.zhidao.mogo.module.obu.obu
import android.content.Context
/**
* Obu基本方法
* @author tongchenfei
@@ -8,11 +10,15 @@ interface IObu {
/**
* 初始化
*/
fun init()
fun init(context: Context)
/**
* 注册数据回调
*/
fun registerObuCallback(callback: IObuCallback)
/**
* release
*/
fun release()
}

View File

@@ -0,0 +1,236 @@
package com.zhidao.mogo.module.obu.obu
import android.content.Context
import android.os.Handler
import android.os.Message
import com.mogo.utils.logger.Logger
import com.mogo.utils.network.utils.GsonUtil
import com.zhidao.mogo.module.obu.ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY
import com.zhidao.mogo.module.obu.ObuConstant.TYPE_ROAD_USER_COLLISION_WARNING
import com.zhidao.mogo.module.obu.obu.bean.MogoObuEventInfo
import com.zhidao.mogo.module.obu.obu.bean.MogoObuTrafficLightInfo
import com.zhidao.mogo.module.obu.socket.IUdpSocketStatusCallback
import com.zhidao.mogo.module.obu.socket.UdpSocketManager
import org.json.JSONObject
/**
* 大唐高鸿obu
*
* @author tongchenfei
*/
class NetCarObu : BaseObu(), IUdpSocketStatusCallback, Handler.Callback {
companion object {
const val TAG = "NetCarObu"
const val MSG_SEND_ACTIVATION_MSG = 1001
const val MSG_RECONNECT = 1002
const val SEND_ACTIVATION_MSG_DELAY = 4 * 1000L
const val RECONNECT_DELAY = 10_000L
const val TARGET_IP = "192.168.118.104"
const val TARGET_PORT = 50500
}
private lateinit var socketManager: UdpSocketManager
private val handler = Handler(this)
override fun init(context: Context) {
super.init(context)
Logger.d(TAG, "NetCar obu init")
socketManager = UdpSocketManager(context = context, useDefaultAddress = true, callback = this)
}
override fun isReady() {
Logger.d(TAG, "udp is ready")
// 1. 向obu注册
sendRegisterMsg()
}
private var unique: String = ""
override fun onMessageReceived(msg: ByteArray) {
val response = String(msg)
val json = JSONObject(response)
Logger.d(TAG, "收到消息: $json")
when (json.optInt("tag")) {
1002 -> {
// 查询状态成功,准备注册
socketManager.defaultAddress?.let {
socketManager.sendMsgTo(GsonUtil.jsonFromObject(Request(2001, NcsRegisteredData(it.ip, it.port))), TARGET_IP, TARGET_PORT)
startReconnectTiming()
}
}
2002 -> {
// 响应注册
val rsp = json.optInt("rsp", -1)
if (rsp == 0) {
// 注册成功, 等待激活
unique = json.optString("unique", "")
startActivationTiming()
}
}
2004 -> {
// 响应解除注册
val rsp = json.optInt("rsp", -1)
if (rsp == 0) {
// 解除注册成功
socketManager.release()
}
}
2006 -> {
// 响应激活
val rsp = json.optInt("rsp", -1)
if (rsp != 0) {
// 激活失败,需要重新激活
sendActivationMsg()
} else {
// 激活成功,重新计时
startActivationTiming()
}
}
2104 -> {
// 红绿灯倒数秒数上报(车速引导)
val dataJson = json.optJSONObject("data")
if (dataJson != null) {
// val lightInfo = dataJson.optJSONObject("phase")
val lightInfoArray = dataJson.optJSONArray("phase")
if (lightInfoArray != null && lightInfoArray.length() > 0) {
Logger.d(TAG, "lightInfo: $lightInfoArray")
val lightInfo = lightInfoArray.getJSONObject(0)
val trafficLightInfo = MogoObuTrafficLightInfo()
val color = lightInfo.optInt("color")
if (color in 1..3) {
// 有效颜色数据
trafficLightInfo.lightStatus = when (color) {
2 -> "R"
3 -> "Y"
else -> "G"
}
trafficLightInfo.surplusTime = lightInfo.optInt("time", 0).toString()
callback?.onTrafficLightInfoCallback(trafficLightInfo)
// val end = lightInfo.optInt("guide_speed_max", -1)
// val start = lightInfo.optInt("guide_speed_min", -1)
// if (start != -1 && end != -1) {
// val eventInfo = MogoObuEventInfo()
// eventInfo.mogoEventId = TYPE_OPTIMAL_SPEED_ADVISORY
// eventInfo.describe = "前方路口,建议车速 $start 到 $end km/h"
// callback?.let {
// handler.post {
// it.onEventInfoCallback(eventInfo)
// }
// }
// }
}
} else {
Logger.e(TAG, "红绿灯数据为空")
}
} else {
Logger.e(TAG, "红绿灯数据为data空")
}
}
2105 -> {
// 事件上报
val event = json.optJSONObject("data")
if (event != null) {
val type = event.optInt("type", 0) % 100000
Logger.d(TAG, "事件id取模后: $type")
if (type == 4012) {
// 前方行人预警
val eventInfo = MogoObuEventInfo()
eventInfo.mogoEventId = TYPE_ROAD_USER_COLLISION_WARNING
handler.post {
callback?.onEventInfoCallback(eventInfo)
}
} else if (type == 3005) {
// 红绿灯变灯提醒
val eventInfo = MogoObuEventInfo()
eventInfo.type = "vip变灯提醒"
eventInfo.typeCode = "vip变灯提醒"
eventInfo.describe = "将为您变灯vip车辆可优先通行"
handler.post {
callback?.onEventInfoCallback(eventInfo)
}
}
} else {
Logger.e(TAG, "事件数据为空")
}
}
}
}
private fun sendRegisterMsg() {
socketManager.defaultAddress?.let {
socketManager.sendMsgTo(GsonUtil.jsonFromObject(Request<NcsRegisteredData>(2001, NcsRegisteredData(it.ip, it.port))), TARGET_IP, TARGET_PORT)
startReconnectTiming()
}
}
/**
* 开启激活计时
*/
private fun startActivationTiming() {
handler.removeMessages(MSG_SEND_ACTIVATION_MSG)
handler.removeMessages(MSG_RECONNECT)
handler.sendEmptyMessageDelayed(MSG_SEND_ACTIVATION_MSG, SEND_ACTIVATION_MSG_DELAY)
}
private fun startReconnectTiming() {
handler.removeMessages(MSG_RECONNECT)
handler.sendEmptyMessageDelayed(MSG_RECONNECT, RECONNECT_DELAY)
}
/**
* 发送激活数据
*/
private fun sendActivationMsg() {
Logger.d(TAG, "准备发送激活消息====")
socketManager.sendMsgTo(GsonUtil.jsonFromObject(NcsActivationRequest(unique = unique)), TARGET_IP, TARGET_PORT)
startReconnectTiming()
}
override fun handleMessage(msg: Message): Boolean {
return when (msg.what) {
MSG_SEND_ACTIVATION_MSG -> {
sendActivationMsg()
true
}
MSG_RECONNECT -> {
if (!handler.hasMessages(MSG_SEND_ACTIVATION_MSG)) {
// 没有等待激活,就进行重试
Logger.d(TAG, "准备重连===")
sendRegisterMsg()
}
true
}
else -> false
}
}
val firstMsg = "{\"tag\":1001}"
override fun release() {
super.release()
// 解除注册
socketManager.sendMsgTo(GsonUtil.jsonFromObject(NcsUnRegisteredRequest(unique = unique)), TARGET_IP, TARGET_PORT)
}
data class Request<T>(val tag: Int, val data: T)
/**
* 注册请求data
*/
data class NcsRegisteredData(val ip: String, val port: Int)
/**
* 解注册请求request
*/
data class NcsUnRegisteredRequest(val tag: Int = 2003, val unique: String)
/**
* 激活请求
*/
data class NcsActivationRequest(val tag: Int = 2005, val unique: String)
}

View File

@@ -1,5 +1,6 @@
package com.zhidao.mogo.module.obu.obu.bean
import com.mogo.module.common.constants.TrafficLightConst.*
import com.zhidao.smartv2x.model.obu.TrafficLightInfo
/**
@@ -10,20 +11,72 @@ import com.zhidao.smartv2x.model.obu.TrafficLightInfo
*
* @author tongchenfei
*/
class MogoObuTrafficLightInfo(){
var id:String? =null
var lightStatus:String? =null
var surplusTime:String? =null
var lightPriority:String? =null
override fun toString(): String {
return "MogoObuTrafficLightInfo(id=$id, lightStatus=$lightStatus, surplusTime=$surplusTime, lightPriority=$lightPriority)"
}
class MogoObuTrafficLightInfo() {
var id: String? = null
var lightStatus: String? = null
set(value) {
field = value
resetLightArray(value)
}
var surplusTime: String? = null
set(value) {
field = value
resetSurplusTimeArray(value)
}
var lightPriority: String? = null
constructor(info:TrafficLightInfo):this(){
var lightArray: IntArray = IntArray(4) { 0 }
var surplusTimeArray: Array<String> = Array(4) { "" }
constructor(info: TrafficLightInfo) : this() {
this.id = info.id
this.lightStatus = info.lightStatus
this.surplusTime = info.surplusTime
this.lightPriority = info.lightPriority
resetLightArray(lightStatus)
resetSurplusTimeArray(surplusTime)
}
override fun toString(): String {
return "MogoObuTrafficLightInfo(id=$id, lightStatus=$lightStatus, surplusTime=$surplusTime, lightPriority=$lightPriority, lightArray=${lightArray.contentToString()}, surplusTimeArray=${surplusTimeArray.contentToString()})"
}
private fun resetLightArray(lightStatus: String?) {
when (lightStatus) {
"R" -> {
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_AROUND] = TRAFFIC_LIGHT_COLOR_GREEN
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_LEFT] = TRAFFIC_LIGHT_COLOR_RED
lightArray[TRAFFIC_LIGHT_DIRECTION_STRAIGHT] = TRAFFIC_LIGHT_COLOR_RED
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_RIGHT] = TRAFFIC_LIGHT_COLOR_GREEN
}
"Y" -> {
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_AROUND] = TRAFFIC_LIGHT_COLOR_GREEN
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_LEFT] = TRAFFIC_LIGHT_COLOR_YELLOW
lightArray[TRAFFIC_LIGHT_DIRECTION_STRAIGHT] = TRAFFIC_LIGHT_COLOR_YELLOW
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_RIGHT] = TRAFFIC_LIGHT_COLOR_GREEN
}
"G" -> {
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_AROUND] = TRAFFIC_LIGHT_COLOR_GREEN
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_LEFT] = TRAFFIC_LIGHT_COLOR_GREEN
lightArray[TRAFFIC_LIGHT_DIRECTION_STRAIGHT] = TRAFFIC_LIGHT_COLOR_GREEN
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_RIGHT] = TRAFFIC_LIGHT_COLOR_GREEN
}
else -> {
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_AROUND] = TRAFFIC_LIGHT_COLOR_GRAY
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_LEFT] = TRAFFIC_LIGHT_COLOR_GRAY
lightArray[TRAFFIC_LIGHT_DIRECTION_STRAIGHT] = TRAFFIC_LIGHT_COLOR_GRAY
lightArray[TRAFFIC_LIGHT_DIRECTION_TURN_RIGHT] = TRAFFIC_LIGHT_COLOR_GRAY
}
}
}
private fun resetSurplusTimeArray(surplusTime: String?) {
surplusTimeArray[TRAFFIC_LIGHT_DIRECTION_TURN_AROUND] = ""
surplusTimeArray[TRAFFIC_LIGHT_DIRECTION_TURN_LEFT] = surplusTime ?: ""
surplusTimeArray[TRAFFIC_LIGHT_DIRECTION_STRAIGHT] = surplusTime ?: ""
surplusTimeArray[TRAFFIC_LIGHT_DIRECTION_TURN_RIGHT] = ""
}
}

View File

@@ -0,0 +1,13 @@
package com.zhidao.mogo.module.obu.socket
/**
* udp 数据回调
*/
interface ISocketMsgCallback {
/**
* udp过来的字节码数据目前已知数据类型就是ByteArray
*
* @param msg udp发过来的数据
*/
fun onMessageReceived(msg: ByteArray)
}

View File

@@ -0,0 +1,11 @@
package com.zhidao.mogo.module.obu.socket
/**
* udp状态回调
*/
interface IUdpSocketStatusCallback:ISocketMsgCallback {
/**
* udp连接准备完毕指的是准备好接收数据了
*/
fun isReady()
}

View File

@@ -72,4 +72,9 @@ class SimpleSocketManager(private val callback: IUdpSocketCallback? = null) {
fun sendMessage(msg: String) {
Logger.d(TAG, "暂不支持发送消息")
}
fun release(){
socket?.close()
dataCacheHandler.looper.quitSafely()
}
}

View File

@@ -1,9 +1,13 @@
package com.zhidao.mogo.module.obu.socket
import android.content.Context
import android.net.wifi.WifiManager
import android.os.Handler
import android.os.HandlerThread
import android.util.ArrayMap
import com.mogo.utils.NetworkUtils
import com.mogo.utils.logger.Logger
import java.lang.Thread.sleep
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
@@ -12,9 +16,11 @@ import java.util.concurrent.Executors
/**
* udp socket 管理类统一管理udp socket数据接收和发送
*/
class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
class UdpSocketManager(val context: Context? = null, useDefaultAddress: Boolean = false, private val callback: IUdpSocketStatusCallback? = null) {
companion object {
const val TAG = "Mogo-UdpSocketManager"
const val DEFAULT_PORT = 50501
const val DEFAULT_IP = "192.168.8.169"
}
private val socketMap = ArrayMap<SimpleAddress, DatagramSocket>()
@@ -23,20 +29,66 @@ class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
private val dataCacheThread = HandlerThread("obu-data-cache")
private val dataCacheHandler: Handler
var defaultAddress:SimpleAddress? = null
init {
dataCacheThread.start()
dataCacheHandler = Handler(dataCacheThread.looper)
if (useDefaultAddress) {
// 获取连接的wifi的ip地址
if (context == null) {
throw IllegalArgumentException("do not find context at constructor")
}else{
// defaultAddress = SimpleAddress(DEFAULT_IP, DEFAULT_PORT)
// receiveMsgFrom(DEFAULT_IP, DEFAULT_PORT)
if (NetworkUtils.isConnectedWifi(context)) {
// 已经判定连接到了wifi
generateDefaultAddress()
}else{
// 还没连接到wifi需要等待此处采用每隔一秒检查一次不用再注册相关监听广播
dataCacheHandler.post {
while (!NetworkUtils.isConnectedWifi(context)) {
sleep(1000)
}
// 已经连接到wifi
generateDefaultAddress()
}
}
}
}
}
@Volatile
private var isConnected = false
fun sendMsgTo(msg: String, ip: String, port: Int) {
Logger.d(TAG, "sendMsg: $msg to $ip:$port")
isConnected = true
val address = SimpleAddress(ip, port)
socketExecutor.execute(UdpSenderRunnable(address, msg))
}
/**
* 仅获取连接wifi后的ip地址使用默认端口进行数据接收
*/
private fun generateDefaultAddress(){
context?.let {
val wifiManager = it.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiInfo = wifiManager.connectionInfo
val ip = intIp2StringIp(wifiInfo.ipAddress)
Logger.d(TAG, "获取到本机ip地址: $ip")
defaultAddress = SimpleAddress(ip, DEFAULT_PORT)
// 生成了默认地址,开始准备接受数据
receiveMsgFrom(ip, DEFAULT_PORT)
}
}
private fun intIp2StringIp(ip: Int):String {
return "${ip and 0xff}.${(ip shr 8) and 0xff}.${(ip shr 16) and 0xff}.${(ip shr 24) and 0xff}"
}
private var isReady = false
fun receiveMsgFrom(ip: String, port: Int) {
isConnected = true
val address = SimpleAddress(ip, port)
@@ -78,6 +130,10 @@ class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
if (socket.isClosed) {
break
}
if (!isReady) {
isReady = true
callback?.isReady()
}
Logger.d(TAG, "准备接受消息====$address")
socket.receive(packet)
val msg = ByteArray(buffer.size)
@@ -91,4 +147,5 @@ class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
}
}

View File

@@ -11,6 +11,7 @@ import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.module.common.entity.CloudLocationInfo;
@@ -123,6 +124,8 @@ public class MogoRTKLocation {
cloudLocationInfo.setSystemTime(System.currentTimeMillis());
cloudLocationInfo.convertCoor2GCJ02();
cacheList.add(cloudLocationInfo);
} else {
Logger.e(TAG, "location == null");
}
}

View File

@@ -38,6 +38,9 @@ dependencies {
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.arouter
implementation rootProject.ext.dependencies.amapnavi3dmap
annotationProcessor rootProject.ext.dependencies.aroutercompiler
if (Boolean.valueOf(RELEASE)) {
api rootProject.ext.dependencies.mogomap

View File

@@ -6,6 +6,6 @@
<service
android:name=".SmallMapService"
android:exported="false"
android:process=":smallMap" />
/>
</application>
</manifest>

View File

@@ -8,9 +8,21 @@ import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CustomMapStyleOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.mogo.module.common.view.RoundLayout;
import com.mogo.module.small.map.animation.DirectionRotateAnimation;
import java.io.InputStream;
import java.net.URL;
/**
* 小地图的方向View
*
@@ -20,6 +32,12 @@ import com.mogo.module.small.map.animation.DirectionRotateAnimation;
public class SmallMapDirectionView extends RoundLayout {
private ImageView mIvMapBorder;
private TextureMapView mTextureMapView;
private AMap mAMap;
private UiSettings mUiSettings;
private CameraUpdate mCameraUpdate;
private MyLocationStyle myLocationStyle;
private DirectionRotateAnimation mRotateAnimation;
private int lastAngle = 0;
@@ -37,9 +55,46 @@ public class SmallMapDirectionView extends RoundLayout {
}
private void initView(Context context) {
mRotateAnimation = new DirectionRotateAnimation(context, null);
LayoutInflater.from(context).inflate(R.layout.module_small_map_view, this);
mIvMapBorder = findViewById(R.id.ivMapBorder);
mRotateAnimation = new DirectionRotateAnimation(context, null);
mTextureMapView = findViewById(R.id.textureMapView);
mTextureMapView.onCreate(null);
mAMap = mTextureMapView.getMap();
mAMap.setMapType(AMap.MAP_TYPE_NIGHT);//夜景地图aMap是地图控制器对象。
URL small_map_style = getClass().getResource("/assets/small_map_style.data");
URL small_map_style_extra = getClass().getResource("/assets/small_map_style_extra.data");
mAMap.setCustomMapStyle(new CustomMapStyleOptions()
.setEnable(true)
.setStyleDataPath(small_map_style.getPath())
.setStyleExtraPath(small_map_style_extra.getPath())
);
myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点定位点依照设备方向旋转并且会跟随设备移动。1秒1次定位如果不设置myLocationType默认也会执行此种模式。
myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
BitmapDescriptor location = BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_my_location_logo);
myLocationStyle.myLocationIcon(location);
mAMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
mAMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点false表示隐藏定位蓝点并不进行定位默认是false。
//设置希望展示的地图缩放级别
mCameraUpdate = CameraUpdateFactory.zoomTo(12);
mAMap.moveCamera(mCameraUpdate);
mUiSettings = mAMap.getUiSettings();
mUiSettings.setZoomControlsEnabled(false);// 地图缩放级别的交换按钮
// mUiSettings.setZoomGesturesEnabled(false);// 缩放手势
// mUiSettings.setScrollGesturesEnabled(false);// 滑动手势
// mUiSettings.setRotateGesturesEnabled(false);// 旋转手势
// mUiSettings.setTiltGesturesEnabled(false);// 倾斜手势
mUiSettings.setAllGesturesEnabled(false);// 所有手势
mUiSettings.setMyLocationButtonEnabled(false); // 显示默认的定位按钮
mUiSettings.setLogoBottomMargin(-150); //设置Logo下边界距离屏幕底部的边距,设置为负值即可
}

View File

@@ -32,7 +32,7 @@ public class SmallMapService extends Service {
public void onCreate() {
super.onCreate();
Logger.d(TAG, "onCreate");
addMachineVisionMapView();
addSmallMapView();
}
@Nullable
@@ -46,7 +46,7 @@ public class SmallMapService extends Service {
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
addMachineVisionMapView();
addSmallMapView();
Logger.d(TAG, "onRebind");
}
@@ -69,8 +69,8 @@ public class SmallMapService extends Service {
}
}
private void addMachineVisionMapView() {
Logger.d(TAG, "addMachineVisionMapView");
private void addSmallMapView() {
Logger.d(TAG, "addSmallMapView");
mWindowManagerView = new WindowManagerView.Builder(getApplicationContext())
.contentView(R.layout.module_small_map_direction_view)
@@ -79,8 +79,8 @@ public class SmallMapService extends Service {
WindowManager.LayoutParams.WRAP_CONTENT
)
.position(
getResources().getDimensionPixelOffset(R.dimen.module_mvision_view_x),
getResources().getDimensionPixelOffset(R.dimen.module_mvision_view_y)
getResources().getDimensionPixelOffset(R.dimen.module_small_map_view_x),
getResources().getDimensionPixelOffset(R.dimen.module_small_map_view_y)
)
.gravity(Gravity.TOP | Gravity.LEFT)
.showInWindowManager();

View File

@@ -1,35 +0,0 @@
package com.mogo.module.small.map;
import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import com.mogo.map.MogoBaseMapView;
import com.mogo.utils.logger.Logger;
/**
* @author donghongyu
* @date 12/10/20 1:35 PM
*/
public class SmallMapView extends MogoBaseMapView {
private static final String TAG = "SmallMapView";
public SmallMapView(Context context) {
this(context, null);
}
public SmallMapView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SmallMapView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void addMapView(Context context) {
Logger.d(TAG, "addMapView");
}
}

View File

@@ -73,15 +73,15 @@ public class SmallVisionProvider implements IMogoSmallMapProvider, IMogoStatusCh
@Override
public void showPanel() {
Log.d(TAG, "小地图模块触发展示……");
mSmallMapServiceIntent = new Intent(mContext, SmallMapService.class);
mContext.startService(mSmallMapServiceIntent);
if (MogoApisHandler.getInstance().getApis().getStatusManagerApi().isVrMode()) {
mSmallMapServiceIntent = new Intent(mContext, SmallMapService.class);
mContext.startService(mSmallMapServiceIntent);
}
}
@Override
public void hidePanel() {
Log.d(TAG, "小地图模块触发隐藏……");
if (mSmallMapServiceIntent != null) {
AbsMogoApplication.getApp().stopService(mSmallMapServiceIntent);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!---->
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<corners android:radius="720px" />
<gradient
android:angle="180"
android:endColor="#7997ff"
android:startColor="#284190"
android:type="linear"
android:useLevel="true" />
</shape>
</item>
<!-- 中心背景 -->
<item>
<shape android:shape="rectangle">
<solid android:color="#3F51B5" />
<corners android:radius="720px" />
</shape>
</item>
</layer-list>

View File

@@ -1,16 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.module.common.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rlSmallMapBorder"
android:layout_width="@dimen/module_mvision_view_width"
android:layout_height="@dimen/module_mvision_view_height"
android:layout_width="@dimen/module_small_map_border_view_width"
android:layout_height="@dimen/module_small_map_border_view_width"
app:roundLayoutRadius="360dp">
<View
android:layout_width="@dimen/module_small_map_view_border_width"
android:layout_height="@dimen/module_small_map_view_border_height"
android:layout_centerInParent="true"
android:background="@drawable/bg_module_small_map_view_border" />
<com.mogo.module.common.view.RoundLayout
android:id="@+id/rlSmallMapBorder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:roundLayoutRadius="360dp">
<com.amap.api.maps.TextureMapView
android:id="@+id/textureMapView"
android:layout_width="@dimen/module_small_map_view_width"
android:layout_height="@dimen/module_small_map_view_width" />
</com.mogo.module.common.view.RoundLayout>
<ImageView
android:id="@+id/ivMapBorder"
android:layout_width="@dimen/module_mvision_view_width"
android:layout_height="@dimen/module_mvision_view_height"
android:layout_width="@dimen/module_small_map_border_view_width"
android:layout_height="@dimen/module_small_map_border_view_width"
android:layout_centerInParent="true"
android:src="@drawable/module_small_map_view_border" />
</com.mogo.module.common.view.RoundLayout>
</RelativeLayout>

View File

@@ -1,12 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="module_mvision_view_width">400px</dimen>
<dimen name="module_mvision_view_height">400px</dimen>
<dimen name="module_mvision_view_x">1490px</dimen>
<dimen name="module_mvision_view_y">650px</dimen>
<dimen name="module_small_map_border_view_width">400px</dimen>
<dimen name="module_small_map_border_view_height">400px</dimen>
<dimen name="module_mvision_big_view_x">0px</dimen>
<dimen name="module_mvision_big_view_y">0px</dimen>
<dimen name="module_mvision_big_view_width">1920px</dimen>
<dimen name="module_mvision_big_view_height">1080px</dimen>
<dimen name="module_small_map_view_border_width">260px</dimen>
<dimen name="module_small_map_view_border_height">260px</dimen>
<dimen name="module_small_map_view_width">250px</dimen>
<dimen name="module_small_map_view_height">250px</dimen>
<dimen name="module_small_map_view_x">1490px</dimen>
<dimen name="module_small_map_view_y">650px</dimen>
<dimen name="module_small_map_big_view_x">0px</dimen>
<dimen name="module_small_map_big_view_y">0px</dimen>
<dimen name="module_small_map_big_view_width">1920px</dimen>
<dimen name="module_small_map_big_view_height">1080px</dimen>
</resources>

View File

@@ -1,7 +1,9 @@
package com.mogo.module.v2x;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
@@ -30,6 +32,7 @@ import com.zhidao.mogo.module.obu.obu.bean.MogoObuEventInfo;
import com.zhidao.mogo.module.obu.obu.bean.MogoObuLocationInfo;
import com.zhidao.mogo.module.obu.obu.bean.MogoObuTrafficLightInfo;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.Map;
@@ -66,19 +69,24 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
private static final int MSG_HIDE_TRAFFIC_LIGHT = 1001;
private static final long DEFAULT_HIDE_TRAFFIC_LIGHT_DELAY = 1500L;
private Handler handler = new Handler(this);
private final Handler handler = new Handler(this);
private final ObuTypeExchangeReceiver obuTypeExchangeReceiver = new ObuTypeExchangeReceiver();
private ObuManager obuManager;
public void init(Context context) {
Logger.d(MODULE_NAME, "obuManager初始化--");
ObuManager obuManager = new ObuManager();
obuManager = new ObuManager();
obuManager.init(context);
obuManager.registerObuDataChangedListener(this);
IntentFilter filter = new IntentFilter("com.mogo.launcher.v2x.action.EXCHANGE_OBU_TYPE");
context.registerReceiver(obuTypeExchangeReceiver, filter);
}
/**
* 用来处理30秒内不重复播报的情况
*/
private Map<String, Long> intervalMap = new ArrayMap<>();
private final Map<String, Long> intervalMap = new ArrayMap<>();
private int parseObuEvent(String type) {
switch (type) {
@@ -98,7 +106,7 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
}
}
private MogoLocation[] historyPath = new MogoLocation[2];
private final MogoLocation[] historyPath = new MogoLocation[2];
private float computeCarAngle(MogoLocation location) {
float angle = 0f;
@@ -142,6 +150,10 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
} else {
json.put("surplusTime", trafficLightInfo.getSurplusTime());
}
JSONArray lightJsonArray = new JSONArray(trafficLightInfo.getLightArray());
JSONArray surplusTimeJsonArray = new JSONArray(trafficLightInfo.getSurplusTimeArray());
json.put("lightArray", lightJsonArray);
json.put("surplusTimeArray", surplusTimeJsonArray);
}
String data = json.toString();
Logger.d(MODULE_NAME, "发送红绿灯广播: " + data);
@@ -172,7 +184,7 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
}
// int eventType = parseObuEvent(info.getTypeCode());
int eventType = info.getMogoEventId();
if (eventType == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY&& DebugConfig.getObuType() == DebugConfig.OBU_TYPE_CIDI) {
if (eventType == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY && DebugConfig.getObuType() == DebugConfig.OBU_TYPE_CIDI) {
// 加一个容错机制如果已经驶过绿波车速路口那么再收到绿波车速obu事件就不再上报
MogoLocation currentLocation = V2XLocationListener.getInstance().getLastCarLocation();
double eventAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
@@ -187,7 +199,7 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
return;
}
}
if (SystemClock.elapsedRealtime() - last > DEFAULT_INTERVAL_TIME||DebugConfig.getObuType() == DebugConfig.OBU_TYPE_HUALI) {
if (SystemClock.elapsedRealtime() - last > DEFAULT_INTERVAL_TIME || DebugConfig.getObuType() == DebugConfig.OBU_TYPE_HUALI) {
// 距离上次记录超过三十秒,继续相关逻辑,如果不超过三十秒,忽略此次事件
// 华砺智行obu暂时去掉此判断
intervalMap.put(info.getTypeCode(), SystemClock.elapsedRealtime());
@@ -249,17 +261,17 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
default:
break;
}
}else{
Logger.d(TAG,"未超过时限,不展示事件");
} else {
Logger.d(TAG, "未超过时限,不展示事件");
}
}
@Override
public void onLocationInfoCallback( MogoObuLocationInfo locationInfo) {
public void onLocationInfoCallback(MogoObuLocationInfo locationInfo) {
if (ObuConfig.useObuLocation) {
MogoLocation currentLocation = new MogoLocation();
double coor[] = CoordinateUtils.transformFromWGSToGCJ( locationInfo.getLat(), locationInfo.getLon() );
double coor[] = CoordinateUtils.transformFromWGSToGCJ(locationInfo.getLat(), locationInfo.getLon());
currentLocation.setLatitude(coor[0]);
currentLocation.setLongitude(coor[1]);
@@ -282,4 +294,12 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
sendTrafficLightStatusToAdas(CALL_ADAS_SHOW_TRAFFIC_LIGHT, trafficLightInfo);
}
}
class ObuTypeExchangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int obuType = intent.getIntExtra("obuType", DebugConfig.OBU_TYPE_CIDI);
obuManager.resetObuType(obuType);
}
}
}

View File

@@ -4,14 +4,17 @@ import android.content.Context;
import android.graphics.Bitmap;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.map.MogoLatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.map.uicontroller.EnumMapUI;
import com.mogo.module.common.drawer.MarkerDrawer;
import com.mogo.module.common.drawer.marker.IMarkerView;
import com.mogo.module.common.drawer.marker.MapMarkerAdapter;
import com.mogo.module.common.drawer.marker.RoadConditionInfoWindow3DAdapter;
import com.mogo.module.common.entity.MarkerCardResult;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerLocation;
@@ -532,6 +535,13 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager {
.longitude(roadEventEntity.getLocation().getLon());
optionsRipple.anchor(0.5f, 0.5f);
MarkerShowEntity markerShowEntity = new MarkerShowEntity();
MarkerExploreWay markerExploreWay = roadEventEntity.getNoveltyInfo();
markerShowEntity.setBindObj(markerExploreWay);
markerShowEntity.setMarkerLocation(markerExploreWay.getLocation());
markerShowEntity.setMarkerType(markerExploreWay.getPoiType());
markerShowEntity.setTextContent(markerExploreWay.getPoiType());
// 由于性能问题D车机不使用事件扩散动画
if (!CarSeries.isF8xxSeries()) {
optionsRipple.icon(V2XMarkerAdapter.getV2XRoadEventViewPng(context, roadEventEntity));
@@ -539,8 +549,13 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager {
optionsRipple.icons(V2XMarkerAdapter.getV2XRoadEventViewGif(context, roadEventEntity));
optionsRipple.period(1);
}
mAlarmInfoMarker = V2XServiceManager.getMarkerManager().addMarker(V2X_EVENT_ALARM_POI, optionsRipple);
if (V2XServiceManager.getMoGoStatusManager().isVrMode()) {
mAlarmInfoMarker = MarkerDrawer.getInstance().drawMapMarkerImpl(markerShowEntity, MarkerDrawer.MARKER_Z_INDEX_HIGH, clickListener);
mAlarmInfoMarker.setInfoWindowAdapter(new RoadConditionInfoWindow3DAdapter(markerShowEntity, AbsMogoApplication.getApp(), mAlarmInfoMarker.getMogoMarkerOptions()));
mAlarmInfoMarker.showInfoWindow();
} else {
mAlarmInfoMarker = V2XServiceManager.getMarkerManager().addMarker(V2X_EVENT_ALARM_POI, optionsRipple);
}
// 当前Marker设置为最上面
mAlarmInfoMarker.setToTop();
// 绘制连接线

View File

@@ -106,6 +106,9 @@ public class V2XAnimationWindow extends ConstraintLayout implements IV2XWindow<V
});
vvCarAnimation.start();
Logger.w(MODULE_NAME, "开始播放动画。。。。。");
if (mV2XWindowStatusListener != null) {
mV2XWindowStatusListener.onViewShow();
}
}
if (tts != null) {
AIAssist.getInstance(V2XServiceManager.getContext()).speakTTSVoice(tts);