Merge branch 'dev/dev_eagle_architecture_upgrade' into dev/dev_eagle_wuhan_sikua_obu

This commit is contained in:
董宏宇
2021-09-27 10:20:48 +08:00
211 changed files with 4149 additions and 1863 deletions

View File

@@ -29,14 +29,13 @@ import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public
/*
* @author congtaowang
* @since 2020/10/30
* <p>
* 描述
*/
class BaseDrawer {
/*
* @author congtaowang
* @since 2020/10/30
* <p>
* 描述
*/
public class BaseDrawer {
// 移除过期的 marker
public static final int MSG_REMOVE_DIRTY_MARKERS = 9990;

View File

@@ -5,13 +5,12 @@ import android.content.Context
import android.os.Handler
import android.os.Message
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.data.map.MogoLatLng
import com.mogo.map.marker.IMogoMarker
import com.mogo.map.marker.MogoMarkerOptions
import com.mogo.module.common.MogoApisHandler
import com.mogo.module.common.constants.DataTypes
import com.mogo.module.common.drawer.bean.TrafficData
import com.mogo.module.common.enums.TrafficTypeEnum
import com.mogo.eagle.core.data.traffic.TrafficData
import com.mogo.eagle.core.data.enums.TrafficTypeEnum
import com.mogo.utils.WorkThreadHandler
import com.mogo.utils.logger.Logger
import java.util.concurrent.ConcurrentHashMap

View File

@@ -1,77 +0,0 @@
package com.mogo.module.common.drawer.bean;
import com.mogo.module.common.enums.TrafficTypeEnum;
/**
* @author xiaoyuzhou
* @date 2021/8/17 8:41 下午
* 交通元素数据,
*/
public class TrafficData {
/**
* 交通元素类型, 车、人、摩托、大巴车、卡车、自行车
*/
public TrafficTypeEnum type;
/**
* 识别物体唯一标识
*/
public String uuid;
/**
* 识别物体的纬度
*/
public double lat;
/**
* 识别物体的经度
*/
public double lon;
/**
* 车头朝向
*/
public double heading;
/**
* 系统时间
*/
public long systemTime;
/**
* 定位卫星时间
*/
public long satelliteTime;
/**
* 海拔
*/
public double alt;
/**
* 速度
*/
public double speed;
/**
* 莫顿码
*/
public long mortonCode;
/**
* 实际距离
* 使用distanceX和distanceY计算
*/
public double distance;
/**
* 危险等级
* range(0..3)
* 0x00: 保留
* 0x01: 模型原始颜色
* 0x02: 通知 -- 黄
* 0x03: 警告 -- 红
*/
public int threatLevel;
}

View File

@@ -202,7 +202,7 @@ enum class EventTypeEnum(
"限速预警",
poiTypeSrcVr=R.drawable.icon_warning_v2x_over_speed,
content="已超速",
tts=""
tts="已超速"
),
TYPE_USECASE_ID_LTA(
ObuConstants.USE_CASE_ID.LTA.toString(),
@@ -223,7 +223,7 @@ enum class EventTypeEnum(
"车内标牌",
poiTypeSrcVr=R.drawable.icon_warning_v2x_road_construction,
content="前方施工",
tts=""
tts="前方施工"
),
TYPE_USECASE_ID_TJW(
ObuConstants.USE_CASE_ID.TJW.toString(),

View File

@@ -1,72 +0,0 @@
package com.mogo.module.common.enums
import com.mogo.module.common.R
/**
* @author xiaoyuzhou
* @date 2021/8/18 11:39 上午
* 交通元素类型
*/
enum class TrafficTypeEnum(
var type: Int,
var desc: String,
var traffic2DIconId: Int,
var traffic3DIconId: Int
) {
TYPE_TRAFFIC_ID_WEI_ZHI(
0,
"未知数据",
R.raw.special_vehicle,
R.raw.special_vehicle
),
TYPE_TRAFFIC_ID_PEOPLE(
1,
"",
R.raw.people,
R.raw.people
),
TYPE_TRAFFIC_ID_BICYCLE(
2,
"自行车",
R.raw.zixingche,
R.raw.zixingche
),
TYPE_TRAFFIC_ID_TA_CHE(
3,
"他车",
R.raw.special_vehicle,
R.raw.special_vehicle
),
TYPE_TRAFFIC_ID_MOTO(
4,
"摩托",
R.raw.motuoche,
R.raw.motuoche
),
TYPE_TRAFFIC_ID_BUS(
6,
"大巴",
R.raw.daba,
R.raw.daba
),
TYPE_TRAFFIC_ID_TRUCK(
8,
"卡车",
R.raw.daba,
R.raw.daba
),
TYPE_TRAFFIC_ID_SPECIAL_VEHICLE(
11,
"特殊车辆",
R.raw.special_vehicle,
R.raw.special_vehicle
),
TYPE_TRAFFIC_ID_DAO_LU_SHI_GONG(
12,
"道路施工",
R.raw.v2x_shigong_warning,
R.raw.v2x_shigong_warning
)
}

View File

@@ -1,337 +0,0 @@
package com.mogo.module.common.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.widget.ImageView;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import com.mogo.module.common.R;
@SuppressLint("AppCompatCustomView")
public class CustomCircleImageView extends ImageView {
private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 2;
private static final int DEFAULT_BORDER_WIDTH = 0;
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
private static final boolean DEFAULT_BORDER_OVERLAY = false;
private final RectF mDrawableRect = new RectF();
private final RectF mBorderRect = new RectF();
private final Matrix mShaderMatrix = new Matrix();
private final Paint mBitmapPaint = new Paint();
private final Paint mBorderPaint = new Paint();
private final Paint mFillPaint = new Paint();
private int mBorderColor = DEFAULT_BORDER_COLOR;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
private int mFillColor = DEFAULT_FILL_COLOR;
private Bitmap mBitmap;
private BitmapShader mBitmapShader;
private int mBitmapWidth;
private int mBitmapHeight;
private float mDrawableRadius;
private float mBorderRadius;
private ColorFilter mColorFilter;
private boolean mReady;
private boolean mSetupPending;
private boolean mBorderOverlay;
public CustomCircleImageView( Context context) {
super(context);
init();
}
public CustomCircleImageView( Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomCircleImageView( Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomCircleImageView, defStyle, 0);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CustomCircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getColor(R.styleable.CustomCircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
mBorderOverlay = a.getBoolean(R.styleable.CustomCircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
mFillColor = a.getColor(R.styleable.CustomCircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);
a.recycle();
init();
}
private void init() {
super.setScaleType(SCALE_TYPE);
mReady = true;
if (mSetupPending) {
setup();
mSetupPending = false;
}
}
@Override
public ScaleType getScaleType() {
return SCALE_TYPE;
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
}
@Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (adjustViewBounds) {
throw new IllegalArgumentException("adjustViewBounds not supported.");
}
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap == null) {
return;
}
if (mFillColor != Color.TRANSPARENT) {
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mFillPaint);
}
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mBitmapPaint);
if (mBorderWidth != 0) {
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mBorderRadius, mBorderPaint);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setup();
}
public int getBorderColor() {
return mBorderColor;
}
public void setBorderColor(@ColorInt int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public void setBorderColorResource(@ColorRes int borderColorRes) {
setBorderColor(getContext().getResources().getColor(borderColorRes));
}
public int getFillColor() {
return mFillColor;
}
public void setFillColor(@ColorInt int fillColor) {
if (fillColor == mFillColor) {
return;
}
mFillColor = fillColor;
mFillPaint.setColor(fillColor);
invalidate();
}
public void setFillColorResource(@ColorRes int fillColorRes) {
setFillColor(getContext().getResources().getColor(fillColorRes));
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth;
setup();
}
public boolean isBorderOverlay() {
return mBorderOverlay;
}
public void setBorderOverlay(boolean borderOverlay) {
if (borderOverlay == mBorderOverlay) {
return;
}
mBorderOverlay = borderOverlay;
setup();
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
mBitmap = bm;
setup();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap = getBitmapFromDrawable(drawable);
setup();
}
@Override
public void setImageResource(@DrawableRes int resId) {
super.setImageResource(resId);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null;
setup();
}
@Override
public void setColorFilter(ColorFilter cf) {
if (cf == mColorFilter) {
return;
}
mColorFilter = cf;
mBitmapPaint.setColorFilter(mColorFilter);
invalidate();
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
try {
Bitmap bitmap;
if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void setup() {
if (!mReady) {
mSetupPending = true;
return;
}
if (getWidth() == 0 && getHeight() == 0) {
return;
}
if (mBitmap == null) {
invalidate();
return;
}
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
mFillPaint.setStyle(Paint.Style.FILL);
mFillPaint.setAntiAlias(true);
mFillPaint.setColor(mFillColor);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
mBorderRect.set(0, 0, getWidth(), getHeight());
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
mDrawableRect.set(mBorderRect);
if (!mBorderOverlay) {
mDrawableRect.inset(mBorderWidth, mBorderWidth);
}
mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
updateShaderMatrix();
invalidate();
}
private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;
mShaderMatrix.set(null);
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}

View File

@@ -7,12 +7,7 @@
</attr>
</declare-styleable>
<declare-styleable name="CustomCircleImageView">
<attr name="civ_border_width" format="dimension" />
<attr name="civ_border_color" format="color" />
<attr name="civ_border_overlay" format="boolean" />
<attr name="civ_fill_color" format="color" />
</declare-styleable>
<declare-styleable name="CustomRatingBar">
<!---->
<attr name="elenmentWidth" format="dimension" />

View File

@@ -1,5 +1,20 @@
package com.mogo.module.extensions.entrance;
import static com.mogo.module.common.utils.SPConst.getSPGuideRecord;
import static com.mogo.module.common.utils.SPConst.getSpGuide;
import static com.mogo.module.extensions.ExtensionsModuleConst.TYPE_ENTRANCE;
import static com.mogo.module.service.receiver.MogoReceiver.ACTION_V2X_REMOVE_TIP_WINDOW;
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_BUTTON;
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_TIME;
import static com.mogo.module.share.constant.ShareConstants.KEY_SERVER_SHOW_DAY_COUNT;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE_TIME;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE_TIME;
import static com.mogo.module.share.constant.ShareConstants.ONE_DAY_TIME;
import static com.mogo.module.share.constant.ShareConstants.SEVEN_DAY_TIME;
import static com.mogo.module.share.constant.ShareConstants.VOICE_ALERT_COUNT;
import android.content.Intent;
import android.graphics.Rect;
import android.location.Location;
@@ -14,7 +29,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
@@ -72,8 +86,6 @@ import com.mogo.module.extensions.utils.TopViewNoLinkageAnimHelper;
import com.mogo.module.service.receiver.MogoReceiver;
import com.mogo.module.share.manager.ServiceApisManager;
import com.mogo.service.IMogoServiceApis;
import com.mogo.service.adas.IMogoAdasOCHCallback;
import com.mogo.service.adas.entity.AdasOCHData;
import com.mogo.service.analytics.IMogoAnalytics;
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
import com.mogo.service.entrance.ButtonIndex;
@@ -101,21 +113,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Random;
import static com.mogo.module.common.utils.SPConst.getSPGuideRecord;
import static com.mogo.module.common.utils.SPConst.getSpGuide;
import static com.mogo.module.extensions.ExtensionsModuleConst.TYPE_ENTRANCE;
import static com.mogo.module.service.receiver.MogoReceiver.ACTION_V2X_REMOVE_TIP_WINDOW;
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_BUTTON;
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_TIME;
import static com.mogo.module.share.constant.ShareConstants.KEY_SERVER_SHOW_DAY_COUNT;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE_TIME;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE;
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE_TIME;
import static com.mogo.module.share.constant.ShareConstants.ONE_DAY_TIME;
import static com.mogo.module.share.constant.ShareConstants.SEVEN_DAY_TIME;
import static com.mogo.module.share.constant.ShareConstants.VOICE_ALERT_COUNT;
/**
* @author congtaowang
* @since 2020-01-07
@@ -129,9 +126,8 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
IMogoAimlessModeListener,
IMogoStatusChangedListener,
IMogoIntentListener,
// IMogoLocationListener,
IMogoCheckListener ,
IMogoAdasOCHCallback,
// IMogoLocationListener,
IMogoCheckListener,
IMogoCarLocationChangedListener2 {
private static final String TAG = "EntranceFragment";
@@ -215,7 +211,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
private TextView tvRed;
private TextView tvGreen;
private CheckedTextView ctvAutopilotStatus;
// private CheckedTextView ctvAutopilotStatus;
/**
* 内部变量标识是否在vrMode用于方法执行过滤避免重复或异常调用
@@ -285,7 +281,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
mMove2CurrentLocation = findViewById(R.id.module_entrance_id_move2_current_location);
mUserHeadImg = findViewById(R.id.ivUserHeadImg);
groupFix = findViewById(R.id.groupFix);
ctvAutopilotStatus = findViewById(R.id.module_mogo_autopilot_status);
// ctvAutopilotStatus = findViewById(R.id.module_mogo_autopilot_status);
ConstraintLayout rootView = findViewById(R.id.module_entrance_id_top_motion_layout);
if (rootView != null) {
@@ -356,16 +352,14 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
});
}
onAutopilotStatusChanged(
MogoApisHandler.getInstance().getApis().getAdasControllerApi().getAutopilotStatus() == IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING);
ctvAutopilotStatus.setOnClickListener(new OnPreventFastClickListener() {
@Override
public void onClickImpl(View v) {
// 如果能自动驾驶,就自动驾驶,不能就提示
autopilotStatusClick();
}
});
// ctvAutopilotStatus.setOnClickListener(new OnPreventFastClickListener() {
// @Override
// public void onClickImpl(View v) {
// // 如果能自动驾驶,就自动驾驶,不能就提示
// autopilotStatusClick();
// }
// });
dealWeatherContainer();
@@ -400,7 +394,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
enterVrMode();
localIsVrMode = true;
}
// //检测入口
// //检测入口
jumpCheck = findViewById(R.id.module_ext_enter_check);
tipImageView = findViewById(R.id.error_tip_image);
jumpCheck.setOnClickListener(new View.OnClickListener() {
@@ -414,21 +408,6 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
}
/**
* 自动驾驶状态改变
*
* @param isInAutopilot true - 在自动驾驶中 false - 不在自动驾驶中
*/
public void onAutopilotStatusChanged(boolean isInAutopilot) {
getActivity().runOnUiThread(() -> {
ctvAutopilotStatus.setChecked(isInAutopilot);
});
}
private void autopilotStatusClick() {
EntranceViewHolder.getInstance().entranceAutopilotStatusClick();
}
private int debugPanelClickCount = 0;
private long lastDebugPanelClickTime = 0;
@@ -443,8 +422,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
mMsgContainer.setVisibility(View.GONE);
groupUserHead.setVisibility(View.GONE);
groupUserHead.setVisibility(View.GONE);
ctvAutopilotStatus.setVisibility(View.VISIBLE);
// tvExitVrMode.setVisibility(View.VISIBLE);
// tvExitVrMode.setVisibility(View.VISIBLE);
TopViewAnimHelper.getInstance().enterVrMode();
TopViewNoLinkageAnimHelper.getInstance().enterVrMode();
mNaviInfo = vrModeNavInfoView;
@@ -586,7 +564,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
if (intervalTime == 0) {
SharedPrefsMgr.getInstance(getContext()).putLong(KEY_SHARE_OUTER_GUIDE_TIME, time);
SharedPrefsMgr.getInstance(getContext()).putInt(KEY_SHARE_OUTER_GUIDE, ++shareItemSum);
// AIAssist.getInstance(getContext()).speakTTSVoice(mOuterGuideVoiceStrings[random.nextInt(3)]);
// AIAssist.getInstance(getContext()).speakTTSVoice(mOuterGuideVoiceStrings[random.nextInt(3)]);
AIAssist.getInstance(getContext()).speakTTSVoice(mOuterGuideVoiceStrings[0]);
} else {
Logger.d(TAG, " playShareOuterGuideVoice else interval = " + (time - intervalTime));
@@ -745,7 +723,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
mMogoRegisterCenter.registerMogoNaviListener(TYPE_ENTRANCE, this);
mMogoRegisterCenter.registerMogoMapListener(TYPE_ENTRANCE, this);
//车辆监控
//车辆监控
CallerCheckManager.registerVehicleMonitoringListener(MogoReceiver.ACTION_CHECK_VEHICLE_MONITORING, this);
mMogoMarkerManager = mService.getMarkerManager(getContext());
@@ -885,15 +863,15 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
} else {
mExitNavi.setText(R.string.module_ext_str_continue_navi);
}
// if ( isLock ) {
// if ( mMApUIController.getCurrentUiMode() == EnumMapUI.CarUp_2D ) {
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
// } else {
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
// }
// } else {
// mMove2CurrentLocation.setImageResource( R.drawable.module_map_ic_move2_current_location );
// }
// if ( isLock ) {
// if ( mMApUIController.getCurrentUiMode() == EnumMapUI.CarUp_2D ) {
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
// } else {
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
// }
// } else {
// mMove2CurrentLocation.setImageResource( R.drawable.module_map_ic_move2_current_location );
// }
}
private void traceData(String from) {
@@ -1008,14 +986,14 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
private void debugTopView() {
findViewById(R.id.btnDebugCtrlNaviView).setOnClickListener(view -> {
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
// MyLocationUtil.setMyLocationIconUrl(getContext(), "https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
// MyLocationUtil.setMyLocationIconUrl(getContext(), "https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
if (!toggle) {
TopViewAnimHelper.getInstance().showNaviView();
} else {
@@ -1025,7 +1003,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
});
findViewById(R.id.btnDebugCtrlSubView).setOnClickListener(view -> {
// MyLocationUtil.emphasizeMyLocation();
// MyLocationUtil.emphasizeMyLocation();
View v = LayoutInflater.from(getContext()).inflate(R.layout.demo_top, null);
TextView tv = v.findViewById(R.id.tvIndex);
tv.setText("sub view height: " + currentHeight + ": " + v);
@@ -1053,17 +1031,17 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
});
findViewById(R.id.btnDebugCtrlTopView).setOnClickListener(view -> {
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
// ".1000_0.jpeg");
// MyLocationUtil.setMyLocationIconUrl(getContext(),"https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
// ".1000_0.jpeg");
// MyLocationUtil.emphasizeMyLocation();
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
// ".1000_0.jpeg");
// MyLocationUtil.setMyLocationIconUrl(getContext(),"https" +
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
// ".1000_0.jpeg");
// MyLocationUtil.emphasizeMyLocation();
View v = LayoutInflater.from(getContext()).inflate(R.layout.demo_top, null);
TextView tv = v.findViewById(R.id.tvIndex);
Random random = new Random();
@@ -1071,7 +1049,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
tv.setText(" height: " + currentHeight + ": " + v);
ViewGroup.LayoutParams params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, currentHeight);
// mApis.getEntranceButtonController().addLeftFeatureView(v);
// mApis.getEntranceButtonController().addLeftFeatureView(v);
mApis.getTopViewManager().addView(v, params, new IMogoTopViewStatusListener() {
@Override
@@ -1114,12 +1092,12 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
mMsgContainer.setVisibility(View.GONE);
// String enthusiasmIndex = "一般的字加粗的字一般的字";
// SpannableString spannableStringUnSelectCountStr = new SpannableString(enthusiasmIndex);
// ForegroundColorSpan foregroundColorSpanUnSelectCount = new ForegroundColorSpan(Color.RED);
// spannableStringUnSelectCountStr.setSpan(foregroundColorSpanUnSelectCount, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//
// TipToast.tip(spannableStringUnSelectCountStr.toString());
// String enthusiasmIndex = "一般的字加粗的字一般的字";
// SpannableString spannableStringUnSelectCountStr = new SpannableString(enthusiasmIndex);
// ForegroundColorSpan foregroundColorSpanUnSelectCount = new ForegroundColorSpan(Color.RED);
// spannableStringUnSelectCountStr.setSpan(foregroundColorSpanUnSelectCount, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//
// TipToast.tip(spannableStringUnSelectCountStr.toString());
TipDrawable drawable =
new TipDrawable(getResources().getDrawable(R.drawable.model_ext_default_user_head));
TipToast.tip("分享成功", drawable);
@@ -1136,11 +1114,11 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
mCameraMode.setSelected(ui == EnumMapUI.NorthUP_2D);
mCameraMode.setText(getString(ui == EnumMapUI.NorthUP_2D ? R.string.mode_car_up : R.string.mode_north_up));
// if ( ui == EnumMapUI.CarUp_2D ) {
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
// } else if( ui == EnumMapUI.NorthUP_2D ){
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
// }
// if ( ui == EnumMapUI.CarUp_2D ) {
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
// } else if( ui == EnumMapUI.NorthUP_2D ){
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
// }
}
@@ -1424,20 +1402,13 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
}
@Override
public void updateMonitoringStatus(boolean hasError){
Log.d(TAG,"updateCheckStatus");
if(hasError==true){
tipImageView.setVisibility(View.VISIBLE);
}else{
tipImageView.setVisibility(View.INVISIBLE);
public void updateMonitoringStatus(boolean hasError) {
Log.d(TAG, "updateCheckStatus");
if (hasError == true) {
tipImageView.setVisibility(View.VISIBLE);
} else {
tipImageView.setVisibility(View.INVISIBLE);
}
}
public void onArriveAt(AdasOCHData data) {
}
@Override
public void onStateChanged(int state, String reason) {
ctvAutopilotStatus.setChecked(state == IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING);
}
}

View File

@@ -8,7 +8,6 @@ import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.module.extensions.utils.EntranceViewHolder;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.entrance.ButtonIndex;
import com.mogo.service.entrance.IMogoEntranceAutopilotStatusClickListener;
import com.mogo.service.entrance.IMogoEntranceButtonController;
import com.mogo.service.windowview.IMogoEntranceViewListener;
@@ -71,16 +70,6 @@ public class MogoEntranceButtonControllerImpl implements IMogoEntranceButtonCont
EntranceViewHolder.getInstance().removeEntranceViewListener(listener);
}
@Override
public void addEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
EntranceViewHolder.getInstance().addEntranceAutopilotStatusClickListener(listener);
}
@Override
public void removeEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
EntranceViewHolder.getInstance().removeEntranceAutopilotStatusClickListener(listener);
}
@Override
public void init( Context context ) {

View File

@@ -13,7 +13,7 @@ import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import com.mogo.eagle.core.view.LiveRoundLayout;
import com.mogo.eagle.core.widget.LiveRoundLayout;
import com.mogo.module.extensions.R;
import com.mogo.utils.logger.Logger;
import com.tencent.rtmp.ITXLivePlayListener;

View File

@@ -12,7 +12,6 @@ import android.widget.TextView;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.extensions.R;
import com.mogo.module.extensions.bean.BottomLayerViewWrapper;
import com.mogo.service.entrance.IMogoEntranceAutopilotStatusClickListener;
import com.mogo.service.windowview.IMogoEntranceViewListener;
import com.mogo.utils.logger.Logger;
@@ -133,7 +132,7 @@ public class EntranceViewHolder {
View v = wrapper.getView();
v.setLayoutParams(params);
rootViewGroup.addView(v, 0);
// rootViewGroup.setBackgroundColor(Color.WHITE);
// rootViewGroup.setBackgroundColor(Color.WHITE);
}
public void removeBottomLayerView(View view) {
@@ -270,7 +269,6 @@ public class EntranceViewHolder {
}
private final List<IMogoEntranceViewListener> listeners = new ArrayList<>();
private final List<IMogoEntranceAutopilotStatusClickListener> btnClickListeners = new ArrayList<>();
public void addEntranceViewListener(IMogoEntranceViewListener listener) {
listeners.add(listener);
@@ -280,20 +278,6 @@ public class EntranceViewHolder {
listeners.remove(listener);
}
public void addEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
btnClickListeners.add(listener);
}
public void removeEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
btnClickListeners.remove(listener);
}
public void entranceAutopilotStatusClick() {
for (IMogoEntranceAutopilotStatusClickListener listener : btnClickListeners) {
listener.click();
}
}
public void release() {
rootViewGroup = null;
featureViewGroup = null;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<shape android:shape="rectangle">
<corners android:bottomLeftRadius="20px" android:bottomRightRadius="45px" android:topLeftRadius="45px" android:topRightRadius="20px" />
<gradient android:angle="315" android:endColor="#2B6EFF" android:startColor="#2B6EFF" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:bottomLeftRadius="20px" android:bottomRightRadius="45px" android:topLeftRadius="45px" android:topRightRadius="20px" />
<gradient android:angle="315" android:endColor="#3B4577" android:startColor="#3B4577" />
</shape>
</item>
</selector>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.view.LiveRoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.mogo.eagle.core.widget.LiveRoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -65,4 +65,4 @@
app:layout_constraintTop_toBottomOf="@+id/ivErrorIcon" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.mogo.eagle.core.view.LiveRoundLayout>
</com.mogo.eagle.core.widget.LiveRoundLayout>

View File

@@ -6,27 +6,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckedTextView
android:id="@+id/module_mogo_autopilot_status"
android:layout_width="@dimen/module_mogo_autopilot_status_bg_width"
android:layout_height="@dimen/module_mogo_autopilot_status_bg_height"
android:layout_marginLeft="@dimen/module_mogo_autopilot_status_margin_left"
android:layout_marginTop="@dimen/module_mogo_autopilot_status_margin_top"
android:background="@drawable/module_mogo_autopilot_status_bg"
android:drawableLeft="@drawable/module_ext_ic_autopilot"
android:drawablePadding="@dimen/dp_30"
android:elevation="@dimen/dp_10"
android:gravity="center_vertical"
android:visibility="gone"
android:paddingLeft="@dimen/module_mogo_autopilot_status_padding"
android:text="自动驾驶"
android:textColor="#FFFFFF"
android:textSize="@dimen/module_mogo_autopilot_status_text_size"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<include
layout="@layout/module_ext_layout_extensions"
android:layout_width="match_parent"
@@ -359,6 +338,7 @@
android:id="@+id/error_tip_image"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_40"
android:visibility="invisible"
android:src="@drawable/check_error_image"
app:layout_constraintRight_toRightOf="@+id/module_ext_enter_check"
app:layout_constraintTop_toTopOf="@+id/module_ext_enter_check" />

View File

@@ -9,10 +9,5 @@
<dimen name="module_switch_image">50px</dimen>
<dimen name="module_switch_image_circle">60px</dimen>
<dimen name="module_mogo_autopilot_status_bg_width">460px</dimen>
<dimen name="module_mogo_autopilot_status_bg_height">140px</dimen>
<dimen name="module_mogo_autopilot_status_margin_left">20px</dimen>
<dimen name="module_mogo_autopilot_status_margin_top">530px</dimen>
<dimen name="module_mogo_autopilot_status_padding">92px</dimen>
<dimen name="module_mogo_autopilot_status_text_size">44px</dimen>
</resources>

View File

@@ -251,11 +251,5 @@
<dimen name="module_switch_image">35px</dimen>
<dimen name="module_switch_image_circle">38px</dimen>
<dimen name="module_mogo_autopilot_status_bg_width">300px</dimen>
<dimen name="module_mogo_autopilot_status_bg_height">100px</dimen>
<dimen name="module_mogo_autopilot_status_margin_left">20px</dimen>
<dimen name="module_mogo_autopilot_status_margin_top">345px</dimen>
<dimen name="module_mogo_autopilot_status_padding">20px</dimen>
<dimen name="module_mogo_autopilot_status_text_size">30px</dimen>
</resources>

View File

@@ -468,14 +468,7 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
Logger.d(TAG, "requestCode: " + requestCode + " resultCode: " + resultCode);
if (requestCode == REQUEST_CODE_DIALOG) {
//申请悬浮窗权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 检查是否有悬浮窗权限
if (Settings.canDrawOverlays(this)) {
startVoicePad();
}
} else {
startVoicePad();
}
}
}
}

View File

@@ -79,11 +79,6 @@ public class PushModuleProvider implements IMogoModuleProvider {
@Override
public void init(final Context context) {
HandlerUtils.INSTANCE.getMBgHandler().post(new Runnable() {
@Override
public void run() {
PushRepository.Companion.init(context);
}
});
HandlerUtils.INSTANCE.getMBgHandler().post(() -> PushRepository.Companion.init(context));
}
}

View File

@@ -123,7 +123,9 @@ class PushRepository(mContext: Context) {
} else {
return
}
iterateNext()
mHandler.post {
iterateNext()
}
}
}

View File

@@ -1,22 +1,15 @@
package com.mogo.module.push.view
import android.animation.Animator
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PixelFormat
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.*
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.Scroller
import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.core.animation.doOnEnd
import androidx.core.view.isVisible
import com.elegant.analytics.utils.Logger
import com.mogo.commons.context.ContextHolderUtil
import com.mogo.commons.voice.AIAssist
import com.mogo.module.push.Config
import com.mogo.module.push.R
@@ -27,14 +20,15 @@ import com.mogo.module.push.view.roundimage.RoundedImageView
import com.mogo.module.push.viewmodel.PushViewModel
import com.mogo.service.windowview.IMogoTopViewManager
import com.mogo.service.windowview.IMogoTopViewStatusListener
import com.mogo.utils.ResourcesHelper
import com.mogo.utils.ThreadPoolService
import com.mogo.utils.UiThreadHandler
import com.mogo.utils.glide.GlideApp
import com.mogo.utils.logger.Logger
import kotlin.math.log
class FloatView constructor(
private val pushViewModel: PushViewModel,
private val context: Context
private val pushViewModel: PushViewModel,
private val context: Context
) {
companion object {
@@ -46,44 +40,37 @@ class FloatView constructor(
interface PushViewController {
fun show(bean: PushBean?)
fun hide()
fun timer(time: Int)
fun inflateView(@LayoutRes layoutId: Int)
}
abstract inner class PushView(context: Context) : FrameLayout(context),
PushViewController {
private lateinit var appIcon: ImageView
PushViewController {
private lateinit var titleIconContainer: View
private lateinit var pushTitle: TextView
private lateinit var pushImage: RoundedImageView
private lateinit var pushContent: TextView
private lateinit var pushTimer: TextView
private lateinit var pushButtonLeft: TextView
private lateinit var pushButtonRight: TextView
lateinit var pushButton: View
private lateinit var pushCheck: TextView
private var pushData: PushBean? = null
override fun inflateView(layoutId: Int) {
LayoutInflater.from(context).inflate(layoutId, this, true)
appIcon = findViewById(R.id.module_push_app_icon)
pushTitle = findViewById(R.id.module_push_title)
pushCheck = findViewById(R.id.module_push_check)
pushImage = findViewById(R.id.module_push_image)
pushContent = findViewById(R.id.module_push_content)
pushButtonLeft = findViewById(R.id.module_push_button_left)
pushButtonRight = findViewById(R.id.module_push_button_right)
pushTimer = findViewById(R.id.module_push_timer)
titleIconContainer = findViewById(R.id.module_push_app_icon_title)
pushButton = findViewById(R.id.module_push_buttons)
setOnClickListener {
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_MAIN, "1")
turnNextMessage()
}
pushButtonLeft.setOnClickListener {
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_LEFT, "1")
turnNextMessage()
}
pushButtonRight.setOnClickListener {
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_RIGHT, "1")
turnNextMessage()
pushCheck.setOnClickListener {
pushData?.let {
if (pushCheckDialog == null) {
pushCheckDialog = PushCheckDialog(ContextHolderUtil.getContext())
}
pushCheckDialog!!.showCheckDialog(it.title, it.content)
}
}
}
@@ -94,35 +81,11 @@ class FloatView constructor(
}
}
fun hasButtons(bean: PushBean?): Boolean {
bean?.buttons?.forEach {
if (it.text.isNotEmpty()) {
return true
}
}
return false
}
fun hasTextContent(bean: PushBean?): Boolean =
bean?.content?.isEmpty()?.not() ?: false
fun hasImgContent(bean: PushBean?): Boolean = bean?.QRCode?.isEmpty()?.not() ?: false
open fun setBean(bean: PushBean) {
// app icon
if (bean.appIcon.isNotEmpty()) {
appIcon.visible()
GlideApp.with(this).load(bean.appIcon).into(appIcon)
} else {
appIcon.gone()
}
pushData = bean
// title
pushTitle.text = bean.title
// decrease timer
pushTimer.text = if (bean.showTimeout > 99) "" else "${bean.showTimeout}s"
// image
if (bean.imageUrl.isEmpty() && bean.QRCode.isEmpty()) {
pushImage.gone()
@@ -140,9 +103,9 @@ class FloatView constructor(
pushImage.layoutParams = params
ThreadPoolService.execute {
val bmp = stringConverterBitmap(
bean.QRCode,
getQrImgWidth(),
getQrImgHeight()
bean.QRCode,
getQrImgWidth(),
getQrImgHeight()
)
UiThreadHandler.post {
pushImage.setImageBitmap(bmp)
@@ -151,22 +114,6 @@ class FloatView constructor(
}
}
// button
pushButton.gone()
pushButtonLeft.gone()
pushButtonRight.gone()
if (!bean.buttons.isNullOrEmpty()) {
if (bean.buttons[0].text.isNotEmpty()) {
pushButton.visible()
pushButtonLeft.text = bean.buttons[0].text
pushButtonLeft.visible()
}
if (bean.buttons.size > 1 && bean.buttons[1].text.isNotEmpty()) {
pushButtonRight.text = bean.buttons[1].text
pushButtonRight.visible()
}
}
// content
if (bean.content.isEmpty()) {
pushContent.gone()
@@ -175,10 +122,10 @@ class FloatView constructor(
pushContent.visible()
}
// tts
if (bean.tts.isNotEmpty()) {
AIAssist.getInstance(context).speakTTSVoice(bean.tts)
}
// 产品侧需要重新梳理tts暂时不播报
// if (bean.tts.isNotEmpty()) {
// AIAssist.getInstance(context).speakTTSVoice(bean.tts)
// }
}
abstract fun getImgWidth(): Int
@@ -186,12 +133,6 @@ class FloatView constructor(
abstract fun getQrImgWidth(): Int
abstract fun getQrImgHeight(): Int
@SuppressLint("SetTextI18n")
override fun timer(time: Int) {
Logger.d(TAG, "time = $time")
pushTimer.text = "${time}s"
}
override fun show(bean: PushBean?) {
isAddWindow = true
uiHandler.removeCallbacks(delayClosePush)
@@ -252,184 +193,175 @@ class FloatView constructor(
}
override fun getImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width)
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width)
override fun getImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
override fun getQrImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
override fun getQrImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
}
inner class PushViewInWindowView(context: Context) : PushView(context), View.OnTouchListener {
private val mContentContainer: View
private val mWindowManager =
context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val params = WindowManager.LayoutParams()
init {
@Suppress("DEPRECATION")
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE
or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
params.width = WindowManager.LayoutParams.WRAP_CONTENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
params.gravity = Gravity.START or Gravity.BOTTOM
params.format = PixelFormat.TRANSLUCENT
params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
if (Build.VERSION.SDK_INT > 25) {
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
}
inflateView(R.layout.module_push_item_vertical)
mContentContainer = findViewById(R.id.module_push_content_container)
setOnTouchListener(this)
}
override fun show(bean: PushBean?) {
super.show(bean)
mLastVisibleType = TYPE_WINDOW_MANAGER
setBean(bean!!)
try {
mWindowManager.addView(this, params)
} catch (e: Exception) {
mWindowManager.updateViewLayout(this, params)
}
translationXAnimation(
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical),
0f
) {
if (pushViewModel.pushBean != null) {
startClosePush()
}
}
}
private fun translationXAnimation(
from: Float,
to: Float,
doOnEnd: (animator: Animator) -> Unit
) {
val transitionXAnimator: ObjectAnimator =
ObjectAnimator.ofFloat(
this,
View.TRANSLATION_X,
from,
to
)
transitionXAnimator.duration = 200
transitionXAnimator.doOnEnd(doOnEnd)
transitionXAnimator.start()
}
override fun setBean(bean: PushBean) {
super.setBean(bean)
var paddingBottom = 0
if (pushButton.isVisible) {
paddingBottom =
context.resources.getDimensionPixelSize(R.dimen.module_push_content_paddingBottom_vertical)
}
mContentContainer.setPadding(0, 0, 0, paddingBottom)
}
override fun hide() {
super.hide()
translationXAnimation(
this.x,
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical)
) {
Logger.d(TAG, "here")
this.x = 0f
mWindowManager.removeViewImmediate(this)
}
}
override fun onTouch(v: View?, ev: MotionEvent?): Boolean {
if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
return false
}
when (ev?.action) {
MotionEvent.ACTION_DOWN -> {
needInterceptClick = false
startX = ev.x
}
MotionEvent.ACTION_MOVE -> {
moveX = startX - ev.x
scrollBy(moveX.toInt(), 0)
startX = ev.x
if (scrollX < 0) {
scrollTo(0, 0)
}
if (!needInterceptClick && scrollX > 20) {
needInterceptClick = true
}
invalidate()
}
MotionEvent.ACTION_UP -> {
if (scrollX > 0) {
mScroller.startScroll(scrollX, 0, width - scrollX, 0)
invalidate()
return true
}
if (needInterceptClick) {
return true
}
}
else -> {
startX = 0f
moveX = 0f
}
}
return false
}
override fun computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.currX, mScroller.currY)
invalidate()
} else {
if (mScroller.currX == 0) {
return
}
mScroller.finalX = 0
removeCallbacks(delayClosePush)
if (isAddWindow) {
if (currentBean != null) {
AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1")
}
mWindowManager.removeView(this)
isAddWindow = false
}
pushViewModel.pushBean?.showTimeout = 0
updateTimer()
}
}
override fun getImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical)
override fun getImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical)
override fun getQrImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
override fun getQrImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
}
// inner class PushViewInWindowView(context: Context) : PushView(context), View.OnTouchListener {
//
// private val mContentContainer: View
// private val mWindowManager =
// context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
//
// private val params = WindowManager.LayoutParams()
//
// init {
//
// @Suppress("DEPRECATION")
// params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
// params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
// or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
// or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE
// or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
// or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
// params.width = WindowManager.LayoutParams.WRAP_CONTENT
// params.height = WindowManager.LayoutParams.WRAP_CONTENT
// params.gravity = Gravity.START or Gravity.BOTTOM
// params.format = PixelFormat.TRANSLUCENT
// params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
// params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
// if (Build.VERSION.SDK_INT > 25) {
// params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
// }
//
// inflateView(R.layout.module_push_item_vertical)
// mContentContainer = findViewById(R.id.module_push_content_container)
// setOnTouchListener(this)
// }
//
// override fun show(bean: PushBean?) {
// super.show(bean)
// mLastVisibleType = TYPE_WINDOW_MANAGER
// setBean(bean!!)
//
// try {
// mWindowManager.addView(this, params)
// } catch (e: Exception) {
// mWindowManager.updateViewLayout(this, params)
// }
// translationXAnimation(
// -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical),
// 0f
// ) {
// if (pushViewModel.pushBean != null) {
// startClosePush()
// }
// }
// }
//
// private fun translationXAnimation(
// from: Float,
// to: Float,
// doOnEnd: (animator: Animator) -> Unit
// ) {
// val transitionXAnimator: ObjectAnimator =
// ObjectAnimator.ofFloat(
// this,
// View.TRANSLATION_X,
// from,
// to
// )
// transitionXAnimator.duration = 200
// transitionXAnimator.doOnEnd(doOnEnd)
// transitionXAnimator.start()
// }
//
// override fun hide() {
// super.hide()
// translationXAnimation(
// this.x,
// -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical)
// ) {
// Logger.d(TAG, "here")
// this.x = 0f
// mWindowManager.removeViewImmediate(this)
// }
// }
//
// override fun onTouch(v: View?, ev: MotionEvent?): Boolean {
//
// if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
// return false
// }
// when (ev?.action) {
// MotionEvent.ACTION_DOWN -> {
// needInterceptClick = false
// startX = ev.x
// }
// MotionEvent.ACTION_MOVE -> {
// moveX = startX - ev.x
// scrollBy(moveX.toInt(), 0)
// startX = ev.x
// if (scrollX < 0) {
// scrollTo(0, 0)
// }
// if (!needInterceptClick && scrollX > 20) {
// needInterceptClick = true
// }
// invalidate()
// }
// MotionEvent.ACTION_UP -> {
// if (scrollX > 0) {
// mScroller.startScroll(scrollX, 0, width - scrollX, 0)
// invalidate()
// return true
// }
// if (needInterceptClick) {
// return true
// }
// }
// else -> {
// startX = 0f
// moveX = 0f
// }
// }
// return false
// }
//
// override fun computeScroll() {
// if (mScroller.computeScrollOffset()) {
// scrollTo(mScroller.currX, mScroller.currY)
// invalidate()
// } else {
// if (mScroller.currX == 0) {
// return
// }
// mScroller.finalX = 0
// removeCallbacks(delayClosePush)
// if (isAddWindow) {
// if (currentBean != null) {
// AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1")
// }
// mWindowManager.removeView(this)
// isAddWindow = false
// }
// pushViewModel.pushBean?.showTimeout = 0
// updateTimer()
// }
// }
//
// override fun getImgWidth(): Int =
// context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical)
//
// override fun getImgHeight(): Int =
// context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical)
//
// override fun getQrImgWidth(): Int =
// context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
//
// override fun getQrImgHeight(): Int =
// context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
// }
private var pushCheckDialog: PushCheckDialog? = null
private val delayClosePush: Runnable
private var isAddWindow = false
private val uiHandler = Handler(Looper.getMainLooper())
@@ -473,10 +405,8 @@ class FloatView constructor(
val time = pushViewModel.pushBean?.showTimeout ?: 0
if (time > 0) {
pushViewModel.pushBean!!.showTimeout--
pushViewController?.timer(time)
uiHandler.postDelayed(delayClosePush, 1000)
} else {
pushViewController?.timer(0)
pushViewModel.pushMessageFinish(true)
}
}
@@ -520,17 +450,17 @@ class FloatView constructor(
}
private fun showByWindowManager(bean: PushBean?) {
if (pushViewController !is PushViewInWindowView) {
pushViewController = PushViewInWindowView(context)
}
pushViewController?.show(bean)
// if (pushViewController !is PushViewInWindowView) {
// pushViewController = PushViewInWindowView(context)
// }
// pushViewController?.show(bean)
}
private fun startClosePush() {
uiHandler.removeCallbacks(delayClosePush)
uiHandler.postDelayed(
delayClosePush,
1000L
delayClosePush,
1000L
)
}

