[2.13.0-merge]yakun and code style

This commit is contained in:
zhongchao
2022-11-21 18:07:52 +08:00
844 changed files with 3197 additions and 29173 deletions

View File

@@ -11,6 +11,7 @@ import android.widget.TextView;
import com.mogo.commons.crash.FinalizeCrashFixer;
import com.mogo.commons.screen.ScreenHelper;
import com.mogo.commons.module.MogoServices;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.toast.TipDrawable;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
@@ -47,6 +48,7 @@ public abstract class AbsMogoApplication extends Application {
}
ScreenHelper.setScreenConfig(this);
Utils.init(this);
MogoServices.getInstance().init(this);
}
private void initRxJavaErrorHandler() {
@@ -99,4 +101,5 @@ public abstract class AbsMogoApplication extends Application {
}
return contentView;
}
}

View File

@@ -0,0 +1,63 @@
package com.mogo.commons.module;
/**
* @author congtaowang
* @since 2019-12-31
* <p>
* 模块描述信息
*/
public class MogoModule {
/**
* 模块加载路径
*/
private String mPath;
/**
* 模块名称
*/
private String mName;
/**
* 广播接收者
*/
private String mBroadcastAction;
/**
* @param path 模块加载路径
* @param name 模块名称
*/
public MogoModule( String path, String name ) {
this.mPath = path;
this.mName = name;
}
public String getPath() {
return mPath;
}
public MogoModule setPath( String path ) {
this.mPath = path;
return this;
}
public String getName() {
return mName;
}
public MogoModule setName( String name ) {
this.mName = name;
return this;
}
public String getBroadcastAction() {
return mBroadcastAction;
}
public MogoModule setBroadcastAction( String broadcastAction ) {
this.mBroadcastAction = broadcastAction;
return this;
}
}

View File

@@ -0,0 +1,88 @@
package com.mogo.commons.module;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author congtaowang
* @since 2019-12-23
* <p>
* 模块路由路径
*/
public class MogoModulePaths {
private static final List<MogoModule> mMogoModules = new ArrayList<>();
// 不需要启动APP也能运行的模块
private static final List<MogoModule> mMogoBaseModules = new ArrayList<>();
private static final List<MogoModule> mModuleFunctions = new ArrayList<>();
private static final List<MogoModule> mModuleFunctionServers = new ArrayList<>();
/**
* 添加卡片模块
*
* @param module
*/
public static void addModule(MogoModule module) {
if (module == null || TextUtils.isEmpty(module.getPath().replace(" ", ""))) {
throw new IllegalArgumentException("module path can't be empty or null or blank");
}
mMogoModules.add(module);
}
/**
* 添加模块功能
*
* @param module 功能模块
*/
public static void addModuleFunction(MogoModule module) {
if (module == null || TextUtils.isEmpty(module.getPath().replace(" ", ""))) {
throw new IllegalArgumentException("module path can't be empty or null or blank");
}
mModuleFunctions.add(module);
}
/**
* 添加 功能服务, 不带UI Fragment的
*
* @param module 功能模块
*/
public static void addModuleFunctionServer(MogoModule module) {
if (module == null || TextUtils.isEmpty(module.getPath().replace(" ", ""))) {
throw new IllegalArgumentException("module path can't be empty or null or blank");
}
mModuleFunctionServers.add(module);
}
/**
* 添加基础模块
*
* @param module
*/
public static void addBaseModule(MogoModule module) {
if (module == null || TextUtils.isEmpty(module.getPath().replace(" ", ""))) {
throw new IllegalArgumentException("module path can't be empty or null or blank");
}
mMogoBaseModules.add(module);
}
public static List<MogoModule> getModules() {
return mMogoModules;
}
public static List<MogoModule> getBaseModules() {
return mMogoBaseModules;
}
public static List<MogoModule> getModuleFunctions() {
return mModuleFunctions;
}
public static List<MogoModule> getModuleFunctionServers() {
return mModuleFunctionServers;
}
}

View File