View File

@@ -0,0 +1,568 @@
package com.mogo.module.push.view
import android.animation.Animator
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PixelFormat
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.*
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.Scroller
import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.core.animation.doOnEnd
import androidx.core.view.isVisible
import com.elegant.analytics.utils.Logger
import com.mogo.commons.voice.AIAssist
import com.mogo.module.push.Config
import com.mogo.module.push.R
import com.mogo.module.push.model.PushBean
import com.mogo.module.push.utils.AnalyticsUtils
import com.mogo.module.push.utils.stringConverterBitmap
import com.mogo.module.push.view.roundimage.RoundedImageView
import com.mogo.module.push.viewmodel.PushViewModel
import com.mogo.service.windowview.IMogoTopViewManager
import com.mogo.service.windowview.IMogoTopViewStatusListener
import com.mogo.utils.ResourcesHelper
import com.mogo.utils.ThreadPoolService
import com.mogo.utils.UiThreadHandler
import com.mogo.utils.glide.GlideApp
class FloatViewOrigin constructor(
private val pushViewModel: PushViewModel,
private val context: Context
) {
companion object {
const val TYPE_TOP_VIEW = 1
const val TYPE_WINDOW_MANAGER = 2
const val TAG: String = "FloatViewOrigin.kt"
}
interface PushViewController {
fun show(bean: PushBean?)
fun hide()
fun timer(time: Int)
fun inflateView(@LayoutRes layoutId: Int)
}
abstract inner class PushViewOrigin(context: Context) : FrameLayout(context),
PushViewController {
private lateinit var appIcon: ImageView
private lateinit var titleIconContainer: View
private lateinit var pushTitle: TextView
private lateinit var pushImage: RoundedImageView
private lateinit var pushContent: TextView
private lateinit var pushTimer: TextView
private lateinit var pushButtonLeft: TextView
private lateinit var pushButtonRight: TextView
lateinit var pushButton: View
override fun inflateView(layoutId: Int) {
LayoutInflater.from(context).inflate(layoutId, this, true)
appIcon = findViewById(R.id.module_push_app_icon)
pushTitle = findViewById(R.id.module_push_title)
pushImage = findViewById(R.id.module_push_image)
pushContent = findViewById(R.id.module_push_content)
pushButtonLeft = findViewById(R.id.module_push_button_left)
pushButtonRight = findViewById(R.id.module_push_button_right)
pushTimer = findViewById(R.id.module_push_timer)
titleIconContainer = findViewById(R.id.module_push_app_icon_title)
pushButton = findViewById(R.id.module_push_buttons)
setOnClickListener {
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_MAIN, "1")
turnNextMessage()
}
pushButtonLeft.setOnClickListener {
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_LEFT, "1")
turnNextMessage()
}
pushButtonRight.setOnClickListener {
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_RIGHT, "1")
turnNextMessage()
}
}
private fun turnNextMessage() {
pushViewModel.pushBean?.apply {
showTimeout = 0
updateTimer()
}
}
fun hasButtons(bean: PushBean?): Boolean {
bean?.buttons?.forEach {
if (it.text.isNotEmpty()) {
return true
}
}
return false
}
fun hasTextContent(bean: PushBean?): Boolean =
bean?.content?.isEmpty()?.not() ?: false
fun hasImgContent(bean: PushBean?): Boolean = bean?.QRCode?.isEmpty()?.not() ?: false
open fun setBean(bean: PushBean) {
// app icon
if (bean.appIcon.isNotEmpty()) {
appIcon.visible()
GlideApp.with(this).load(bean.appIcon).into(appIcon)
} else {
appIcon.gone()
}
// title
pushTitle.text = bean.title
// decrease timer
pushTimer.text = if (bean.showTimeout > 99) "" else "${bean.showTimeout}s"
// image
if (bean.imageUrl.isEmpty() && bean.QRCode.isEmpty()) {
pushImage.gone()
} else if (bean.imageUrl.isNotEmpty()) {
val params = pushImage.layoutParams
params.width = getImgWidth()
params.height = getImgHeight()
pushImage.layoutParams = params
pushImage.visible()
GlideApp.with(this).load(bean.imageUrl).into(pushImage)
} else if (bean.QRCode.isNotEmpty()) {
val params = pushImage.layoutParams
params.width = getQrImgWidth()
params.height = getQrImgHeight()
pushImage.layoutParams = params
ThreadPoolService.execute {
val bmp = stringConverterBitmap(
bean.QRCode,
getQrImgWidth(),
getQrImgHeight()
)
UiThreadHandler.post {
pushImage.setImageBitmap(bmp)
pushImage.visible()
}
}
}
// button
pushButton.gone()
pushButtonLeft.gone()
pushButtonRight.gone()
if (!bean.buttons.isNullOrEmpty()) {
if (bean.buttons[0].text.isNotEmpty()) {
pushButton.visible()
pushButtonLeft.text = bean.buttons[0].text
pushButtonLeft.visible()
}
if (bean.buttons.size > 1 && bean.buttons[1].text.isNotEmpty()) {
pushButtonRight.text = bean.buttons[1].text
pushButtonRight.visible()
}
}
// content
if (bean.content.isEmpty()) {
pushContent.gone()
} else {
pushContent.text = bean.content
pushContent.visible()
}
// tts
if (bean.tts.isNotEmpty()) {
AIAssist.getInstance(context).speakTTSVoice(bean.tts)
}
}
abstract fun getImgWidth(): Int
abstract fun getImgHeight(): Int
abstract fun getQrImgWidth(): Int
abstract fun getQrImgHeight(): Int
@SuppressLint("SetTextI18n")
override fun timer(time: Int) {
Logger.d(TAG, "time = $time")
pushTimer.text = "${time}s"
}
override fun show(bean: PushBean?) {
isAddWindow = true
uiHandler.removeCallbacks(delayClosePush)
}
override fun hide() {
isAddWindow = false
}
}
open inner class PushViewInTopView(context: Context) : PushViewOrigin(context) {
private val mTopViewManager: IMogoTopViewManager = getApis(context).topViewManager
init {
inflateView(R.layout.module_push_item_origin)
}
private var topViewStatusListener = object : IMogoTopViewStatusListener {
override fun onViewRemoved(view: View?) {
isAddWindow = false
if (pushViewModel.pushBean?.showTimeout ?: 0 > 0) {
if (getApis(context).statusManagerApi.isV2XShow) {
// 被中断的消息,需要再次被显示一次
uiHandler.removeCallbacks(delayClosePush)
pushViewModel.push()
pushViewModel.pushMessageFinish()
return
}
}
pushViewModel.pushBean?.showTimeout = 0
updateTimer()
}
override fun onViewAdded(view: View?) {
if (pushViewModel.pushBean != null) {
startClosePush()
}
}
override fun beforeViewRemoveAnim(view: View?) {
}
override fun beforeViewAddAnim(view: View?) {
}
}
override fun show(bean: PushBean?) {
super.show(bean)
mLastVisibleType = TYPE_TOP_VIEW
mTopViewManager.addView(this, topViewStatusListener)
setBean(bean!!)
}
override fun hide() {
super.hide()
mTopViewManager.removeView(this)
}
override fun getImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width)
override fun getImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
override fun getQrImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
override fun getQrImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
}
inner class PushViewInWindowView(context: Context) : PushViewOrigin(context), View.OnTouchListener {
private val mContentContainer: View
private val mWindowManager =
context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val params = WindowManager.LayoutParams()
init {
@Suppress("DEPRECATION")
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE
or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
params.width = WindowManager.LayoutParams.WRAP_CONTENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
params.gravity = Gravity.START or Gravity.BOTTOM
params.format = PixelFormat.TRANSLUCENT
params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
if (Build.VERSION.SDK_INT > 25) {
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
}
inflateView(R.layout.module_push_item_vertical)
mContentContainer = findViewById(R.id.module_push_content_container)
setOnTouchListener(this)
}
override fun show(bean: PushBean?) {
super.show(bean)
mLastVisibleType = TYPE_WINDOW_MANAGER
setBean(bean!!)
try {
mWindowManager.addView(this, params)
} catch (e: Exception) {
mWindowManager.updateViewLayout(this, params)
}
translationXAnimation(
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical),
0f
) {
if (pushViewModel.pushBean != null) {
startClosePush()
}
}
}
private fun translationXAnimation(
from: Float,
to: Float,
doOnEnd: (animator: Animator) -> Unit
) {
val transitionXAnimator: ObjectAnimator =
ObjectAnimator.ofFloat(
this,
View.TRANSLATION_X,
from,
to
)
transitionXAnimator.duration = 200
transitionXAnimator.doOnEnd(doOnEnd)
transitionXAnimator.start()
}
override fun setBean(bean: PushBean) {
super.setBean(bean)
var paddingBottom = 0
if (pushButton.isVisible) {
paddingBottom =
context.resources.getDimensionPixelSize(R.dimen.module_push_content_paddingBottom_vertical)
}
mContentContainer.setPadding(0, 0, 0, paddingBottom)
}
override fun hide() {
super.hide()
translationXAnimation(
this.x,
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical)
) {
Logger.d(TAG, "here")
this.x = 0f
mWindowManager.removeViewImmediate(this)
}
}
override fun onTouch(v: View?, ev: MotionEvent?): Boolean {
if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
return false
}
when (ev?.action) {
MotionEvent.ACTION_DOWN -> {
needInterceptClick = false
startX = ev.x
}
MotionEvent.ACTION_MOVE -> {
moveX = startX - ev.x
scrollBy(moveX.toInt(), 0)
startX = ev.x
if (scrollX < 0) {
scrollTo(0, 0)
}
if (!needInterceptClick && scrollX > 20) {
needInterceptClick = true
}
invalidate()
}
MotionEvent.ACTION_UP -> {
if (scrollX > 0) {
mScroller.startScroll(scrollX, 0, width - scrollX, 0)
invalidate()
return true
}
if (needInterceptClick) {
return true
}
}
else -> {
startX = 0f
moveX = 0f
}
}
return false
}
override fun computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.currX, mScroller.currY)
invalidate()
} else {
if (mScroller.currX == 0) {
return
}
mScroller.finalX = 0
removeCallbacks(delayClosePush)
if (isAddWindow) {
if (currentBean != null) {
AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1")
}
mWindowManager.removeView(this)
isAddWindow = false
}
pushViewModel.pushBean?.showTimeout = 0
updateTimer()
}
}
override fun getImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical)
override fun getImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical)
override fun getQrImgWidth(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
override fun getQrImgHeight(): Int =
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
}
private val delayClosePush: Runnable
private var isAddWindow = false
private val uiHandler = Handler(Looper.getMainLooper())
private var startX = 0f
private var moveX = 0f
private val mScroller: Scroller = Scroller(context)
private var needInterceptClick = false
private var pause = false
private var currentBean: PushBean? = null
private var mLastVisibleType = -1
private var pushViewController: PushViewController? = null
init {
delayClosePush = Runnable {
updateTimer()
}
}
fun pushBeanChanged(bean: PushBean?) {
uiHandler.post {
uiHandler.removeCallbacks(delayClosePush)
if (bean == null) {
if (currentBean != null) {
AnalyticsUtils.track(Config.NEWS_CARD_DISAPPEAR, "title", currentBean!!.title)
}
hide()
} else {
show(bean)
AnalyticsUtils.track(Config.NEWS_CARD_SHOW, "title", bean.title)
}
currentBean = bean
}
}
private fun updateTimer() {
uiHandler.removeCallbacks(delayClosePush)
val time = pushViewModel.pushBean?.showTimeout ?: 0
if (time > 0) {
pushViewModel.pushBean!!.showTimeout--
pushViewController?.timer(time)
uiHandler.postDelayed(delayClosePush, 1000)
} else {
pushViewController?.timer(0)
pushViewModel.pushMessageFinish(true)
}
}
private fun show(bean: PushBean) {
if (isAddWindow) {
if (getApis(context).statusManagerApi.isMainPageOnResume) {
if (mLastVisibleType != TYPE_TOP_VIEW) {
hide()
(pushViewController as View).postDelayed({
show(bean)
}, 750L)
} else {
showByTopView(bean)
}
} else {
if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
hide()
(pushViewController as View).postDelayed({
show(bean)
}, 750L)
} else {
showByWindowManager(bean)
}
}
startClosePush()
} else {
if (getApis(context).statusManagerApi.isMainPageOnResume) {
showByTopView(bean)
} else {
showByWindowManager(bean)
}
}
}
private fun showByTopView(bean: PushBean) {
if (pushViewController !is PushViewInTopView) {
pushViewController = PushViewInTopView(context)
}
pushViewController?.show(bean)
}
private fun showByWindowManager(bean: PushBean?) {
if (pushViewController !is PushViewInWindowView) {
pushViewController = PushViewInWindowView(context)
}
pushViewController?.show(bean)
}
private fun startClosePush() {
uiHandler.removeCallbacks(delayClosePush)
uiHandler.postDelayed(
delayClosePush,
1000L
)
}
fun hide() {
if (!isAddWindow) {
return
}
try {
pushViewController?.hide()
} catch (e: Exception) {
e.printStackTrace()
}
}
fun pauseTimer(on: Boolean) {
if (on) {
uiHandler.removeCallbacks(delayClosePush)
} else {
updateTimer()
uiHandler.post {
if (on) {
pause = true
uiHandler.removeCallbacks(delayClosePush)
} else if (pause) {
pause = false
updateTimer()
}
}
}
}
fun isAddWindow(): Boolean = isAddWindow
}