@@ -0,0 +1,113 @@
package com.mogo.commons.module;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_OLD_OTHER;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.text.TextUtils;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.module.intent.IMogoIntentListener;
import com.mogo.commons.module.intent.IntentHandlerFactory;
import com.mogo.commons.module.intent.IntentManager;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.module.receiver.MogoReceiver;
import com.mogo.commons.voice.AIAssist;
import com.mogo.eagle.core.data.config.CloudPoiManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.realtime.api.MoGoAiCloudRealTime;
import java.util.List;
public class MogoServices implements IMogoIntentListener {
private MogoServices() {
}
private static final class InstanceHolder {
private static final MogoServices INSTANCE = new MogoServices();
}
public static MogoServices getInstance() {
return InstanceHolder.INSTANCE;
}
private static final String TAG = "MogoServices";
private IntentManager mIntentManager;
private Context mContext;
public void init(Context context) {
mContext = context;
MogoStatusManager.getInstance().setAIAssistReady(TAG, AIAssist.getInstance(mContext).hasFlush());
CloudPoiManager.getInstance().updateFromConfig(context);
registerMogoReceiver(context);
mIntentManager = IntentManager.getInstance();
mIntentManager.registerIntentListener(MogoReceiver.ACTION_VOICE_UI, this);
mIntentManager.registerIntentListener(MogoReceiver.ACTION_VOICE_READY, this);
mIntentManager.registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, this);
Intent intent = new Intent("com.freedom.ser.ACTION");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
mContext.sendBroadcast(intent);
if (DebugConfig.isNeedUploadCoordinatesDurationInTime()) {
MoGoAiCloudRealTime.startRealTime(mContext, DebugConfig.getSocketAppId());
}
}
private void registerMogoReceiver(Context context) {
if (context == null) {
return;
}
List<MogoModule> modules = MogoModulePaths.getModules();
if (modules.isEmpty()) {
return;
}
MogoReceiver receiver = new MogoReceiver(context);
IntentFilter filter = new IntentFilter();
if (!modules.isEmpty()) {
for (MogoModule module : modules) {
if (TextUtils.isEmpty(module.getBroadcastAction())) {
continue;
}
filter.addAction(module.getBroadcastAction());
}
}
filter.addAction(MogoReceiver.VOICE_ACTION);
// 小智语音
filter.addAction(MogoReceiver.ACTION_VOICE_UI);
filter.addAction(MogoReceiver.ACTION_VOICE_READY);
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
try {
context.getApplicationContext().registerReceiver(receiver, filter);
} catch (Exception e) {
CallerLogger.INSTANCE.e(M_OLD_OTHER + TAG, "registerMogoReceiver error : " + e);
}
}
@Override
public void onIntentReceived(String command, Intent intent) {
if (TextUtils.equals(command, ConnectivityManager.CONNECTIVITY_ACTION)
&& NetworkUtils.isConnected(mContext)) {
mIntentManager.unregisterIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, this);
}
IntentHandlerFactory.getInstance().handle(mContext, command, intent);
}
public void destroy() {
CallerLogger.INSTANCE.d(M_OLD_OTHER + TAG, "MogoServices do nothings.");
if (DebugConfig.isNeedUploadCoordinatesDurationInTime()) {
MoGoAiCloudRealTime.stopRealTime();
}
}
}

View File

@@ -0,0 +1,32 @@
package com.mogo.commons.module;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 描述
*/
public class ServiceConst {
/**
* 类型
*/
public static final String TYPE = "STRATEGY_REFRESH";
/**
* 卡片 用户数据
*/
public static final String CARD_TYPE_USER_DATA = "CARD_TYPE_USER_DATA";
/**
* 卡片 探路数据
*/
public static final String CARD_TYPE_ROAD_CONDITION = "CARD_TYPE_ROAD_CONDITION";
/**
* 卡片 新鲜事
*/
public static final String CARD_TYPE_NOVELTY = "CARD_TYPE_NOVELTY";
}

View File

@@ -0,0 +1,25 @@
package com.mogo.commons.module.intent;
import android.content.Context;
import android.content.Intent;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.voice.AIAssist;
/**
* @author congtaowang
* @since 2020/6/5
* <p>
* 描述
*/
public class AIAssistIntentHandler implements IntentHandler {
private static final String TAG = "AIAssistIntentHandler";
@Override
public void handle( Context context, Intent intent ) {
AIAssist.getInstance( context ).flush();
MogoStatusManager.getInstance().setAIAssistReady( TAG, true );
}
}

View File

@@ -0,0 +1,52 @@
package com.mogo.commons.module.intent;
import android.content.Context;
import android.content.Intent;
import com.mogo.commons.module.ServiceConst;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.utils.CarSeries;
/**
* @author congtaowang
* @since 2020/6/5
*
* 描述
*/
public class AccStatusIntentHandler implements IntentHandler {
private static volatile AccStatusIntentHandler sInstance;
private AccStatusIntentHandler() {
}
public static AccStatusIntentHandler getInstance() {
if ( sInstance == null ) {
synchronized ( AccStatusIntentHandler.class ) {
if ( sInstance == null ) {
sInstance = new AccStatusIntentHandler();
}
}
}
return sInstance;
}
public synchronized void release() {
sInstance = null;
}
@Override
public void handle( Context context, Intent intent ) {
String action = intent.getAction();
if ( Intent.ACTION_POWER_CONNECTED.equals( action ) ) {
if ( CarSeries.isF8xxSeries() ) {
MogoStatusManager.getInstance().setAccStatus( ServiceConst.TYPE, true );
}
} else if ( Intent.ACTION_POWER_DISCONNECTED.equals( action ) ) {
if ( CarSeries.isF8xxSeries() ) {
MogoStatusManager.getInstance().setAccStatus( ServiceConst.TYPE, false );
}
}
}
}

View File

@@ -0,0 +1,19 @@
package com.mogo.commons.module.intent;
import android.content.Context;
import android.content.Intent;
/**
* @author congtaowang
* @since 2020-04-17
* <p>
* 描述
*/
public class EmptyIntentHandler implements IntentHandler {
private static final String TAG = "EmptyIntentHandler";
@Override
public void handle( Context context, Intent intent ) {
}
}

View File

@@ -0,0 +1,18 @@
package com.mogo.commons.module.intent;
import android.content.Intent;
/**
* @author congtaowang
* @since 2020-01-09
* <p>
* 免唤醒语音监听
*/
public interface IMogoIntentListener {
/**
* @param intentStr 广播action、语音 command
* @param intent 意图
*/
void onIntentReceived( String intentStr, Intent intent );
}

View File

@@ -0,0 +1,36 @@
package com.mogo.commons.module.intent;
import android.content.Intent;
import com.alibaba.android.arouter.facade.template.IProvider;
/**
* @author congtaowang
* @since 2020-01-09
* <p>
* 唤醒语音控制
*/
public interface IMogoIntentManager extends IProvider {
/**
* 注册意图接收者
*
* @param intent
*/
public void registerIntentListener( String intent, IMogoIntentListener listener );
/**
* 注册意图接收者
*
* @param intent
*/
public void unregisterIntentListener( String intent, IMogoIntentListener listener );
/**
* 触发意图回调,各业务不用关心
*
* @param intentStr
* @param intent
*/
public void invoke( String intentStr, Intent intent );
}