View File

@@ -0,0 +1,37 @@
package com.mogo.module.push.view
import android.content.Context
import android.widget.ImageView
import android.widget.TextView
import com.mogo.module.common.dialog.BaseFloatDialog
import com.mogo.module.push.R
class PushCheckDialog(context: Context) : BaseFloatDialog(context) {
private var pushCheckClose: ImageView? = null
private var pushCheckTitle: TextView? = null
private var pushCheckContent: TextView? = null
init {
setContentView(R.layout.module_push_dialog_check)
setCanceledOnTouchOutside(true)
pushCheckClose = findViewById(R.id.module_push_dialog_close)
pushCheckTitle = findViewById(R.id.module_push_dialog_title)
pushCheckContent = findViewById(R.id.module_push_dialog_content)
pushCheckClose?.setOnClickListener {
dismiss()
}
}
fun showCheckDialog(title: String, content: String) {
if (isShowing) {
return
}
if (title.isBlank() || content.isBlank()) {
return
}
pushCheckTitle?.text = title
pushCheckContent?.text = content
show()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/module_push_check_dialog_bg_color" />
<corners android:radius="@dimen/module_push_dialog_check_bg_corner" />
</shape>

View File

@@ -1,7 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?><!--<selector xmlns:android="http://schemas.android.com/apk/res/android">-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:endColor="#33000000"
android:startColor="#33000000"
android:type="linear" />
<corners android:radius="@dimen/module_push_ui_bkg_corner" />
<solid android:color="#F23F4057" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/module_push_ui_bkg_corner" />
<solid android:color="#F23F4057" />
</shape>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/module_push_dialog_check_width"
android:layout_height="@dimen/module_push_dialog_check_height"
android:background="@drawable/module_push_dialog_check_background">
<ImageView
android:id="@+id/module_push_dialog_close"
android:layout_width="@dimen/module_push_dialog_close_width"
android:layout_height="@dimen/module_push_dialog_close_height"
android:layout_marginLeft="@dimen/module_push_dialog_close_margin"
android:layout_marginTop="@dimen/module_push_dialog_close_margin"
android:scaleType="fitXY"
android:src="@drawable/module_push_dialog_close"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/module_push_dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/module_push_dialog_title_margin"
android:textColor="@android:color/white"
android:textSize="@dimen/module_push_dialog_title_size"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/module_push_dialog_content"
android:layout_width="@dimen/module_push_dialog_content_width"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/module_push_dialog_content_margin_top"
android:textColor="@android:color/white"
android:textSize="@dimen/module_push_dialog_content_size"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/module_push_dialog_title" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,18 +4,19 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/module_push_ui_height"
android:background="@drawable/module_push_item_background_p">
android:layout_marginTop="@dimen/module_push_ui_margin_top"
android:background="@drawable/module_push_item_background">
<com.mogo.module.push.view.roundimage.RoundedImageView
android:id="@+id/module_push_image"
android:layout_width="@dimen/module_push_ui_image_width"
android:layout_height="@dimen/module_push_ui_image_height"
android:layout_marginLeft="@dimen/module_push_ui_image_marLeft"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:riv_corner_radius="@dimen/module_push_ui_image_corner" />
app:riv_corner_radius_bottom_left="@dimen/module_push_ui_image_corner"
app:riv_corner_radius_top_left="@dimen/module_push_ui_image_corner" />
<LinearLayout
android:id="@+id/module_push_app_icon_title"
@@ -24,19 +25,10 @@
android:layout_marginLeft="@dimen/module_push_ui_app_icon_leftMargin"
android:layout_marginTop="@dimen/module_push_ui_app_icon_topMargin"
android:gravity="center_vertical"
android:minHeight="@dimen/module_push_ui_app_icon_size"
app:layout_constraintRight_toLeftOf="@+id/module_push_progress_bar_frame"
app:layout_constraintLeft_toRightOf="@+id/module_push_image"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginTop="@dimen/module_push_ui_app_icon_goneTopMargin">
<ImageView
android:id="@+id/module_push_app_icon"
android:layout_width="@dimen/module_push_ui_app_icon_size"
android:layout_height="@dimen/module_push_ui_app_icon_size"
android:layout_marginRight="@dimen/module_push_title_margin_start"
android:background="@drawable/module_push_ui_ic_message2" />
<TextView
android:id="@+id/module_push_title"
android:layout_width="wrap_content"
@@ -44,102 +36,59 @@
android:ellipsize="end"
android:gravity="center_vertical|left"
android:maxWidth="@dimen/module_push_title_mix_width"
android:singleLine="true"
android:maxLength="25"
tools:text="标题标题标题标题标题标题标题"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="@dimen/module_push_ui_title_textSize"
app:layout_constrainedWidth="true" />
app:layout_constrainedWidth="true"
tools:text="官方公告" />
</LinearLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/module_push_rl_content"
android:layout_width="@dimen/module_push_ui_content_width"
android:layout_height="@dimen/module_push_ui_content_height"
android:layout_marginTop="@dimen/module_push_ui_content_marginTop"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/module_push_ui_content_marginBottom"
app:layout_constraintLeft_toLeftOf="@id/module_push_app_icon_title"
app:layout_constraintRight_toRightOf="@id/module_push_progress_bar_frame"
app:layout_constraintTop_toBottomOf="@id/module_push_app_icon_title">
<TextView
android:id="@+id/module_push_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxLines="3"
android:layout_above="@+id/module_push_buttons"
android:ellipsize="end"
android:maxLines="3"
android:textColor="@android:color/white"
android:textSize="@dimen/module_push_ui_title_text_size"
tools:text="文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内" />
android:textSize="@dimen/module_push_ui_title_text_size" />
<LinearLayout
android:id="@+id/module_push_buttons"
android:layout_width="match_parent"
android:layout_height="@dimen/module_push_button_height"
android:layout_alignParentBottom="true"
android:layout_marginTop="@dimen/module_push_button_margin_top"
android:layout_marginBottom="@dimen/module_push_button_margin_bottom"
android:gravity="center"
android:weightSum="2">
<TextView
android:id="@+id/module_push_button_left"
android:layout_width="@dimen/module_push_button_width"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/module_push_left_button"
android:ellipsize="end"
android:gravity="center"
android:enabled="true"
android:lines="1"
android:maxWidth="@dimen/module_push_button_maxWidth"
android:maxLength="6"
android:text="查看"
android:textColor="#FFFFFF"
android:textSize="@dimen/module_push_title_text_size"
android:textStyle="bold" />
<TextView
android:id="@+id/module_push_button_right"
android:layout_width="@dimen/module_push_button_width"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/module_push_button_right_marLeft"
android:layout_weight="1"
android:background="@drawable/module_push_right_button"
android:ellipsize="end"
android:gravity="center"
android:lines="1"
android:maxWidth="@dimen/module_push_button_maxWidth"
android:maxLength="6"
android:text="忽略"
android:textColor="#FFFFFF"
android:textSize="@dimen/module_push_title_text_size"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>
<FrameLayout
android:id="@+id/module_push_progress_bar_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/module_push_progress_bar_frame_marginTop"
android:layout_marginEnd="@dimen/module_push_progress_bar_frame_marginEnd"
android:background="@drawable/module_push_decrease_timer_bkg"
android:paddingLeft="@dimen/module_push_progress_bar_frame_padding"
android:paddingRight="@dimen/module_push_progress_bar_frame_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<View
android:id="@+id/module_push_line"
android:layout_width="@dimen/module_push_line_width"
android:layout_height="@dimen/module_push_line_height"
android:layout_marginLeft="@dimen/module_push_line_margin_left"
android:background="@color/module_push_item_line_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/module_push_rl_content"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/module_push_timer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#80FFFFFF"
android:textSize="@dimen/module_push_ui_timer_textSize"
tools:text="11s" />
</FrameLayout>
<TextView
android:id="@+id/module_push_check"
android:layout_width="@dimen/module_push_check_width"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/module_push_check_margin"
android:layout_marginBottom="@dimen/module_push_check_margin"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="@string/module_push_check"
android:textColor="@color/module_push_check_color"
android:textSize="@dimen/module_push_check_text_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/module_push_line"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/module_push_ui_height"
android:background="@drawable/module_push_item_background_p">
<com.mogo.module.push.view.roundimage.RoundedImageView
android:id="@+id/module_push_image"
android:layout_width="@dimen/module_push_ui_image_width"
android:layout_height="@dimen/module_push_ui_image_height"
android:layout_marginLeft="@dimen/module_push_ui_image_marLeft"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:riv_corner_radius="@dimen/module_push_ui_image_corner" />
<LinearLayout
android:id="@+id/module_push_app_icon_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/module_push_ui_app_icon_leftMargin"
android:layout_marginTop="@dimen/module_push_ui_app_icon_topMargin"
android:gravity="center_vertical"
android:minHeight="@dimen/module_push_ui_app_icon_size"
app:layout_constraintRight_toLeftOf="@+id/module_push_progress_bar_frame"
app:layout_constraintLeft_toRightOf="@+id/module_push_image"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginTop="@dimen/module_push_ui_app_icon_goneTopMargin">
<ImageView
android:id="@+id/module_push_app_icon"
android:layout_width="@dimen/module_push_ui_app_icon_size"
android:layout_height="@dimen/module_push_ui_app_icon_size"
android:layout_marginRight="@dimen/module_push_title_margin_start"
android:background="@drawable/module_push_ui_ic_message2" />
<TextView
android:id="@+id/module_push_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center_vertical|left"
android:maxWidth="@dimen/module_push_title_mix_width"
android:singleLine="true"
android:maxLength="25"
tools:text="标题标题标题标题标题标题标题"
android:textColor="@android:color/white"
android:textSize="@dimen/module_push_ui_title_textSize"
app:layout_constrainedWidth="true" />
</LinearLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/module_push_ui_content_marginTop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/module_push_app_icon_title"
app:layout_constraintRight_toRightOf="@id/module_push_progress_bar_frame"
app:layout_constraintTop_toBottomOf="@id/module_push_app_icon_title">
<TextView
android:id="@+id/module_push_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxLines="3"
android:layout_above="@+id/module_push_buttons"
android:ellipsize="end"
android:textColor="@android:color/white"
android:textSize="@dimen/module_push_ui_title_text_size"
tools:text="文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内" />
<LinearLayout
android:id="@+id/module_push_buttons"
android:layout_width="match_parent"
android:layout_height="@dimen/module_push_button_height"
android:layout_alignParentBottom="true"
android:layout_marginTop="@dimen/module_push_button_margin_top"
android:layout_marginBottom="@dimen/module_push_button_margin_bottom"
android:gravity="center"
android:weightSum="2">
<TextView
android:id="@+id/module_push_button_left"
android:layout_width="@dimen/module_push_button_width"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/module_push_left_button"
android:ellipsize="end"
android:gravity="center"
android:enabled="true"
android:lines="1"
android:maxWidth="@dimen/module_push_button_maxWidth"
android:maxLength="6"
android:text="查看"
android:textColor="#FFFFFF"
android:textSize="@dimen/module_push_title_text_size"
android:textStyle="bold" />
<TextView
android:id="@+id/module_push_button_right"
android:layout_width="@dimen/module_push_button_width"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/module_push_button_right_marLeft"
android:layout_weight="1"
android:background="@drawable/module_push_right_button"
android:ellipsize="end"
android:gravity="center"
android:lines="1"
android:maxWidth="@dimen/module_push_button_maxWidth"
android:maxLength="6"
android:text="忽略"
android:textColor="#FFFFFF"
android:textSize="@dimen/module_push_title_text_size"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>
<FrameLayout
android:id="@+id/module_push_progress_bar_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/module_push_progress_bar_frame_marginTop"
android:layout_marginEnd="@dimen/module_push_progress_bar_frame_marginEnd"
android:background="@drawable/module_push_decrease_timer_bkg"
android:paddingLeft="@dimen/module_push_progress_bar_frame_padding"
android:paddingRight="@dimen/module_push_progress_bar_frame_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/module_push_timer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#80FFFFFF"
android:textSize="@dimen/module_push_ui_timer_textSize"
tools:text="11s" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/module_push_ui_width_vertical"
android:layout_height="wrap_content"
android:background="@drawable/module_push_item_background"
android:background="@drawable/module_push_item_background_origin"
android:maxHeight="@dimen/module_push_item_maxHeight_vertical"
android:orientation="vertical"
android:paddingLeft="@dimen/module_push_ui_app_icon_leftMargin_vertical"

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<dimen name="module_push_ui_height">230px</dimen>
<dimen name="module_push_ui_image_width">230px</dimen>
<dimen name="module_push_ui_image_height">230px</dimen>
<dimen name="module_push_ui_image_corner">30px</dimen>
<dimen name="module_push_ui_app_icon_leftMargin">21px</dimen>
<dimen name="module_push_ui_app_icon_topMargin">34px</dimen>
<dimen name="module_push_ui_app_icon_goneTopMargin">33px</dimen>
<dimen name="module_push_line_width">2px</dimen>
<dimen name="module_push_line_height">120px</dimen>
<dimen name="module_push_line_margin_left">30px</dimen>
<dimen name="module_push_check_margin">55px</dimen>
<dimen name="module_push_check_text_size">42px</dimen>
<dimen name="module_push_check_width">208px</dimen>
<dimen name="module_push_title_mix_width">394px</dimen>
<dimen name="module_push_ui_title_textSize">42px</dimen>
<dimen name="module_push_ui_content_width">567px</dimen>
<dimen name="module_push_ui_content_height">100px</dimen>
<dimen name="module_push_ui_content_marginTop">20px</dimen>
<dimen name="module_push_ui_content_marginBottom">34px</dimen>
<dimen name="module_push_ui_title_text_size">34px</dimen>
<dimen name="module_push_dialog_check_width">1200px</dimen>
<dimen name="module_push_dialog_check_height">763px</dimen>
<dimen name="module_push_dialog_check_bg_corner">32px</dimen>
<dimen name="module_push_dialog_close_width">107px</dimen>
<dimen name="module_push_dialog_close_height">107px</dimen>
<dimen name="module_push_dialog_close_margin">40px</dimen>
<dimen name="module_push_dialog_title_margin">54px</dimen>
<dimen name="module_push_dialog_title_size">56px</dimen>
<dimen name="module_push_dialog_content_width">1000px</dimen>
<dimen name="module_push_dialog_content_margin_top">33px</dimen>
<dimen name="module_push_dialog_content_size">43px</dimen>
<dimen name="module_push_ui_margin_top">20px</dimen>
</resources>

View File

@@ -4,4 +4,7 @@
<color name="module_push_item_title_textColor">#FFFFFF</color>
<color name="module_push_item_content_textColor">#B2FFFFFF</color>
<color name="module_push_item_time_textColor">#999999</color>
<color name="module_push_item_line_color">#B3FFFFFF</color>
<color name="module_push_check_color">#5A8EFD</color>
<color name="module_push_check_dialog_bg_color">#E63B4577</color>
</resources>

View File

@@ -98,4 +98,29 @@
<dimen name="module_push_item_image_width">118px</dimen>
<dimen name="module_push_item_image_height">86px</dimen>
<dimen name="module_push_panel_bkg_padding">8px</dimen>
<dimen name="module_push_ui_content_marginBottom">34px</dimen>
<dimen name="module_push_ui_content_width">567px</dimen>
<dimen name="module_push_ui_content_height">100px</dimen>
<dimen name="module_push_line_width">2px</dimen>
<dimen name="module_push_line_height">120px</dimen>
<dimen name="module_push_line_margin_left">30px</dimen>
<dimen name="module_push_check_margin">55px</dimen>
<dimen name="module_push_check_text_size">42px</dimen>
<dimen name="module_push_check_width">208px</dimen>
<dimen name="module_push_dialog_check_width">1200px</dimen>
<dimen name="module_push_dialog_check_height">763px</dimen>
<dimen name="module_push_dialog_check_bg_corner">32px</dimen>
<dimen name="module_push_dialog_close_width">107px</dimen>
<dimen name="module_push_dialog_close_height">107px</dimen>
<dimen name="module_push_dialog_close_margin">40px</dimen>
<dimen name="module_push_dialog_title_margin">54px</dimen>
<dimen name="module_push_dialog_title_size">56px</dimen>
<dimen name="module_push_dialog_content_width">1000px</dimen>
<dimen name="module_push_dialog_content_margin_top">33px</dimen>
<dimen name="module_push_dialog_content_size">43px</dimen>
<dimen name="module_push_ui_margin_top">20px</dimen>
</resources>

View File

@@ -3,4 +3,5 @@
<string name="module_push_str_delete">清除</string>
<string name="module_push_str_clear">清空历史消息</string>
<string name="module_push_str_not_data">暂无消息</string>
<string name="module_push_check">查看</string>
</resources>

View File

@@ -60,6 +60,8 @@ dependencies {
implementation project(':modules:mogo-module-common')
implementation project(':core:mogo-core-data')
implementation project(':core:mogo-core-res')
implementation project(':core:mogo-core-function-call')
}
}

View File

@@ -18,6 +18,7 @@ import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.module.common.utils.CarSeries;
import com.mogo.module.service.dispatch.DispatchAutoPilotManager;
import com.mogo.module.service.location.MogoRTKLocation;
import com.mogo.module.service.routeoverlay.MogoRouteOverlayManager;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
@@ -106,6 +107,7 @@ public class MogoServiceProvider implements IMogoModuleProvider {
MogoServices.getInstance().preInit( context );
MogoServices.getInstance().init( AbsMogoApplication.getApp() );
DispatchAutoPilotManager.getInstance().initSocket(context);
MogoRouteOverlayManager.getInstance(context).init();
UiThreadHandler.postDelayed( () -> {
}, 5_000L );
}

View File

@@ -2,7 +2,7 @@ package com.mogo.module.service.autopilot;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
import com.mogo.eagle.core.data.autopilot.RemoteControlAutoPilotParameters;
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
import com.mogo.service.cloud.socket.IMogoSocketManager;
import com.mogo.utils.logger.Logger;

View File

@@ -10,7 +10,11 @@ import android.os.Handler;
import android.os.Message;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.eagle.core.data.autopilot.AdasOCHData;
import com.mogo.eagle.core.data.autopilot.RemoteControlAutoPilotParameters;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.function.api.hmi.autopilot.IMoGoCheckAutoPilotBtnListener;
import com.mogo.eagle.core.function.call.hmi.CallerHmiListenerManager;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
import com.mogo.module.common.MogoApisHandler;
@@ -19,10 +23,7 @@ import com.mogo.module.service.dispatch.model.DispatchServiceModel;
import com.mogo.module.service.dispatch.model.IDispatch;
import com.mogo.service.IMogoServiceApis;
import com.mogo.service.adas.IMogoAdasOCHCallback;
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
import com.mogo.service.adas.entity.AdasOCHData;
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
import com.mogo.service.entrance.IMogoEntranceAutopilotStatusClickListener;
import com.mogo.utils.logger.Logger;
import java.util.ArrayList;
@@ -31,7 +32,7 @@ import java.util.List;
//负责监听自动驾驶状态并进行状态上报,自动驾驶路线上报,接收调度指令展示指令弹窗
public class DispatchAutoPilotManager implements IMogoOnMessageListener<DispatchAdasAutoPilotLocReceiverBean>
, IDispatchRemindClickListener
, IMogoCarLocationChangedListener2, IMogoAdasOCHCallback, IMogoEntranceAutopilotStatusClickListener {
, IMogoCarLocationChangedListener2, IMogoAdasOCHCallback, IMoGoCheckAutoPilotBtnListener {
private static final String TAG = "DispatchAutoPilotManager";
private static volatile DispatchAutoPilotManager instance;
@@ -95,7 +96,7 @@ public class DispatchAutoPilotManager implements IMogoOnMessageListener<Dispatch
.registerCarLocationChangedListener(TAG, this);
mApis.getAdasControllerApi()
.addAdasOCHCallback(this);
mApis.getEntranceButtonController().addEntranceAutopilotStatusClickListener(this);
CallerHmiListenerManager.INSTANCE.addCheckAutoPilotBtnListener(TAG, this);
dispatchDialogManager = DispatchDialogManager.getInstance(context);
dispatchDialogManager.addIDispatchRemindListener(this);
handler.sendEmptyMessageDelayed(MSG_TYPE_UPLOAD_AUTOPILOT_STATUS, 1000L);
@@ -210,15 +211,18 @@ public class DispatchAutoPilotManager implements IMogoOnMessageListener<Dispatch
}
@Override
public void click() {
// 确保到达终点后,再次点击,不会有回馈,并且在下次调开始时,才会重置
if (isArriveEnd) {
return;
}
//todo 确认是否要根据停靠时自动驾驶状态,再次开启自动驾驶
// 确保处于调度中并且返回的自动驾驶状态为1才开启自动驾驶
if (isDispatch ) {
startAutoPilot();
public void onCheck(boolean isChecked) {
if (isChecked) {
// 确保到达终点后,再次点击,不会有回馈,并且在下次调开始时,才会重置
if (isArriveEnd) {
return;
}
//todo 确认是否要根据停靠时自动驾驶状态,再次开启自动驾驶
// 确保处于调度中并且返回的自动驾驶状态为1才开启自动驾驶
// 上述等待鄂州项目复盘后,产品输出完成方案后再进操作!!!
if (isDispatch) {
startAutoPilot();
}
}
}

View File

@@ -38,7 +38,7 @@ import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.R;
import com.mogo.module.service.status.EnvStatusManager;
import com.mogo.module.service.timedelay.TimeDelayUploadManager;
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
import com.mogo.eagle.core.data.autopilot.RemoteControlAutoPilotParameters;
import com.mogo.service.adas.entity.ADASCarStateInfo;
import com.mogo.service.adas.entity.ADASRecognizedResult;
import com.mogo.service.entrance.ButtonIndex;

View File

@@ -0,0 +1,71 @@
package com.mogo.module.service.routeoverlay;
import android.content.Context;
import android.location.Location;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.drawer.MarkerDrawer;
import com.mogo.service.adas.IMogoAdasRouteCallBack;
import java.util.List;
public class MogoRouteOverlayManager implements IMogoCarLocationChangedListener2 {
private static volatile MogoRouteOverlayManager sInstance;
private Context mContext;
private MogoRouteOverlayManager(Context context){
mContext = context;
}
public void init() {
MogoApisHandler.getInstance().getApis().getAdasControllerApi().addAdasAutopilotRouteCallBack(new IMogoAdasRouteCallBack(){
@Override
public void routeResult(List<MogoLatLng> routeList) {
RouteOverlayDrawer.getInstance(mContext).putRouteList(routeList);
}
});
}
public static MogoRouteOverlayManager getInstance(Context context) {
if (sInstance == null) {
synchronized (MogoRouteOverlayManager.class) {
if (sInstance == null) {
sInstance = new MogoRouteOverlayManager(context);
}
}
}
return sInstance;
}
@Override
public void onCarLocationChanged2(Location latLng) {
updateLocation(latLng);
}
@Override
public void onCarLocationChanged(MogoLatLng latLng) {
}
public void updateLocation(Location location){
if (location == null){
return;
}
//坐标转换
MogoLocation loc = new MogoLocation();
loc.setTime(loc.getTime());
loc.setAccuracy(location.getAccuracy());
loc.setSpeed(location.getSpeed());
loc.setLongitude(location.getLongitude());
loc.setLatitude(location.getLatitude());
loc.setAltitude(location.getAltitude());
loc.setBearing(location.getBearing());
loc.setProvider(location.getProvider());
RouteOverlayDrawer.getInstance(mContext).drawRouteOverlay(loc);
}
}

View File

@@ -0,0 +1,114 @@
package com.mogo.module.service.routeoverlay;
import android.content.Context;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.overlay.IMogoOverlayManager;
import com.mogo.map.overlay.IMogoPolyline;
import com.mogo.map.overlay.MogoPolylineOptions;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.drawer.MarkerDrawer;
import com.mogo.module.common.utils.LocationUtils;
import com.mogo.utils.ColorUtils;
import java.util.ArrayList;
import java.util.List;
public class RouteOverlayDrawer {
private IMogoPolyline mMoGoPolyline;
// 连接线参数
private MogoPolylineOptions mPolylineOptions;
// 线路径集合
private List<MogoLatLng> mPolylinePointList;
// 渐变色
private List<Integer> mPolylineColors;
private Context mContext;
IMogoOverlayManager mogoOverlayManager;
private static volatile RouteOverlayDrawer sInstance;
private RouteOverlayDrawer(Context context) {
mPolylineOptions = new MogoPolylineOptions();
// 绘制路径集合
mPolylinePointList = new ArrayList<>();
// 引导线颜色
mPolylineColors = new ArrayList<>();
mContext = context;
mogoOverlayManager = MogoApisHandler.getInstance().getApis().getMapServiceApi().getOverlayManager(mContext);
}
public static RouteOverlayDrawer getInstance(Context context) {
if (sInstance == null) {
synchronized (RouteOverlayDrawer.class) {
if (sInstance == null) {
sInstance = new RouteOverlayDrawer(context);
}
}
}
return sInstance;
}
public synchronized void release() {
sInstance = null;
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return sInstance;
}
private List<MogoLatLng> mRouteList;
public void drawRouteOverlay(MogoLocation location){
if (mRouteList == null ){
clearMogoRouteOverlay();
return;
}
if (mRouteList.size() >0){
//adas回调导航路径 绘制引导线
draw(location,mRouteList);
}
}
/**
* 绘制最优路线
*
* @param routelist 要绘制的经纬度度集合
*/
public IMogoPolyline draw(MogoLocation carLocal, List<MogoLatLng> routelist) {
clearMogoRouteOverlay();
if (routelist != null) {
// 将当前车辆位置放进去
mPolylinePointList.add(new MogoLatLng(carLocal.getLatitude(), carLocal.getLongitude()));
// 过滤后台推送的推荐路线集合
for (MogoLatLng polyline : routelist) {
//需要剔除已经行驶过的经纬度,这里需要比对推荐路线集合中的点是否在当前车辆行驶方向前面如果不在则抛弃
if (LocationUtils.isPointOnCarFront(carLocal, polyline)) {
mPolylinePointList.add(polyline);
}
}
mPolylineColors.addAll(ColorUtils.getGradientAlpha("#002965ED", "#FF2965ED", "#002965ED", mPolylinePointList.size()));
// 替换路径集合
mPolylineOptions.points(mPolylinePointList);
// 线条粗细,渐变,渐变色值
mPolylineOptions.width(25).useGradient(true).colorValues(mPolylineColors);
// 绘制线
mMoGoPolyline = mogoOverlayManager.addPolyline(mPolylineOptions);
}
return mMoGoPolyline;
}
public void clearMogoRouteOverlay(){
if (mMoGoPolyline != null) {
mMoGoPolyline.remove();
mPolylinePointList.clear();
mPolylineColors.clear();
}
}
public void putRouteList(List<MogoLatLng> routeList) {
this.mRouteList = routeList;
}
}

View File

@@ -10,7 +10,7 @@
android:paddingStart="@dimen/module_services_panel_item_start"
android:paddingBottom="@dimen/module_services_panel_item_padding">
<com.mogo.module.common.widget.CustomCircleImageView
<com.mogo.eagle.core.widget.CustomCircleImageView
android:id="@+id/module_services_id_panel_item_avatar"
android:layout_width="@dimen/module_services_panel_item_avatar_size"
android:layout_height="@dimen/module_services_panel_item_avatar_size"

View File

@@ -85,6 +85,7 @@ dependencies {
implementation project(':modules:mogo-module-service')
implementation project(':modules:mogo-module-obu')
implementation project(':core:mogo-core-res')
implementation project(':core:mogo-core-data')
implementation project(':core:mogo-core-function-call')
}

View File

@@ -54,14 +54,6 @@ public class V2XConst {
public static final String V2X_ACC_OFF_TIME_STR = "v2x_acc_off_time_str";
public static final String V2X_STRATEGY_PUSH = "v2x_strategy_push";
public static final int STATE_ERROR = -1;
public static final int STATE_IDLE = 0;
public static final int STATE_PREPARING = 1;
public static final int STATE_PREPARED = 2;
public static final int STATE_PLAYING = 3;
public static final int STATE_PAUSED = 4;
public static final int STATE_PLAYBACK_COMPLETED = 5;
public static final int STATE_SEEKING = 6;
/**
* V2X 埋点

View File

@@ -11,6 +11,7 @@ import com.mogo.module.v2x.listener.V2XMessageListener_401011;
import com.mogo.module.v2x.listener.V2XMessageListener_401012;
import com.mogo.module.v2x.listener.V2XMessageListener_402000;
import com.mogo.module.v2x.listener.V2XMessageListener_401018;
import com.mogo.module.v2x.listener.V2XMessageListener_404000;
import com.mogo.utils.logger.Logger;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
@@ -36,6 +37,7 @@ public class V2XSocketManager {
private V2XMessageListener_401010 v2XMessageListener_401010;
private V2XMessageListener_402000 mV2XMessageListener_402000;
private V2XMessageListener_401018 mV2XMessageListener401018;
private V2XMessageListener_404000 mV2XMessageListener_404000;
private V2XSocketManager() {
}
@@ -66,6 +68,7 @@ public class V2XSocketManager {
register401007();
register401009();
register401020();
register404000();
registerWarningMsg();
// TODO 这里是前瞻需求,量产版本需要注释
@@ -120,6 +123,11 @@ public class V2XSocketManager {
.getMoGoSocketManager()
.unregisterOnMessageListener(402000, mV2XMessageListener_402000);
}
if (mV2XMessageListener_404000 != null) {
V2XServiceManager
.getMoGoSocketManager()
.unregisterOnMessageListener(404000, mV2XMessageListener_404000);
}
}
/**
@@ -245,6 +253,17 @@ public class V2XSocketManager {
);
}
public void register404000() {
mV2XMessageListener_404000 = new V2XMessageListener_404000();
// 道路事件,在线车辆绘制
V2XServiceManager
.getMoGoSocketManager()
.registerOnMessageListener(
404000,
mV2XMessageListener_404000
);
}
/**
* * 车路云—场景预警-V1.0
* * http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=52829799

View File

@@ -0,0 +1,26 @@
package com.mogo.module.v2x.listener;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
import com.mogo.eagle.core.data.v2x.AdvanceWarningBean;
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.utils.GsonUtil;
/**
* @author chenfufeng
* @description 路口碰撞预警、盲区预警等
* @since: 2021/9/23
*/
public class V2XMessageListener_404000 implements IMogoOnMessageListener<AdvanceWarningBean> {
@Override
public Class target() {
return AdvanceWarningBean.class;
}
@Override
public void onMsgReceived(AdvanceWarningBean message) {
// 将接收到的数据转换成最优车道推荐的场景数据
Logger.i(MODULE_NAME, "V2XMessageListener_404000" + GsonUtil.jsonFromObject(message));
}
}

View File

@@ -28,6 +28,7 @@ import com.mogo.module.common.utils.CarSeries;
import com.mogo.module.service.ServiceConst;
import com.mogo.module.service.Utils;
import com.mogo.module.v2x.MoGoV2XServicePaths;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XConst;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.entity.net.V2XSpecialCarRes.V2XMarkerEntity;
@@ -288,7 +289,7 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager {
MogoMarkerOptions options = new MogoMarkerOptions().object(roadEventEntity)
.latitude(roadEventEntity.getLocation().getLat()).longitude(roadEventEntity.getLocation().getLon());
options.anchor(0.5f, 0.5f);
options.icon3DRes(com.mogo.module.common.R.raw.special_vehicle);
options.icon3DRes(R.raw.special_vehicle);
options.anchorColor("#FFBF29FF");
m3DMarker = V2XServiceManager.getMarkerManager().addMarker(V2X_EVENT_ALARM_POI, options);
m3DMarker.setToTop();

View File

@@ -14,7 +14,7 @@ import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.listener.V2XWindowStatusListener;
import com.mogo.module.v2x.scenario.view.IV2XWindow;
import com.mogo.module.v2x.view.TextureVideoView;
import com.mogo.eagle.core.widget.TextureVideoView;
import com.mogo.utils.logger.Logger;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;

View File

@@ -1,366 +0,0 @@
package com.mogo.module.v2x.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import androidx.annotation.Nullable;
import com.mogo.module.v2x.utils.ImageUtil;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
/**
* 加载图片帧动画
*/
public class AnimationView extends View implements Handler.Callback {
public static final int DEFAULT_ANIM_TIME = 20;
public static final int PROCESS_DATA = 1;
public static final int PROCESS_ANIM_FINISH = 1 << 1;
public static final int PROCESS_DELAY = 1 << 2;
public AnimData mCurAnimData;
public int mCurAnimPos;
public boolean mIsRepeat;
public int mAnimTime;
private Handler mHandler;
private ProcessAnimThread mProcessThread;
private Bitmap mCurShowBmp;
private List<AnimData> mAnimDataList = new ArrayList<>();
public AnimationView(Context context) {
this(context, null);
}
public AnimationView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public AnimationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mHandler = new Handler(this);
mProcessThread = new ProcessAnimThread(getContext(), mHandler);
mAnimTime = DEFAULT_ANIM_TIME;
}
public void setIsRepeat(boolean repeat) {
mIsRepeat = repeat;
}
private int mGravity;
public void setGravity(int gravity) {
mGravity = gravity;
invalidate();
}
public void setData(List<AnimData> list) {
if (list != null) {
mAnimDataList.clear();
mAnimDataList.addAll(list);
}
}
private Matrix mTempMatrix = new Matrix();
@Override
protected void onDraw(Canvas canvas) {
if (mCurShowBmp != null && !mCurShowBmp.isRecycled()) {
int x = 0;
int y = 0;
float scaleX = 1f;
float scaleY = 1f;
switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.LEFT:
x = 0;
break;
case Gravity.RIGHT:
x = this.getWidth() - mCurShowBmp.getWidth();
break;
case Gravity.CENTER_HORIZONTAL:
x = (this.getWidth() - mCurShowBmp.getWidth()) / 2;
break;
case Gravity.FILL_HORIZONTAL: {
int w = mCurShowBmp.getWidth();
if (w > 0) {
scaleX = (float) this.getWidth() / (float) w;
}
break;
}
default:
break;
}
switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
case Gravity.TOP:
y = 0;
break;
case Gravity.BOTTOM:
y = this.getHeight() - mCurShowBmp.getHeight();
break;
case Gravity.CENTER_VERTICAL:
y = (this.getHeight() - mCurShowBmp.getHeight()) / 2;
break;
case Gravity.FILL_VERTICAL: {
int h = mCurShowBmp.getHeight();
if (h > 0) {
scaleY = (float) this.getHeight() / (float) h;
}
break;
}
default:
break;
}
if (scaleX == 1 && scaleY != 1) {
scaleX = scaleY;
switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.RIGHT:
x = this.getWidth() - (int) (mCurShowBmp.getWidth() * scaleX);
break;
case Gravity.CENTER_HORIZONTAL:
x = (this.getWidth() - (int) (mCurShowBmp.getWidth() * scaleX)) / 2;
break;
}
} else if (scaleX != 1 && scaleY == 1) {
scaleY = scaleX;
switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
case Gravity.BOTTOM:
y = this.getHeight() - (int) (mCurShowBmp.getHeight() * scaleY);
break;
case Gravity.CENTER_VERTICAL:
y = (this.getHeight() - (int) (mCurShowBmp.getHeight() * scaleY)) / 2;
break;
}
}
mTempMatrix.reset();
mTempMatrix.postScale(scaleX, scaleY);
mTempMatrix.postTranslate(x, y);
canvas.drawBitmap(mCurShowBmp, mTempMatrix, null);
}
}
private boolean mHasStarted = false;
public void start() {
mHasStarted = true;
if (mWidth == 0 || mHeight == 0) {
return;
}
startPlay();
}
private void startPlay() {
if (mAnimDataList != null && mAnimDataList.size() > 0) {
mCurAnimPos = 0;
AnimData animData = mAnimDataList.get(mCurAnimPos);
mCurShowBmp = ImageUtil.getBitmap(getContext(), animData.filePath, mWidth, mHeight);
invalidate();
if (mListener != null) {
mListener.onAnimChange(mCurAnimPos, mCurShowBmp);
}
checkIsPlayNext();
}
}
private void playNext(final int curAnimPosition) {
Message msg = Message.obtain();
msg.what = PROCESS_DELAY;
msg.arg1 = curAnimPosition;
mHandler.sendMessageDelayed(msg, mAnimTime);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
quit();
}
private void quit() {
mHasStarted = false;
if (mProcessThread != null) {
mProcessThread.clearAll();
}
}
private int mWidth;
private int mHeight;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
if (mProcessThread != null) {
mProcessThread.setSize(w, h);
}
if (mHasStarted) {
startPlay();
}
}
private boolean mHavePause = false;
public void pause() {
mHavePause = true;
mHandler.removeMessages(PROCESS_DELAY);
}
public void resume() {
if (mHavePause && mHasStarted) {
checkIsPlayNext();
}
}
@Override
public boolean handleMessage(Message msg) {
//此 handleMessage 在主线程被调用
switch (msg.what) {
case PROCESS_ANIM_FINISH: {
Bitmap bitmap = (Bitmap) msg.obj;
if (bitmap != null) {
if (mCurShowBmp != null) {
mCurShowBmp.recycle();
mCurShowBmp = null;
}
mCurShowBmp = bitmap;
if (mListener != null) {
mListener.onAnimChange(mCurAnimPos, bitmap);
}
invalidate();
}
checkIsPlayNext();
break;
}
case PROCESS_DELAY: {
int curAnimPosition = msg.arg1;
AnimData data = mAnimDataList.get(curAnimPosition);
mProcessThread.processData(data);
break;
}
}
return true;
}
private void checkIsPlayNext() {
mCurAnimPos++;
if (mCurAnimPos >= mAnimDataList.size()) {
if (mIsRepeat) {
mCurAnimPos = 0;
playNext(mCurAnimPos);
} else {
if (mListener != null) {
mListener.onAnimEnd();
}
}
} else {
playNext(mCurAnimPos);
}
}
private AnimCallBack mListener;
public void setAnimCallBack(AnimCallBack callBack) {
mListener = callBack;
}
public interface AnimCallBack {
void onAnimChange(int position, Bitmap bitmap);
void onAnimEnd();
}
public static class AnimData {
public Object filePath;
}
public static class ProcessAnimThread {
private HandlerThread mHandlerThread;
private Handler mProcessHandler;
private Handler mUiHandler;
private AnimData mCurAnimData;
private int mWidth;
private int mHeight;
private WeakReference<Context> mContext;
public ProcessAnimThread(Context context, Handler handler) {
mUiHandler = handler;
mContext = new WeakReference<Context>(context);
init();
}
public void setSize(int width, int height) {
mWidth = width;
mHeight = height;
}
private void init() {
mHandlerThread = new HandlerThread("process_anim_thread");
mHandlerThread.start();
mProcessHandler = new Handler(mHandlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// 消息是在子线程 HandlerThread 里面被处理,所以这里的 handleMessage 在
//子线程里被调用
switch (msg.what) {
case PROCESS_DATA: {
AnimData animData = (AnimData) msg.obj;
Bitmap bitmap = ImageUtil.getBitmap(mContext.get(), animData.filePath, mWidth, mHeight);
if (bitmap != null) {
Message finishMsg = Message.obtain();
finishMsg.what = PROCESS_ANIM_FINISH;
finishMsg.obj = bitmap;
//消息处理完毕,使用主线程的 Handler 将消息发送到主线程
mUiHandler.sendMessage(finishMsg);
}
break;
}
}
return true;
}
});
}
public void processData(AnimData animData) {
if (animData != null) {
Message msg = Message.obtain();
msg.what = PROCESS_DATA;
msg.obj = animData;
mProcessHandler.sendMessage(msg);
}
}
public void clearAll() {
mHandlerThread.quit();
mHandlerThread = null;
}
}
}

View File

@@ -17,6 +17,7 @@ import com.mogo.cloud.trafficlive.api.ITrafficCarLiveCallBack;
import com.mogo.cloud.trafficlive.api.MoGoAiCloudTrafficLive;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.widget.RoundLayout;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XServiceManager;

View File

@@ -1,131 +0,0 @@
package com.mogo.module.v2x.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.customview.widget.ViewDragHelper;
import com.mogo.module.v2x.V2XConst;
import com.mogo.utils.logger.Logger;
import org.jetbrains.annotations.NotNull;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/5/25 11:13 AM
* desc :
* version: 1.0
*/
public class GestureTopCloseLayout extends ConstraintLayout {
private ViewDragHelper mViewDragHelper;
private ViewCloseListener mViewCloseListener;
public GestureTopCloseLayout(Context context) {
this(context, null);
}
public GestureTopCloseLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GestureTopCloseLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
private int mTop;
@Override
public boolean tryCaptureView(@NotNull View child, int pointerId) {
return true;
}
@Override
public int clampViewPositionVertical(@NotNull View child, int top, int dy) {
final int bottomBound = getPaddingTop();
return Math.min(top, bottomBound);
}
@Override
public int clampViewPositionHorizontal(@NotNull View child, int left, int dx) {
//取得左边界的坐标
final int leftBound = getPaddingLeft();
//取得右边界的坐标
final int rightBound = getWidth() - child.getWidth() - child.getPaddingRight() - leftBound;
//这个地方的含义就是 如果left的值 在leftbound和rightBound之间 那么就返回left
//如果left的值 比 leftbound 还要小 那么就说明 超过了左边界 那我们只能返回给他左边界的值
//如果right的值 比 rightbound 还要大 那么就说明 超过了右边界,那我们只能返回给他右边界的值
return Math.min(Math.max(left, leftBound), rightBound);
}
@Override //不重写该方法默认返回0返回0时若还设置了点击事件则水平方向不能移动
public int getViewHorizontalDragRange(@NotNull View child) {
return getMeasuredWidth() - child.getMeasuredWidth();
}
@Override //不重写该方法默认返回0返回0时若还设置了点击事件则竖直方向不能移动
public int getViewVerticalDragRange(@NotNull View child) {
return getMeasuredHeight() - child.getMeasuredHeight();
}
@Override
public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
Logger.w(V2XConst.MODULE_NAME, "onViewPositionChanged==top=" + top +
" changedView.getHeight()==" + changedView.getHeight());
if (top < 0) {
mTop = top;
if (top <= -changedView.getHeight()) {
mViewDragHelper.smoothSlideViewTo(changedView, 0, getPaddingTop());
invalidate();
if (mViewCloseListener != null) {
mViewCloseListener.onClose();
}
}
}
}
//手指释放的时候回调
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
Logger.w(V2XConst.MODULE_NAME, "onViewReleased==mTop=" + mTop + " getHeight=" + getHeight());
if (mTop < 0) {
mViewDragHelper.settleCapturedViewAt(0, -getHeight());
invalidate();
}
}
});
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return mViewDragHelper.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mViewDragHelper.processTouchEvent(event);
return true;
}
@Override
public void computeScroll() {
if (mViewDragHelper.continueSettling(true)) {
invalidate();
}
}
public void setViewCloseListener(ViewCloseListener mViewCloseListener) {
this.mViewCloseListener = mViewCloseListener;
}
public interface ViewCloseListener {
void onClose();
}
}