View File

@@ -0,0 +1,15 @@
package com.mogo.commons.module.intent;
import android.content.Context;
import android.content.Intent;
/**
* @author congtaowang
* @since 2020-04-17
* <p>
* 描述
*/
public interface IntentHandler {
void handle( Context context, Intent intent );
}

View File

@@ -0,0 +1,59 @@
package com.mogo.commons.module.intent;
import android.content.Context;
import android.content.Intent;
import com.mogo.commons.module.receiver.MogoReceiver;
import java.util.HashMap;
import java.util.Map;
/**
* @author congtaowang
* @since 2020-04-17
* <p>
* 描述
*/
public class IntentHandlerFactory {
private IntentHandlerFactory() {
// private constructor
mHandlers.put( MogoReceiver.ACTION_VOICE_UI, new VoiceUiIntentHandler() );
mHandlers.put( Intent.ACTION_POWER_CONNECTED, AccStatusIntentHandler.getInstance() );
mHandlers.put( Intent.ACTION_POWER_DISCONNECTED, AccStatusIntentHandler.getInstance() );
mHandlers.put( MogoReceiver.ACTION_VOICE_READY, new AIAssistIntentHandler() );
}
private static final class InstanceHolder {
private static final IntentHandlerFactory INSTANCE = new IntentHandlerFactory();
}
public static IntentHandlerFactory getInstance() {
return InstanceHolder.INSTANCE;
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return InstanceHolder.INSTANCE;
}
private final Map< String, IntentHandler > mHandlers = new HashMap<>();
private final IntentHandler DEFAULT = new EmptyIntentHandler();
private IntentHandler getIntentHandler( String intent ) {
if ( mHandlers.containsKey( intent ) && mHandlers.get( intent ) != null ) {
return mHandlers.get( intent );
}
return DEFAULT;
}
public void handle( Context context, String intent, Intent obj ) {
IntentHandler handler = getIntentHandler( intent );
if ( handler != null ) {
handler.handle( context, obj );
}
}
}

View File

@@ -0,0 +1,78 @@
package com.mogo.commons.module.intent;
import android.content.Context;
import android.content.Intent;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author congtaowang
* @since 2020-01-09
* <p>
* 描述
*/
public class IntentManager implements IMogoIntentManager{
private static volatile IntentManager sInstance;
private static final byte[] obj = new byte[0];
private IntentManager() {
}
public static IntentManager getInstance() {
if ( sInstance == null ) {
synchronized ( obj ) {
if ( sInstance == null ) {
sInstance = new IntentManager();
}
}
}
return sInstance;
}
public synchronized void release() {
sInstance = null;
}
private final Map< String, CopyOnWriteArrayList< IMogoIntentListener > > mListeners = new ConcurrentHashMap<>();
@Override
public void registerIntentListener( String intent, IMogoIntentListener listener ) {
if ( listener == null || intent == null ) {
return;
}
if ( !mListeners.containsKey( intent ) ) {
mListeners.put( intent, new CopyOnWriteArrayList<>() );
}
mListeners.get( intent ).add( listener );
}
@Override
public void unregisterIntentListener( String command, IMogoIntentListener listener ) {
if ( mListeners.containsKey( command ) ) {
mListeners.get( command ).remove( listener );
}
}
@Override
public void init( Context context ) {
}
@Override
public void invoke( String command, Intent intent ) {
CopyOnWriteArrayList< IMogoIntentListener > listeners = mListeners.get( command );
if ( listeners != null && !listeners.isEmpty() ) {
Iterator< IMogoIntentListener > iterator = listeners.iterator();
while ( iterator.hasNext() ) {
IMogoIntentListener listener = iterator.next();
if ( listener != null ) {
listener.onIntentReceived( command, intent );
}
}
}
}
}

View File