View File

@@ -1,78 +0,0 @@
package com.mogo.module.v2x.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.mogo.module.v2x.R;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/5/27 2:08 PM
* desc :
* version: 1.0
*/
public class RoundConstraintLayout extends ConstraintLayout {
private float roundLayoutRadius = 14f;
private Path roundPath;
private RectF rectF;
public RoundConstraintLayout(Context context) {
this(context, null);
}
public RoundConstraintLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundLayout);
roundLayoutRadius = typedArray.getDimensionPixelSize(R.styleable.RoundLayout_roundLayoutRadius, (int) roundLayoutRadius);
typedArray.recycle();
init();
}
public RoundConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void init() {
setWillNotDraw(false);//如果你继承的是ViewGroup,注意此行,否则draw方法是不会回调的;
roundPath = new Path();
rectF = new RectF();
}
private void setRoundPath() {
//添加一个圆角矩形到path中, 如果要实现任意形状的View, 只需要手动添加path就行
roundPath.addRoundRect(rectF, roundLayoutRadius, roundLayoutRadius, Path.Direction.CW);
}
public void setRoundLayoutRadius(float roundLayoutRadius) {
this.roundLayoutRadius = roundLayoutRadius;
setRoundPath();
postInvalidate();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
rectF.set(0f, 0f, getMeasuredWidth(), getMeasuredHeight());
setRoundPath();
}
@Override
public void draw(Canvas canvas) {
if (roundLayoutRadius > 0f) {
canvas.clipPath(roundPath);
}
super.draw(canvas);
}
}

View File

@@ -1,79 +0,0 @@
package com.mogo.module.v2x.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
import com.mogo.module.v2x.R;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/3/25 11:39 AM
* desc :
* version: 1.0
*/
public class RoundLayout extends RelativeLayout {
private float roundLayoutRadius = 14f;
private Path roundPath;
private RectF rectF;
public RoundLayout(Context context) {
this(context, null);
}
public RoundLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundLayout);
roundLayoutRadius = typedArray.getDimensionPixelSize(R.styleable.RoundLayout_roundLayoutRadius, (int) roundLayoutRadius);
typedArray.recycle();
init();
}
private void init() {
setWillNotDraw(false);//如果你继承的是ViewGroup,注意此行,否则draw方法是不会回调的;
roundPath = new Path();
rectF = new RectF();
}
private void setRoundPath() {
//添加一个圆角矩形到path中, 如果要实现任意形状的View, 只需要手动添加path就行
roundPath.addRoundRect(rectF, roundLayoutRadius, roundLayoutRadius, Path.Direction.CW);
}
public void setRoundLayoutRadius(float roundLayoutRadius) {
this.roundLayoutRadius = roundLayoutRadius;
setRoundPath();
postInvalidate();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
rectF.set(0f, 0f, getMeasuredWidth(), getMeasuredHeight());
setRoundPath();
}
@Override
public void draw(Canvas canvas) {
if (roundLayoutRadius > 0f) {
canvas.clipPath(roundPath);
}
super.draw(canvas);
}
}