@@ -0,0 +1,24 @@
package com.mogo.commons.module.intent;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.module.receiver.MogoReceiver;
public class VoiceUiIntentHandler implements IntentHandler {
private static final String TAG = "VoiceUiIntentHandler";
@Override
public void handle( Context context, Intent intent ) {
String val = intent.getStringExtra( MogoReceiver.PARRAM_WAKE_STATUS );
if ( TextUtils.equals( val, MogoReceiver.VALUE_DISMISS ) ) {
MogoStatusManager.getInstance().setVoiceUIShow( TAG, false );
} else if ( TextUtils.equals( val, MogoReceiver.VALUE_SHOW ) ) {
MogoStatusManager.getInstance().setVoiceUIShow( TAG, true );
}
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.commons.module.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.mogo.commons.module.intent.IntentHandlerFactory;
public class AccStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive( Context context, Intent intent ) {
IntentHandlerFactory.getInstance().handle( context, intent.getAction(), intent );
}
}

View File

@@ -0,0 +1,54 @@
package com.mogo.commons.module.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.mogo.commons.module.intent.IntentManager;
/**
* @author congtaowang
* @since 2019-10-03
* <p>
* 广播接收者
*/
public class MogoReceiver extends BroadcastReceiver {
/**
* 语音
*/
public static final String VOICE_ACTION = "com.zhidao.speech.awake.notify";
public static final String PARAM_COMMAND = "command";
// 小智语音唤醒UI
public static final String ACTION_VOICE_UI = "com.zhidao.xiaozhi.wake.status";
public static final String PARRAM_WAKE_STATUS = "WAKE_STATUS";
public static final String VALUE_DISMISS = "dismiss";
public static final String VALUE_SHOW = "show";
/**
* 小智语音准备就绪
*/
public static final String ACTION_VOICE_READY = "com.zhidao.auto.AIAssist.ready";
private final IntentManager mMogoIntentManager;
public MogoReceiver(Context context) {
mMogoIntentManager = IntentManager.getInstance();
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (TextUtils.equals(VOICE_ACTION, action)) {
String cmd = intent.getStringExtra(PARAM_COMMAND);
if (!TextUtils.isEmpty(cmd)) {
mMogoIntentManager.invoke(cmd, intent);
}
} else {
mMogoIntentManager.invoke(action, intent);
}
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.commons.module.status;
/**
* @author congtaowang
* @since 2020-01-04
* <p>
* 状态控制器监听
*/
public interface IMogoStatusChangedListener {
/**
* @param descriptor 状态类型
* @param isTrue true - accOn、adas ui show、voice ui show、push ui show、v2x ui show
*/
void onStatusChanged(StatusDescriptor descriptor, boolean isTrue );
}

View File

@@ -0,0 +1,150 @@
package com.mogo.commons.module.status;
import com.alibaba.android.arouter.facade.template.IProvider;
/**
* @author congtaowang
* @since 2020-01-02
* <p>
* 车机状态
*/
public interface IMogoStatusManager extends IProvider {
/**
* 是否在vr模式
* @return true - 在vr模式 false - 不在vr模式
*/
boolean isVrMode();
/**
* 小智语音 UI 是否在展示
*
* @return
*/
boolean isVoiceShow();
/**
* v2x UI 是否在展示
*
* @return
*/
boolean isV2XShow();
/**
* 是否开机
*
* @return true - 开机 false - 关机
*/
boolean isAccOn();
/**
* 主页是否显示
*
* @return
*/
boolean isMainPageOnResume();
/**
* 主页是否在后台运行
*
* @return true-在后台false-不在后台
*/
boolean isMainPageIsBackground();
/**
* 主页是否已启动
*
* @return
*/
boolean isMainPageLaunched();
/**
* 设置vrMode状态
* @param tag 业务类型
* @param vrMode true - 在vr模式 false 不在vr模式
*/
void setVrMode(String tag, boolean vrMode);
/**
* 设置小智语音UI状态
*
* @param tag 业务类型
* @param show true - 显示 false - 隐藏
*/
void setVoiceUIShow( String tag, boolean show );
/**
* 设置 V2X UI 状态
* <p>
*
* @param tag 业务类型
* @param show true - 显示 false - 隐藏
*/
void setV2XUIShow( String tag, boolean show );
/**
* 设置 acc 状态
*
* @param tag 业务类型
* @param isOn true - on, false - off
*/
void setAccStatus( String tag, boolean isOn );
/**
* 主页 resume 状态
*
* @param tag
* @param resume
*/
void setMainPageResumeStatus( String tag, boolean resume );
/**
* 主页 后台运行 状态
*
* @param tag 控制来源
* @param isBackground true-在后台运行false-不在后台运行(也可能是挂了)
*/
void setMainPageIsBackgroundStatus( String tag, boolean isBackground );
/**
* 设置小智语音状态
*
* @param tag
* @param ready
*/
void setAIAssistReady( String tag, boolean ready );
/**
* 设置求助状态
*
* @param tag
* @param seekHelping
*/
void setSeekHelping( String tag, boolean seekHelping );
/**
* 设置主页是否启动
*
* @param tag
* @param launched
*/
void setMainPageLaunchedStatus( String tag, boolean launched );
/**
* 注册监听
*
* @param tag 业务类型
* @param descriptor 监听类型
* @param listener 监听回调
*/
void registerStatusChangedListener(String tag, StatusDescriptor descriptor, IMogoStatusChangedListener listener );
/**
* 注销
*
* @param tag 业务类型
* @param descriptor 注销类型
* @param listener 注销回调
*/
void unregisterStatusChangedListener( String tag, StatusDescriptor descriptor, IMogoStatusChangedListener listener );
}

View File

@@ -0,0 +1,18 @@
package com.mogo.commons.module.status;
/**
* @author congtaowang
* @since 2020-01-04
* <p>
* 状态控制器监听
*/
public interface IMogoStickyStatusChangedListener extends IMogoStatusChangedListener {
/**
* 是否需要黏性状态: 先改变状态,后注册监听
*
* @param descriptor 状态
* @return 默认不需要
*/
boolean requestStickyStatus( StatusDescriptor descriptor );
}

View File

@@ -0,0 +1,187 @@
package com.mogo.commons.module.status;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author congtaowang
* @since 2020-01-02
* <p>
* 状态控制器
*/
public class MogoStatusManager implements IMogoStatusManager {
private static volatile MogoStatusManager sInstance;
private static final byte[] obj = new byte[0];
private MogoStatusManager() {
}
public static MogoStatusManager getInstance() {
if (sInstance == null) {
synchronized (obj) {
if (sInstance == null) {
sInstance = new MogoStatusManager();
}
}
}
return sInstance;
}
/**
* 状态记录
*/
private static final Map<StatusDescriptor, Boolean> mStatus = new ConcurrentHashMap<>();
/**
* 回调集合
*/
private static final Map<StatusDescriptor, List<IMogoStatusChangedListener>> mListeners = new ConcurrentHashMap<>();
/**
* 状态类型修改记录
*/
private static final Map<StatusDescriptor, String> mModifier = new ConcurrentHashMap<>();
@Override
public boolean isVoiceShow() {
return get_bool_val(StatusDescriptor.VOICE_UI);
}
@Override
public boolean isVrMode() {
return get_bool_val(StatusDescriptor.VR_MODE);
}
@Override
public boolean isV2XShow() {
return get_bool_val(StatusDescriptor.V2X_UI);
}
@Override
public boolean isAccOn() {
return get_bool_val(StatusDescriptor.ACC_STATUS);
}
@Override
public boolean isMainPageOnResume() {
return get_bool_val(StatusDescriptor.MAIN_PAGE_RESUME);
}
@Override
public boolean isMainPageIsBackground() {
return get_bool_val(StatusDescriptor.MAIN_PAGE_IS_BACKGROUND);
}
@Override
public boolean isMainPageLaunched() {
return get_bool_val(StatusDescriptor.MAIN_PAGE_CREATED);
}
private boolean get_bool_val(StatusDescriptor descriptor) {
Boolean val = mStatus.get(descriptor);
return val != null && val;
}
@Override
public void setVrMode(String tag, boolean vrMode) {
doSetStatus(tag, StatusDescriptor.VR_MODE, vrMode);
}
@Override
public void setVoiceUIShow(String tag, boolean show) {
doSetStatus(tag, StatusDescriptor.VOICE_UI, show);
}
@Override
public void setV2XUIShow(String tag, boolean show) {
doSetStatus(tag, StatusDescriptor.V2X_UI, show);
}
@Override
public void setAccStatus(String tag, boolean isOn) {
doSetStatus(tag, StatusDescriptor.ACC_STATUS, isOn);
}
@Override
public void setMainPageResumeStatus(String tag, boolean resume) {
doSetStatus(tag, StatusDescriptor.MAIN_PAGE_RESUME, resume);
}
@Override
public void setMainPageIsBackgroundStatus(String tag, boolean isBackground) {
doSetStatus(tag, StatusDescriptor.MAIN_PAGE_IS_BACKGROUND, isBackground);
}
@Override
public void setAIAssistReady(String tag, boolean ready) {
doSetStatus(tag, StatusDescriptor.AI_ASSIST_READY, ready);
}
@Override
public void setSeekHelping(String tag, boolean seekHelping) {
doSetStatus(tag, StatusDescriptor.SEEK_HELPING, seekHelping);
}
@Override
public void setMainPageLaunchedStatus(String tag, boolean launched) {
doSetStatus(tag, StatusDescriptor.MAIN_PAGE_CREATED, launched);
}
private void doSetStatus(String tag, StatusDescriptor target, boolean value) {
mStatus.put(target, value);
invokeStatusChangedListener(target, value);
recordStatusModifier(tag, target);
}
private void invokeStatusChangedListener(StatusDescriptor descriptor, boolean status) {
List<IMogoStatusChangedListener> listenerList = mListeners.get(descriptor);
if (listenerList != null && listenerList.size() > 0) {
IMogoStatusChangedListener[] listeners = new IMogoStatusChangedListener[listenerList.size()];
listenerList.toArray(listeners);
for (IMogoStatusChangedListener listener : listeners) {
if (listener != null) {
listener.onStatusChanged(descriptor, status);
}
}
}
}
private void recordStatusModifier(String tag, StatusDescriptor descriptor) {
mModifier.put(descriptor, tag);
}
@Override
public void registerStatusChangedListener(String tag, StatusDescriptor descriptor, IMogoStatusChangedListener listener) {
if (listener == null || descriptor == null) {
return;
}
if (!mListeners.containsKey(descriptor)) {
mListeners.put(descriptor, new ArrayList<>());
}
mListeners.get(descriptor).add(listener);
if (listener instanceof IMogoStickyStatusChangedListener && ((IMogoStickyStatusChangedListener) listener).requestStickyStatus(descriptor)) {
Boolean val = mStatus.get(descriptor);
if (val != null) {
listener.onStatusChanged(descriptor, get_bool_val(descriptor));
}
}
}
@Override
public void unregisterStatusChangedListener(String tag, StatusDescriptor descriptor, IMogoStatusChangedListener listener) {
if (mListeners.get(descriptor) != null) {
mListeners.get(descriptor).remove(listener);
}
}
@Override
public void init(Context context) {
}
}

View File

@@ -0,0 +1,57 @@
package com.mogo.commons.module.status;
/**
* @author congtaowang
* @since 2020-01-04
* <p>
* 状态描述
*/
public enum StatusDescriptor {
/**
* v2x UI
*/
V2X_UI,
/**
* 小智语音交互 UI
*/
VOICE_UI,
/**
* 开机状态
*/
ACC_STATUS,
/**
* 主页 resume 状态
*/
MAIN_PAGE_RESUME,
/**
* 主页 isBackground 状态
*/
MAIN_PAGE_IS_BACKGROUND,
/**
* 小智语音状态
*/
AI_ASSIST_READY,
/**
* 求助状态
*/
SEEK_HELPING,
/**
* 是否已经进入过主页
*/
MAIN_PAGE_CREATED,
/**
* 是否已经进入vr模式
*/
VR_MODE,
}

View File

@@ -0,0 +1,125 @@
package com.mogo.commons.utils;
import android.text.TextUtils;
import com.mogo.commons.debug.DebugConfig;
import java.lang.reflect.Method;
/**
* @author congtaowang
* @since 2020-03-26
* <p>
* 车机类型
*/
public class CarSeries {
private static boolean invokeFlag = false;
private static boolean isF8xxSeries = false;
public static boolean isF8xxSeries() {
if ( invokeFlag ) {
return isF8xxSeries;
}
isF8xxSeries = DebugConfig.getProductFlavor().startsWith( "f" );
invokeFlag = true;
return isF8xxSeries;
}
@Deprecated
public static final int CAR_SERIES_C80X = 10;
@Deprecated
public static final int CAR_SERIES_D80X = 20;
@Deprecated
public static final int CAR_SERIES_D81X = 21;
@Deprecated
public static final int CAR_SERIES_D82X = 22;
@Deprecated
public static final int CAR_SERIES_D84X = 23;
@Deprecated
public static final int CAR_SERIES_F80X = 30;
@Deprecated
public static final int CAR_SERIES_G80X = 40;
@Deprecated
public static final int CAR_SERIES_E84X = 50;
@Deprecated
public static final int CAR_SERIES_E84XCD = 51;
@Deprecated
public static final int CAR_SERIES_E85X = 50;
@Deprecated
public static final int CAR_SERIES_E85XCD = 51;
@Deprecated
public static final int CAR_SERIES_E85XJD = 51;
@Deprecated
public static int CAR_SERIES = 0;
/**
* Deprecated.
* Use {@link DebugConfig#getProductFlavor()} instead.
*
* @return
*/
@Deprecated
public static int getSeries() {
if ( CAR_SERIES != 0 ) {
return CAR_SERIES;
}
synchronized ( CarSeries.class ) {
if ( CAR_SERIES != 0 ) {
return CAR_SERIES;
}
String device = get( "ro.fota.device" );
if ( TextUtils.isEmpty( device ) ) {
return CAR_SERIES_F80X;
}
if ( "FG166".equals( device ) ) {
CAR_SERIES = CAR_SERIES_C80X;
} else if ( "D801-802".equals( device ) ) {
CAR_SERIES = CAR_SERIES_D80X;
} else if ( "D801B-802B".equals( device ) ) {
// 2+16G
CAR_SERIES = CAR_SERIES_D80X;
} else if ( "D811-812".equals( device ) ) {
CAR_SERIES = CAR_SERIES_D81X;
} else if ( "D821-822".equals( device ) ) {
CAR_SERIES = CAR_SERIES_D82X;
} else if ( "D841-842".equals( device ) ) {
CAR_SERIES = CAR_SERIES_D84X;
} else if ( "G801-802".equals( device ) ) {
CAR_SERIES = CAR_SERIES_G80X;
} else if ( "F801-802".equals( device ) ) {
CAR_SERIES = CAR_SERIES_F80X;
} else if ( "E841-842".equals( device ) ) {
CAR_SERIES = CAR_SERIES_E84X;
} else if ( "E84XCD".equals( device ) ) {
CAR_SERIES = CAR_SERIES_E84XCD;
} else if ( "E851-852".equals( device ) ) {
CAR_SERIES = CAR_SERIES_E85X;
} else if ( "E85XCD".equals( device ) ) {
CAR_SERIES = CAR_SERIES_E85XCD;
} else if ( "E85XJD".equals( device ) ) {
CAR_SERIES = CAR_SERIES_E85XJD;
} else if ( device.startsWith( "E85" ) ) {
CAR_SERIES = CAR_SERIES_E85XJD;
} else {
CAR_SERIES = CAR_SERIES_F80X;
}
return CAR_SERIES;
}
}
@Deprecated
private static String get( String key ) {
String value = "";
try {
Class< ? > c = Class.forName( "android.os.SystemProperties" );
Method get = c.getMethod( "get", new Class[]{String.class, String.class} );
value = ( String ) get.invoke( c, new Object[]{key, "unknown"} );
} catch ( Exception e ) {
value = "";
}
return value;
}
}

View File

@@ -0,0 +1,156 @@
package com.mogo.commons.utils;
import static java.lang.Math.PI;
import android.util.Pair;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020/4/14 1:02 PM
* desc : 计算车辆驾驶方向的工具类
* version: 1.0
*/
public class DrivingDirectionUtils {
public static long getDegreeOfCar2Poi2(double x1, double y1, double x2, double y2, double x1_angle) {
Pair<Double, Double> newPoint = calculateNewPoint(x1, y1, x1_angle, 10);
if (newPoint != null) {
double angle = getAngle(x1, y1, newPoint.first, newPoint.second, x2, y2);
return Math.round(angle + 0.5);
}
return 0;
}
public static double distance(double x1, double y1, double x2, double y2) {
return Math.sqrt(Math.pow(x1 - x2, 2.0) + Math.pow(y1 - y2, 2.0));
}
public static double getAngle(double sx, double sy, double x1, double y1, double x2, double y2) {
x1 = x1 - sx;
y1 = y1 - sy;
x2 = x2 - sx;
y2 = y2 - sy;
double product = x1 * x2 + y1 * y2;
double radians = Math.acos(product / (Math.sqrt(Math.pow(x1, 2.0) + Math.pow(y1, 2.0)) * Math.sqrt(Math.pow(x2, 2.0) + Math.pow(y2, 2.0))));
return Math.toDegrees(radians);
}
public static Pair<Double, Double> calculateNewPoint(double x, double y, double angle, double distance) {
if (distance == 0) {
return null;
}
double radian = Math.toRadians(angle);
double radianCandle = Math.toRadians(90.0 - angle);
double nX = x + distance * Math.sin(radian) / 100000.0;
double nY = y + distance * Math.sin(radianCandle) / 100000.0;
return Pair.create(nX, nY);
}
/**
* 计算车辆行驶方向 与 poi点到车辆的连线 间的夹角
*
* @param carLon 车辆位置 lon
* @param carLat 车辆位置 lat
* @param poiLon poi 位置 lon
* @param poiLat poi 位置 lat
* @param carAngle 车辆行驶方向
* @return
*/
public static int getDegreeOfCar2Poi(double carLon, double carLat, double poiLon, double poiLat, int carAngle) {
int poiAngle = 0;
// 以子午线作为y轴 计算两点的余切 再将余切值转化为角度
double _angle = Math.atan2(Math.abs(carLon - poiLon), Math.abs(carLat - poiLat)) * (180 / PI);
if (poiLon > carLon) {
// poi 在 车辆位置的第1象限
if (poiLat > carLat) {
poiAngle = (int) _angle;
}
// poi 在 车辆位置的第2象限
else {
poiAngle = 180 - (int) _angle;
}
} else {
// poi 在 车辆位置的第3象限
if (poiLat < carLat) {
poiAngle = (int) _angle + 180;
}
// poi 在 车辆位置的第4象限
else {
poiAngle = 360 - (int) _angle;
}
}
return calculationAngle(poiAngle, carAngle);
}
/**
* 计算两个行驶方向间的夹角 计算结果小于180度
*
* @param angle0
* @param angle1
* @return
*/
public static int calculationAngle(int angle0, int angle1) {
// 获取两方向间夹角
int angle = Math.abs(angle0 - angle1);
if (angle > 180) {
int minAngle = Math.min(angle0, angle1);
int maxAngle = Math.max(angle0, angle1);
return 180 - Math.abs(minAngle + 180 - maxAngle);
} else {
return angle;
}
}
/**
* 计算车辆行驶方向角度,起点&终点经纬度
*
* @param carLat 车辆位置 lat
* @param carLon 车辆位置 lon
* @param poiLat poi 位置 lat
* @param poiLon poi 位置 lon
*/
public static int getCarAngle(double carLat, double carLon, double poiLat, double poiLon) {
int poiAngle = 0;
// 以子午线作为y轴 计算两点的余切 再将余切值转化为角度
double _angle = Math.atan2(Math.abs(carLon - poiLon), Math.abs(carLat - poiLat)) * (180 / PI);
if (poiLon > carLon) {
// poi 在 车辆位置的第1象限
if (poiLat > carLat) {
poiAngle = (int) _angle;
}
// poi 在 车辆位置的第2象限
else {
poiAngle = 180 - (int) _angle;
}
} else {
// poi 在 车辆位置的第3象限
if (poiLat < carLat) {
poiAngle = (int) _angle + 180;
}
// poi 在 车辆位置的第4象限
else {
poiAngle = 360 - (int) _angle;
}
}
if (poiAngle >= 355) {
poiAngle = 0;
}
return poiAngle;
}
/**
* 计算连两个角度差值
*
* @param angle1 角度1
* @param angle2 角度2
* @return 差值
*/
public static double getAngleDiff(double angle1, double angle2) {
// 两个角度差值较小
return 180 - Math.abs(Math.abs(angle1 - angle2) - 180);
}
}

View File

@@ -1,149 +0,0 @@
package com.mogo.commons.utils;
import java.text.DecimalFormat;
/**
* 莫顿编码
*
* @author linyang
* @since 2020.07.09
*/
public class MortonCode {
/**
* morton 转 经纬度 时的中间常量
*/
private static final long NDS_180_DEGREES = 0x7fffffff;
/**
* morton 转 经纬度 时的中间常量
*/
private static final long NDS_360_DEGREES = 4294967295L;
/**
* morton 转 经纬度 时的中间常量
*/
private static final long NDS_90_DEGREES = 0x3fffffff;
/**
* 经纬度转 morton 时的中间常量
*/
private static final double RULE_MORTON = Math.pow( 2, 32 ) / 360;
/**
* morton 转 经纬度 时的中间常量
*/
private static final double RULE_MORTON_TO_LONLAT = 360.0 / Math.pow( 2, 32 );
/**
* @param lon
* @param lat
* @return
*/
public static long wrapEncodeMorton( Double lon, Double lat ) {
DecimalFormat decimalFormat = new DecimalFormat( "#.######" );
return encodeMorton( Double.valueOf( decimalFormat.format( lon ) ),
Double.valueOf( decimalFormat.format( lat ) ) );
}
/**
* 编码 morton code
*
* @param lon
* @param lat
* @return
*/
public static long encodeMorton( Double lon, Double lat ) {
Long bit = 1L;
long mortonCode = 0L;
long x = ( long ) ( lon * RULE_MORTON );
long y = ( long ) ( lat * RULE_MORTON );
if ( y < 0 ) {
y += 0x7FFFFFFF;
}
y = y << 1;
for ( int i = 0; i < 32; i++ ) {
// x-part
mortonCode = mortonCode | ( x & bit );
x = x << 1;
bit = bit << 1;
// y-part
mortonCode = mortonCode | ( y & bit );
y = y << 1;
bit = bit << 1;
}
return mortonCode;
}
/**
* 将莫顿码解码为坐标
*
* @param mortonCode
* @return
*/
public static double[] decodeMorton( long mortonCode ) {
long[] midPoint = mortonCodeToCoord( mortonCode );
normalizeCoord( midPoint );
double[] point = new double[2];
// 将经纬度长整数转化为 浮点类型
point[0] = midPoint[0] * RULE_MORTON_TO_LONLAT;
point[1] = midPoint[1] * RULE_MORTON_TO_LONLAT;
return point;
}
/**
* 莫顿码分别拆解为 编码后的经纬度长整数
*
* @param mortonCode
* @return
*/
private static long[] mortonCodeToCoord( long mortonCode ) {
long bit = 1L;
long[] longPoint = new long[2];
for ( int i = 0; i < 32; i++ ) {
longPoint[0] |= mortonCode & bit;
mortonCode >>= 1;
longPoint[1] |= mortonCode & bit;
bit <<= 1;
}
return longPoint;
}
/**
* 对编码后的经纬度长整数进行解码
*
* @param midPoint
*/
private static void normalizeCoord( long[] midPoint ) {
// if x > 180 degrees, then subtract 360 degrees
if ( midPoint[0] > NDS_180_DEGREES ) {
midPoint[0] -=
NDS_360_DEGREES + 1; // add 1 because 0 must be counted as well
} else if ( midPoint[0] < -NDS_180_DEGREES ) // if x < 180 , x += 360
{
midPoint[0] +=
NDS_360_DEGREES + 1; // add 1 because 0 must be counted as well
}
// if y > 90 degrees, then subtract 180 degrees
if ( midPoint[1] > NDS_90_DEGREES ) {
midPoint[1] -=
NDS_180_DEGREES + 1; // add 1 because 0 must be counted as well
} else if ( midPoint[1] < -NDS_90_DEGREES ) // if y < 90, y += 180
{
midPoint[1] +=
NDS_180_DEGREES + 1; // add 1 because 0 must be counted as well
}
return;
}
public static void main( String[] args ) {
System.out.println( encodeMorton( 116.39584, 39.98152 ) );
}
}

View File

@@ -0,0 +1,53 @@
package com.mogo.commons.utils;
import com.mogo.eagle.core.data.map.MogoLatLng;
/**
* @author liujing
* @description 描述
* @since: 2021/4/13
*/
public class Trigonometric {
private final static double radius_b = 6378137;//大半径
private final static double radius_s = 6356725;//小半径
private static double mRadLo;
private static double mRadLa;
private static double Ec;
private static double Ed;
/**
* 计算两点间的角度
*/
public static double getAngle(double lon1, double lat1, double lon2,
double lat2) {
double fLat = Math.PI * (lat1) / 180.0;
double fLng = Math.PI * (lon1) / 180.0;
double tLat = Math.PI * (lat2) / 180.0;
double tLng = Math.PI * (lon2) / 180.0;
double degree = (Math.atan2(Math.sin(tLng - fLng) * Math.cos(tLat), Math.cos(fLat) * Math.sin(tLat) -
Math.sin(fLat) * Math.cos(tLat) * Math.cos(tLng - fLng))) * 180.0 / Math.PI;
if (degree >= 0) {
return degree;
} else {
return 360 + degree;
}
}
/**
* 根据角度获取指定距离点的经纬度
*/
public static MogoLatLng getNewLocation(double lon, double lat, double distance, double angle) {
mRadLo = lon * Math.PI / 180.;
mRadLa = lat * Math.PI / 180.;
Ec = radius_s + (radius_b - radius_s) * (90. - lat) / 90;
Ed = Ec * Math.cos(mRadLa);
double dx = distance * Math.sin(Math.toRadians(angle));
double dy = distance * Math.cos(Math.toRadians(angle));
double lon_new = (dx / Ed + mRadLo) * 180. / Math.PI;
double lat_new = (dy / Ec + mRadLa) * 180. / Math.PI;
return new MogoLatLng(lat_new, lon_new);
}
}

View File

@@ -1,63 +0,0 @@
package com.mogo.commons.utils;
import android.content.Context;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;
public
/**
* @author congtaowang
* @since 2020/10/19
*
* 描述
*/
class ViewPagerSpeedScroller extends Scroller {
private int mFixedDuration = 1500;
public ViewPagerSpeedScroller( Context context ) {
super( context );
}
public ViewPagerSpeedScroller( Context context, Interpolator interpolator ) {
super( context, interpolator );
}
public ViewPagerSpeedScroller( Context context, Interpolator interpolator, boolean flywheel ) {
super( context, interpolator, flywheel );
}
@Override
public void startScroll( int startX, int startY, int dx, int dy ) {
startScroll( startX, startY, dx, dy, mFixedDuration );
}
@Override
public void startScroll( int startX, int startY, int dx, int dy, int duration ) {
super.startScroll( startX, startY, dx, dy, mFixedDuration );
}
public void setFixedDuration( int duration ) {
this.mFixedDuration = duration;
}
public static void attach( Context context, Object pager, int duration ) {
try {
Field filed = pager.getClass().getDeclaredField( "mScroller" );
filed.setAccessible( true );
ViewPagerSpeedScroller scroller = new ViewPagerSpeedScroller( context, new DecelerateInterpolator() );
scroller.setFixedDuration( duration );
filed.set( pager, scroller );
Field field = pager.getClass().getDeclaredField( "mTouchSlop" );
field.setAccessible( true );
field.setInt( pager, 4 );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}