View File

@@ -1,590 +0,0 @@
package com.mogo.module.v2x.view;
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.TextureView;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.MediaController.MediaPlayerControl;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XConst;
import com.mogo.utils.logger.Logger;
import java.io.IOException;
import java.util.Map;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* Displays a video file. The VideoView class can load images from various
* sources (such as resources or content providers), takes care of computing its
* measurement from the video so that it can be used in any layout manager, and
* provides various display options such as scaling and tinting.
*/
public class TextureVideoView extends TextureView implements MediaPlayerControl {
private String TAG = "V2XModuleProvider";
// settable by the client
private Uri mUri;
private Map<String, String> mHeaders;
private int mDuration;
// all possible internal states
private int mCurrentState = V2XConst.STATE_IDLE;
private int mTargetState = mCurrentState, mTagetStateBackup = mCurrentState;
private int mPrepareState = V2XConst.STATE_PREPARED;
// All the stuff we need for playing and showing a video
private Surface mSurface = null;
private MediaPlayer mMediaPlayer = null;
private int mVideoWidth, mVideoHeight;
private OnCompletionListener mOnCompletionListener;
private MediaPlayer.OnPreparedListener mOnPreparedListener;
private int mCurrentBufferPercentage;
private OnErrorListener mOnErrorListener;
private MediaPlayer.OnInfoListener mOnInfoListener;
private int mSeekWhenPrepared;
private boolean isFocusLoss = true;
private boolean isSuspendFromActivity = false;
private int progressWhileSuspend = 0;
public static final int MEDIA_INFO_VIDEO_NOT_SUPPORTED = 860;
public static final int MEDIA_INFO_AUDIO_NOT_SUPPORTED = 862;
public TextureVideoView(Context context) {
super(context);
initVideoView();
}
public TextureVideoView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
initVideoView();
}
public TextureVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initVideoView();
}
@SuppressLint("NewApi")
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(TextureVideoView.class.getName());
}
@SuppressLint("NewApi")
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(TextureVideoView.class.getName());
}
private void initVideoView() {
mVideoWidth = 0;
mVideoHeight = 0;
setSurfaceTextureListener(mSurfaceTextureListener);
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
mCurrentState = V2XConst.STATE_IDLE;
mTargetState = V2XConst.STATE_IDLE;
}
public boolean requestAudioFocus() {
return true;
}
public void setVideoPath(String path) {
setVideoURI(Uri.parse(path));
}
public void setVideoURI(Uri uri) {
setVideoURI(uri, null);
}
public void setVideoURI(Uri uri, Map<String, String> headers) {
if (uri == null) {
Logger.i(MODULE_NAME, "setVideoURI--- uri = null");
} else {
Logger.i(MODULE_NAME, "setVideoURI--- uri = " + uri.getPath());
}
mUri = uri;
mHeaders = headers;
mSeekWhenPrepared = 0;
isFocusLoss = !requestAudioFocus();
openVideo();
requestLayout();
invalidate();
}
public void stopPlayback() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
mTargetState = mCurrentState = V2XConst.STATE_IDLE;
}
}
@SuppressLint("NewApi")
private void openVideo() {
Logger.i(MODULE_NAME, "openVideo");
if (mUri == null) {
Logger.i(MODULE_NAME, "mUri == null ");
}
if (mSurface == null) {
Logger.i(MODULE_NAME, "mSurface == null ");
}
if (mUri == null || mSurface == null || isSuspendFromActivity) {
Logger.i(MODULE_NAME, "isSuspendFromActivity = " + isSuspendFromActivity);
return;
}
release(false);
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mDuration = -1;
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
mMediaPlayer.setOnInfoListener(mInfoListener);
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(getContext(), mUri, mHeaders);
if (mSurface != null) {
/*
Canvas mCanvas = mSurface.lockCanvas(new Rect());
mCanvas.drawColor(Color.BLACK);
mSurface.unlockCanvasAndPost(mCanvas);
invalidate();
*/
mMediaPlayer.setSurface(mSurface);
}
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setVolume(0, 0);
mMediaPlayer.prepare();
mPrepareState = mCurrentState = V2XConst.STATE_PREPARING;
} catch (IOException | SecurityException | IllegalStateException | IllegalArgumentException ex) {
ex.printStackTrace();
onError();
}
}
private void onError() {
mTargetState = mCurrentState = V2XConst.STATE_ERROR;
if (mErrorListener != null)
mErrorListener.onError(mMediaPlayer,
MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
}
MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() {
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
mVideoWidth = mp.getVideoWidth();
mVideoHeight = mp.getVideoHeight();
if (mVideoWidth != 0 && mVideoHeight != 0) {
Logger.d(MODULE_NAME, "OnVideoSizeChangedListener mVideoWidth:" + " mVideoWidth:" + mVideoWidth + " mVideoHeight:" + mVideoHeight);
}
}
};
MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
Logger.i(MODULE_NAME, "MediaPlayer.OnPreparedListener");
mPrepareState = mCurrentState = V2XConst.STATE_PREPARED;
mVideoWidth = mp.getVideoWidth();
mVideoHeight = mp.getVideoHeight();
int seekToPosition = mSeekWhenPrepared;
// Logger.i(MODULE_NAME, "seekToPosition = " + seekToPosition);
if (seekToPosition != 0) {
seekTo(seekToPosition);
}
if (mTargetState == V2XConst.STATE_PLAYING) {
start();
}
if (mOnPreparedListener != null) {
mOnPreparedListener.onPrepared(mMediaPlayer);
}
mp.setOnInfoListener((mp1, what, extra) -> {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
setBackgroundColor(Color.TRANSPARENT);
return true;
});
}
};
private OnCompletionListener mCompletionListener = new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
Logger.i(MODULE_NAME, "MediaPlayer.OnCompletionListener");
mTargetState = mCurrentState = V2XConst.STATE_PLAYBACK_COMPLETED;
if (mOnCompletionListener != null) {
mOnCompletionListener.onCompletion(mMediaPlayer);
}
}
};
private OnSeekCompleteListener mSeekCompleteListener = mp -> {
Logger.i(MODULE_NAME, "MediaPlayer.OnSeekCompleteListener");
try {
mCurrentState = mMediaPlayer.isPlaying() ? V2XConst.STATE_PLAYING : V2XConst.STATE_PAUSED;
} catch (Exception e) {
mCurrentState = V2XConst.STATE_PLAYING;
e.printStackTrace();
}
};
private OnErrorListener mErrorListener = new OnErrorListener() {
public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
Logger.i(MODULE_NAME, "MediaPlayer.onError");
mTargetState = mPrepareState = mCurrentState = V2XConst.STATE_ERROR;
if (mOnErrorListener != null) {
mOnErrorListener.onError(mMediaPlayer, framework_err,
impl_err);
}
release(false);
return true;
}
};
private MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
Logger.i(MODULE_NAME, "MediaPlayer.OnInfoListener---what = " + what + ";extra = " + extra);
int messageId = 0;
if (what == MEDIA_INFO_VIDEO_NOT_SUPPORTED) {
messageId = R.string.VideoView_info_text_video_not_supported;
} else if (what == MEDIA_INFO_AUDIO_NOT_SUPPORTED) {
messageId = R.string.file_not_support;
}
if (messageId != 0) {
if (mOnInfoListener != null) {
mOnInfoListener.onInfo(mp, what, extra);
}
return true;
}
return false;
}
};
private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Logger.i(MODULE_NAME, "MediaPlayer.OnBufferingUpdateListener");
mCurrentBufferPercentage = percent;
}
};
/**
* Register a callback to be invoked when the media file is loaded and ready
* to go.
*
* @param l The callback that will be run
*/
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
mOnPreparedListener = l;
}
/**
* Register a callback to be invoked when the end of a media file has been
* reached during playback.
*
* @param l The callback that will be run
*/
public void setOnCompletionListener(OnCompletionListener l) {
mOnCompletionListener = l;
}
/**
* Register a callback to be invoked when an error occurs during playback or
* setup. If no listener is specified, or if the listener returned false,
* VideoView will inform the user of any errors.
*
* @param l The callback that will be run
*/
public void setOnErrorListener(OnErrorListener l) {
mOnErrorListener = l;
}
public void setOnInfoListener(MediaPlayer.OnInfoListener l) {
mOnInfoListener = l;
}
SurfaceTextureListener mSurfaceTextureListener = new SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Logger.i(MODULE_NAME, "onSurfaceTextureAvailable");
mSurface = new Surface(surface);
openVideo();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
Logger.d(MODULE_NAME, "onSurfaceTextureSizeChanged mVideoWidth:" + " mVideoWidth:" + mVideoWidth + " mVideoHeight:" + mVideoHeight);
boolean isValidState = (mTargetState == V2XConst.STATE_PLAYING);
boolean hasValidSize = (mVideoWidth == width && mVideoHeight == height);
if (mMediaPlayer != null && isValidState && hasValidSize) {
if (mSeekWhenPrepared != 0) {
seekTo(mSeekWhenPrepared);
}
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
if (!isFocusLoss) start();
}
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Logger.i(MODULE_NAME, "onSurfaceTextureDestroyed");
mSurface = null;
release(false);
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
/*
* release the media player in any state
*/
private void release(boolean cleartargetstate) {
Logger.i(MODULE_NAME, "release ---cleartargetstate=" + cleartargetstate);
mCurrentState = V2XConst.STATE_IDLE;
if (cleartargetstate) {
mTargetState = V2XConst.STATE_IDLE;
new Thread(new Runnable() {
@Override
public void run() {
try {
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
try {
mMediaPlayer.stop();
} catch (IllegalStateException e) {
try {
this.wait(1000);
mMediaPlayer.stop();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
if (mMediaPlayer != null) {
mMediaPlayer.release();// release会做reset
}
mMediaPlayer = null;
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}).start();
} else {
if (mMediaPlayer != null) {
try {
mMediaPlayer.stop();
mMediaPlayer.reset();
mMediaPlayer.release();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
mMediaPlayer = null;
}
}
public boolean isPrepared() {
return mPrepareState == V2XConst.STATE_PREPARED
|| isSuspendFromActivity;
}
public void start() {
Logger.i(MODULE_NAME, "TextureVideoView---start");
if (isFocusLoss) {
mTagetStateBackup = V2XConst.STATE_PLAYING;
return;
}
//Logger.i(MODULE_NAME, "mCurrentState = " + mCurrentState);
if (isInPlaybackState()) {
Logger.i(MODULE_NAME, "MediaPlayer.start");
mMediaPlayer.start();
mCurrentState = V2XConst.STATE_PLAYING;
}
mTargetState = V2XConst.STATE_PLAYING;
}
public void pause() {
Logger.i(MODULE_NAME, "TextureVideoView---pause");
Logger.i(MODULE_NAME, "mCurrentState = " + mCurrentState);
if (isInPlaybackState()) {
if (mMediaPlayer.isPlaying()) {
Logger.i(MODULE_NAME, " MediaPlayer.pause");
mMediaPlayer.pause();
mCurrentState = V2XConst.STATE_PAUSED;
}
}
mTagetStateBackup = mTargetState = V2XConst.STATE_PAUSED;
}
public void suspend() {
Logger.i(MODULE_NAME, "TextureVideoView---suspend");
if (!isSuspendFromActivity) {
isSuspendFromActivity = true;
if (mMediaPlayer != null) {
if (isInPlaybackState()) {
progressWhileSuspend = mMediaPlayer.getCurrentPosition();
}
}
release(false);
}
}
public void resume() {
Logger.i(MODULE_NAME, "TextureVideoView---resume");
isSuspendFromActivity = false;
openVideo();
seekTo(progressWhileSuspend);
if (mTagetStateBackup == V2XConst.STATE_IDLE)
mTagetStateBackup = mTargetState;
Logger.i(MODULE_NAME, "isFocusLoss = " + isFocusLoss);
Logger.i(MODULE_NAME, "isInPlaybackState() = " + isInPlaybackState());
if (isFocusLoss) {
if (isInPlaybackState()) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
mCurrentState = V2XConst.STATE_PAUSED;
}
}
}
}
// cache duration as mDuration for faster access
public int getDuration() {
if (isInPlaybackState()) {
if (mDuration > 0) {
return mDuration;
}
mDuration = mMediaPlayer.getDuration();
return mDuration;
}
mDuration = -1;
return mDuration;
}
public int getCurrentPosition() {
if (isInPlaybackState()) {
return mMediaPlayer.getCurrentPosition();
}
return 0;
}
public void seekTo(int msec) {
Logger.i(MODULE_NAME, "TextureVideoView---seekTo---msec = " + msec);
if (isInPlaybackState() && mCurrentState != V2XConst.STATE_SEEKING
&& msec > 0 && msec < getDuration()) {
mCurrentState = V2XConst.STATE_SEEKING;
Logger.i(MODULE_NAME, "MediaPlayer.seekTo(msec) = " + msec);
mMediaPlayer.seekTo(msec);
mSeekWhenPrepared = 0;
} else {
mSeekWhenPrepared = msec;
progressWhileSuspend = msec;
}
}
public boolean isPlaying() {
return isInPlaybackState() && mMediaPlayer.isPlaying();
}
public int getBufferPercentage() {
if (mMediaPlayer != null) {
return mCurrentBufferPercentage;
}
return 0;
}
private boolean isInPlaybackState() {
return (mMediaPlayer != null && mCurrentState != V2XConst.STATE_ERROR
&& mCurrentState != V2XConst.STATE_IDLE && mCurrentState != V2XConst.STATE_PREPARING);
}
@Override
public boolean canPause() {
return false;
}
@Override
public boolean canSeekBackward() {
return false;
}
@Override
public boolean canSeekForward() {
return false;
}
public String getVideoPath() {
if (mUri != null) {
return mUri.getPath();
}
return null;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
setMeasuredDimension(width, height);
}
public boolean isPause() {
return mTargetState == V2XConst.STATE_PAUSED;
}
@Override
public int getAudioSessionId() {
return 0;
}
public int getCurrentState() {
Logger.i(MODULE_NAME, "mCurrentState == " + mCurrentState);
return mCurrentState;
}
}

View File

@@ -16,6 +16,7 @@ import androidx.core.content.ContextCompat;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.widget.RoundLayout;
import com.mogo.module.common.entity.MarkerCarInfo;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XServiceManager;

View File

@@ -15,6 +15,7 @@ import androidx.core.content.ContextCompat;
import com.mogo.cloud.trafficlive.api.ITrafficIntersectionLiveCallBack;
import com.mogo.cloud.trafficlive.api.MoGoAiCloudTrafficLive;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.widget.RoundLayout;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.common.entity.MarkerCarInfo;
import com.mogo.module.v2x.R;

View File

@@ -16,6 +16,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.widget.RoundLayout;
import com.mogo.module.common.entity.MarkerCarInfo;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.utils.V2XUtils;

View File

@@ -9,7 +9,7 @@
android:paddingBottom="@dimen/dp_20"
app:roundLayoutRadius="@dimen/dp_30">
<com.mogo.module.v2x.view.RoundLayout
<com.mogo.eagle.core.widget.RoundLayout
android:id="@+id/rlRoadEventImg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
@@ -37,7 +37,7 @@
android:src="@drawable/v2x_icon_event_play"
android:visibility="gone" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>
<TextView
android:id="@+id/tvEventTypeTitle"

View File

@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.mogo.module.v2x.view.RoundLayout
<com.mogo.eagle.core.widget.RoundLayout
android:id="@+id/rlRoadEventList"
android:layout_width="match_parent"
android:layout_height="@dimen/module_v2x_push_img_height"
@@ -15,7 +15,7 @@
app:layout_constraintTop_toTopOf="parent"
app:roundLayoutRadius="@dimen/dp_30">
<com.mogo.module.v2x.view.RoundLayout
<com.mogo.eagle.core.widget.RoundLayout
android:id="@+id/rlRoadEventImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -28,8 +28,8 @@
android:scaleType="fitXY"
app:actualImageScaleType="fitXY" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>
<com.mogo.service.imageloader.MogoImageView
android:id="@+id/ivReportHead"

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.mogo.eagle.core.widget.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -50,4 +50,4 @@
android:textSize="@dimen/dp_30"
android:visibility="gone" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.mogo.eagle.core.widget.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/module_v2x_event_see_live_window_height"
@@ -48,4 +48,4 @@
android:textSize="@dimen/dp_30"
android:visibility="gone" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.mogo.eagle.core.widget.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -48,4 +48,4 @@
android:textSize="@dimen/dp_30"
android:visibility="gone" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.mogo.eagle.core.widget.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -65,4 +65,4 @@
app:layout_constraintTop_toBottomOf="@+id/ivErrorIcon" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>

View File

@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mogo.module.v2x.view.RoundLayout
<com.mogo.eagle.core.widget.RoundLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:roundLayoutRadius="@dimen/dp_26">
@@ -70,6 +70,6 @@
app:layout_constraintTop_toBottomOf="@+id/ivErrorIcon" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>
</FrameLayout>

View File

@@ -6,14 +6,14 @@
android:layout_height="match_parent"
android:paddingStart="@dimen/module_main_v2x_animation_width">
<com.mogo.module.v2x.view.RoundLayout
<com.mogo.eagle.core.widget.RoundLayout
android:id="@+id/rlRoadEventList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/dp_30"
app:roundLayoutRadius="@dimen/dp_28">
<com.mogo.module.v2x.view.TextureVideoView
<com.mogo.eagle.core.widget.TextureVideoView
android:id="@+id/vvCarAnimation"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -24,6 +24,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>
</RelativeLayout>

View File

@@ -7,7 +7,7 @@
android:background="@drawable/v2x_alert_window_bg"
android:layout_margin="@dimen/dp_3">
<com.mogo.module.v2x.view.RoundLayout
<com.mogo.eagle.core.widget.RoundLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:roundLayoutRadius="@dimen/dp_26">
@@ -47,6 +47,6 @@
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_20"
android:src="@drawable/module_common_close_selector" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>
</FrameLayout>

View File

@@ -8,7 +8,7 @@
android:layout_margin="@dimen/dp_3"
android:background="@drawable/v2x_bg_video_tip_vr">
<com.mogo.module.v2x.view.RoundLayout
<com.mogo.eagle.core.widget.RoundLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:roundLayoutRadius="@dimen/dp_20">
@@ -48,6 +48,6 @@
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_20"
android:src="@drawable/module_common_close_selector_vr" />
</com.mogo.module.v2x.view.RoundLayout>
</com.mogo.eagle.core.widget.RoundLayout>
</RelativeLayout>

View File

@@ -1,7 +1,5 @@
<resources>
<string name="app_name">mogo-module-v2x</string>
<string name="VideoView_info_text_video_not_supported">"不支持该视频。"</string>
<string name="file_not_support">此文件不支持播放</string>
<string name="v2x_help_speed_txt">车速</string>
<string name="v2x_report_pop_submit_txt">已提交</string>
<string name="v2x_report_pop_thank_txt">感谢已送达</string>

View File

@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundLayout">
<attr name="roundLayoutRadius" format="dimension" />
</declare-styleable>
<style name="customTabLayoutTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">@dimen/dp_40</item>