This commit is contained in:
wangcongtao
2020-01-05 16:24:07 +08:00
parent a0aa63b89b
commit 323376dcec
77 changed files with 2518 additions and 567 deletions

2
.idea/misc.xml generated
View File

@@ -5,7 +5,7 @@
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@@ -7,6 +7,8 @@ import androidx.multidex.MultiDex;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.demo.module.map.DemoConstants;
import com.mogo.demo.module.map2.Demo2Constants;
import com.mogo.module.common.ModuleType;
import com.mogo.module.common.MogoModule;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.tanlu.constant.TanluConstants;
@@ -21,9 +23,9 @@ public class MogoApplication extends AbsMogoApplication {
@Override
public void onCreate() {
super.onCreate();
MogoModulePaths.addModule( DemoConstants.TAG );
MogoModulePaths.addModule( Demo2Constants.TAG );
MogoModulePaths.addModule( TanluConstants.TAG );
MogoModulePaths.addModule( new MogoModule( DemoConstants.TAG, "CARD_DEMO" ) );
MogoModulePaths.addModule( new MogoModule( Demo2Constants.TAG, "CARD_DEMO2" ) );
MogoModulePaths.addModule( new MogoModule( TanluConstants.TAG, "CARD_TYPE_ROAD_CODITION" ) );
}
@Override

View File

@@ -9,13 +9,13 @@
</style>
<style name="AppTheme.App" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:statusBarColor" tools:ignore="NewApi">@null</item>
<item name="android:windowEnterAnimation">@null</item>
<item name="android:windowExitAnimation">@null</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowTranslucentNavigation">false</item>
<item name="android:windowAnimationStyle">@style/Animation</item>
</style>

View File

@@ -51,10 +51,11 @@ ext {
// retrofit
retrofit : "com.squareup.retrofit2:retrofit:2.3.0",
retrofitadapter : "com.squareup.retrofit2:adapter-rxjava:2.1.0",
retrofitadapter : "com.squareup.retrofit2:adapter-rxjava2:2.3.0",
retrofitconvertergson : "com.squareup.retrofit2:converter-gson:2.3.0",
retrofitconverterscalars : "com.squareup.retrofit2:converter-scalars:2.1.0",
// leakcanary
leakcanary : 'com.squareup.leakcanary:leakcanary-android:1.5.4',
leakcanarynoop : 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4',
@@ -92,6 +93,7 @@ ext {
mogoserviceapi : "com.mogo.service:mogo-service-api:${MOGO_SERVICE_API_VERSION}",
moduleapps : "com.mogo.module:module-apps:${MOGO_MODULE_APPS_VERSION}",
mogoconnection : "com.mogo.connection:mogo-connection:${MOGO_CONNECTION_VERSION}",
moduleextensions : "com.mogo.connection:module-extensions:${MOGO_MODULE_EXTENSIONS_VERSION}",
// 长链
socketsdk : 'com.zhidao.socketsdk:socketsdk:2.1.0',
@@ -102,6 +104,6 @@ ext {
jetbrainsannotationsjava5: "org.jetbrains:annotations-java5:15.0",
// 统一登录
accountsdk : "com.zhidao.accountservice:account-sdk:1.0.0.1@aar",
accountsdk : "com.zhidao.accoutservice:account-sdk:1.0.0.1@aar",
]
}

View File

@@ -36,6 +36,8 @@ dependencies {
api rootProject.ext.dependencies.analytics
implementation rootProject.ext.dependencies.arouter
annotationProcessor rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxjava
implementation rootProject.ext.dependencies.accountsdk
if (Boolean.valueOf(RELEASE)) {
implementation rootProject.ext.dependencies.mogoutils
compileOnly rootProject.ext.dependencies.mogomapapi

View File

@@ -12,9 +12,13 @@ import com.mogo.commons.network.AllAllowedHostnameVerifier;
import com.mogo.commons.network.Constants;
import com.mogo.commons.network.ParamsUtil;
import com.mogo.commons.network.X509TrustManagerImpl;
import com.mogo.commons.storage.SpStorage;
import com.mogo.utils.TipToast;
import com.mogo.utils.glide.GlideApp;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.NetConfig;
import com.zhidao.account.sdk.AccountClientManager;
import com.zhidao.account.sdk.callback.TicketInfoCallback;
import java.io.InputStream;
import java.security.SecureRandom;
@@ -32,6 +36,8 @@ import okhttp3.OkHttpClient;
*/
public class AbsMogoApplication extends Application {
private static final String TAG = "AbsMogoApplication";
private static Application sApp;
public static Application getApp() {
@@ -66,7 +72,7 @@ public class AbsMogoApplication extends Application {
TipToast.init( sApp, null );
initNetConfig();
initAccountSdk();
// initAccountSdk();
}
private static void initNetConfig() {
@@ -96,7 +102,18 @@ public class AbsMogoApplication extends Application {
return sc;
}
private static void initAccountSdk(){
// AccountClientManager.init(context,businessType,appId);
private static void initAccountSdk() {
AccountClientManager.init( sApp, 1, "os2.0-launcher" );
AccountClientManager.getTicket( new TicketInfoCallback() {
@Override
public void onSuccess( String ticket ) {
SpStorage.setTicket( ticket );
}
@Override
public void onFailure( int code, String msg ) {
Logger.w( TAG, "request ticket error code = %d, msg = %s", code, msg );
}
} );
}
}

View File

@@ -27,4 +27,44 @@ public class DebugConfig {
public static void setDebug( boolean sDebug ) {
DebugConfig.sDebug = sDebug;
}
/**
* 研发环境
*/
public static final int NET_MODE_DEV = 1;
/**
* 测试环境
*/
public static final int NET_MODE_QA = 2;
/**
* 生产环境
*/
public static final int NET_MODE_RELEASE = 3;
private static int sNetMode = NET_MODE_RELEASE;
/**
* 获取网络环境类型
*
* @return {@link #NET_MODE_DEV}
* {@link #NET_MODE_QA}
* {@link #NET_MODE_RELEASE}
*/
public static int getNetMode() {
return sNetMode;
}
/**
* 设置网络环境类型
*
* @param netMode {@link #NET_MODE_DEV}
* {@link #NET_MODE_QA}
* {@link #NET_MODE_RELEASE}
*/
public static void setNetMode( int netMode ) {
DebugConfig.sNetMode = netMode;
}
}

View File

@@ -8,6 +8,7 @@ import androidx.collection.ArrayMap;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.storage.SpStorage;
import com.mogo.map.location.MogoLocation;
import com.mogo.utils.CommonUtils;
import com.mogo.utils.DeviceIdUtils;
@@ -42,6 +43,7 @@ public class ParamsUtil {
params.put( ServerParam.DISPLAY_ID, DeviceUtil.getSystemVersion() );
params.put( ServerParam.SN, Utils.getSn() );
params.put( ServerParam.TICKET, SpStorage.getTicket() );
return params;
}

View File

@@ -1,19 +1,19 @@
package com.mogo.commons.network;
import android.content.Context;
import com.mogo.commons.data.BaseData;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.RequestOptions;
import com.mogo.utils.network.utils.GsonUtil;
import com.mogo.utils.network.utils.Util;
import rx.Subscriber;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
/**
* Created by congtaowang on 2018/10/14.
*/
public abstract class SubscribeImpl< T extends BaseData > extends Subscriber< T > {
public abstract class SubscribeImpl< T extends BaseData > implements Observer< T > {
protected final RequestOptions mRequestOptions;
@@ -29,32 +29,11 @@ public abstract class SubscribeImpl< T extends BaseData > extends Subscriber< T
mAutoTipMsg = autoTipMsg;
}
@Override
public void onStart() {
super.onStart();
if ( !Util.checkAlive( mRequestOptions.getCaller() ) ) {
unsubscribe();
return;
}
final Context context = Util.getContext( mRequestOptions.getCaller() );
}
@Override
public void onCompleted() {
onFinish();
}
private void onFinish() {
onUnsubscribe();
if ( !Util.checkAlive( mRequestOptions.getCaller() ) ) {
unsubscribe();
}
}
private void onUnsubscribe() {
final Context context = Util.getContext( mRequestOptions.getCaller() );
}
@Override
public void onError( Throwable e ) {
onFinish();
@@ -74,18 +53,28 @@ public abstract class SubscribeImpl< T extends BaseData > extends Subscriber< T
}
}
@Override
public void onSubscribe( Disposable d ) {
}
@Override
public void onComplete() {
onFinish();
}
public void onSuccess( T o ) {
Logger.e( TAG, GsonUtil.jsonFromObject( o ) );
}
public void onError( String message, int code ) {
Logger.e( TAG, "%d - %s", code, message );
}
private static boolean isTicketUpdated = false;
private void onUpdateTicket() {
}
}

View File

@@ -0,0 +1,21 @@
package com.mogo.commons.storage;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.utils.storage.SharedPrefsMgr;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* sp 公共缓存区域
*/
public class SpStorage {
public static String getTicket() {
return SharedPrefsMgr.getInstance( AbsMogoApplication.getApp() ).getString( "ticket" );
}
public static void setTicket( String ticket ) {
SharedPrefsMgr.getInstance( AbsMogoApplication.getApp() ).putString( "ticket", ticket );
}
}

View File

@@ -6,7 +6,7 @@ import androidx.collection.ArrayMap;
import java.util.Map;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public final class RetrofitFactory {
@@ -21,7 +21,7 @@ public final class RetrofitFactory {
target = new Retrofit.Builder().
client(OkHttpFactory.getInstance()).
baseUrl(baseUrl).
addCallAdapterFactory(RxJavaCallAdapterFactory.create()).
addCallAdapterFactory( RxJava2CallAdapterFactory.create()).
addConverterFactory(GsonConverterFactory.create()).
build();
sRpcServiceMap.put(baseUrl,target);

View File

@@ -1,95 +0,0 @@
package com.mogo.utils.network;
import androidx.annotation.CallSuper;
import com.mogo.utils.network.ui.ProgressDialog;
import com.mogo.utils.network.utils.Util;
import rx.Subscriber;
/**
* <p>
* Extension of {@link Subscriber}. For better extension and customization, client can extend this
* class to override the default behaviours such as loading appearance on each lifecycle method
* of network callback.<p/>
*/
public abstract class SubscriberEx< T > extends Subscriber< T > {
protected final RequestOptions mRequestOptions;
private ProgressDialog mProgressDialog;
public SubscriberEx( RequestOptions requestOptions ) {
if ( requestOptions == null ) {
throw new IllegalArgumentException( "RequestOptions cannot be null" );
}
this.mRequestOptions = requestOptions;
if ( mRequestOptions.isLoading() ) {
this.mProgressDialog = new ProgressDialog();
}
}
/**
* This method must be called if you want to use the default loading dialog in case of override.
* Otherwise you can ignore it.
*/
@Override
@CallSuper
public void onStart() {
super.onStart();
if ( !Util.checkAlive( mRequestOptions.getCaller() ) ) {
unsubscribe();
return;
}
if ( mRequestOptions.isLoading() && mProgressDialog != null ) {
mProgressDialog.showLoadingDialog( mRequestOptions.getContext(), mRequestOptions.getLoadingMessage(), mRequestOptions.isCancelable(), mRequestOptions.isCancelableOnTouchOutside() );
}
}
/**
* This method must be called if you want to use the default loading dialog in case of override.
* Otherwise you can ignore it.
*/
private void onFinish() {
if ( mRequestOptions.isLoading() && mProgressDialog != null ) {
mProgressDialog.removeLoadingDialog();
mProgressDialog = null;
}
if ( !Util.checkAlive( mRequestOptions.getCaller() ) ) {
unsubscribe();
}
}
/**
* This method must be called if you want to use the default loading dialog in case of override.
* Otherwise you can ignore it.
*/
@Override
@CallSuper
public void onCompleted() {
onFinish();
}
/**
* This method must be called if you want to use the default loading dialog in case of override.
* Otherwise you can ignore it.
*/
@Override
@CallSuper
public void onError( Throwable e ) {
onFinish();
}
/**
* This method must be override if you care about the result of request.
*
* @param o The result of network request
*/
@Override
@CallSuper
public void onNext( T o ) {
}
}

View File

@@ -43,4 +43,5 @@ MOGO_MODULE_APPS_VERSION=1.0.0-SNAPSHOT
MOGO_CONNECTION_VERSION=1.0.0-SNAPSHOT
MOGO_MODULE_NAVI_VERSION=1.0.0-SNAPSHOT
MOGO_MODULE_SERVICE_VERSION=1.0.0-SNAPSHOT
MOGO_MODULE_EXTENSIONS_VERSION=1.0.0-SNAPSHOT

View File

@@ -38,7 +38,8 @@ import com.mogo.utils.logger.Logger;
* <p>
* 代理高德导航地图
*/
public class AMapNaviViewWrapper implements IMogoMapView, IMogoMapUIController,
public class AMapNaviViewWrapper implements IMogoMapView,
IMogoMapUIController,
AMap.OnMarkerClickListener,
AMap.OnMapLoadedListener,
AMap.OnMapTouchListener,
@@ -138,10 +139,13 @@ public class AMapNaviViewWrapper implements IMogoMapView, IMogoMapUIController,
mMapView.setOnMapTouchListener( this );
mMapView.setOnPolylineClickListener( this );
mMapView.setAMapNaviViewListener( this );
if ( mMapView.getMap() != null ) {
mMapView.getMap().setOnPOIClickListener( this );
mMapView.getMap().setOnMapClickListener( this );
mMapView.getMap().setOnCameraChangeListener( this );
mMapView.setOnCameraChangeListener( this );
final AMap aMap = mMapView.getMap();
if ( aMap != null ) {
aMap.setOnPOIClickListener( this );
aMap.setOnMapClickListener( this );
aMap.setOnCameraChangeListener( this );
}
AMapMessageManager.getInstance().registerAMapMessageListener( this );
}
@@ -428,6 +432,11 @@ public class AMapNaviViewWrapper implements IMogoMapView, IMogoMapUIController,
return getMap().getScalePerPixel();
}
@Override
public float getZoomLevel() {
return getMap().getZoomLevel();
}
@Override
public void onNaviStarted() {
if ( checkAMapView() ) {
@@ -449,7 +458,6 @@ public class AMapNaviViewWrapper implements IMogoMapView, IMogoMapUIController,
@Override
public void onCameraChange( CameraPosition cameraPosition ) {
}
@Override
@@ -458,4 +466,24 @@ public class AMapNaviViewWrapper implements IMogoMapView, IMogoMapUIController,
MogoMapListenerHandler.getInstance().onMapChanged( ObjectUtils.fromAMap( cameraPosition.target ), cameraPosition.zoom, cameraPosition.tilt, cameraPosition.bearing );
}
}
@Override
public MogoLatLng getCameraNorthEastPosition() {
try {
return ObjectUtils.fromAMap( mMapView.getMap().getProjection().getVisibleRegion().latLngBounds.northeast );
} catch ( Exception e ) {
}
return null;
}
@Override
public MogoLatLng getCameraSouthWestPosition() {
try {
return ObjectUtils.fromAMap( mMapView.getMap().getProjection().getVisibleRegion().latLngBounds.southwest );
} catch ( Exception e ) {
}
return null;
}
}

View File

@@ -11,6 +11,7 @@ import com.mogo.map.IMogoMap;
import com.mogo.map.IMogoUiSettings;
import com.mogo.map.impl.amap.marker.AMapInfoWindowAdapter;
import com.mogo.map.impl.amap.marker.AMapMarkerWrapper;
import com.mogo.map.impl.amap.uicontroller.AMapUIController;
import com.mogo.map.impl.amap.utils.ObjectUtils;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
@@ -43,6 +44,7 @@ public class AMapWrapper implements IMogoMap {
mUIcontroller = controller;
// 设置实现自定义 info window
mAMap.setInfoWindowAdapter( new AMapInfoWindowAdapter() );
AMapUIController.getInstance().initClient( mUIcontroller );
}
public static AMap getAMap() {
@@ -205,6 +207,18 @@ public class AMapWrapper implements IMogoMap {
}
}
@Override
public float getZoomLevel() {
if ( checkAMap() ) {
try {
return mAMap.getCameraPosition().zoom;
} catch ( Exception e ) {
}
}
return 0;
}
private boolean checkAMap() {
if ( mAMap == null ) {
Logger.e( TAG, "高德map实例为空请检查" );

View File

@@ -21,11 +21,6 @@ public class AMapUIController implements IMogoMapUIController {
private IMogoMapUIController mClient;
private AMapUIController() {
try {
mClient = MogoMap.getInstance().getMogoMap().getUIController();
} catch ( Exception e ) {
Logger.e( TAG, "获取UI控制实例失败", e );
}
}
public static AMapUIController getInstance() {
@@ -39,6 +34,10 @@ public class AMapUIController implements IMogoMapUIController {
return sInstance;
}
public void initClient( IMogoMapUIController client ) {
this.mClient = client;
}
public synchronized void release() {
sInstance = null;
}
@@ -74,7 +73,7 @@ public class AMapUIController implements IMogoMapUIController {
@Override
public void moveToCenter( MogoLatLng latLng ) {
if ( mClient != null ) {
mClient.moveToCenter(latLng);
mClient.moveToCenter( latLng );
}
}
@@ -106,4 +105,28 @@ public class AMapUIController implements IMogoMapUIController {
}
return 0;
}
@Override
public float getZoomLevel() {
if ( mClient != null ) {
return mClient.getZoomLevel();
}
return 0;
}
@Override
public MogoLatLng getCameraNorthEastPosition() {
if ( mClient != null ) {
return mClient.getCameraNorthEastPosition();
}
return null;
}
@Override
public MogoLatLng getCameraSouthWestPosition() {
if ( mClient != null ) {
return mClient.getCameraSouthWestPosition();
}
return null;
}
}

View File

@@ -114,5 +114,17 @@ public interface IMogoMap {
*/
float getScalePerPixel();
void changeZoom(float zoom);
/**
* 改变地图缩放级别
*
* @param zoom
*/
void changeZoom( float zoom );
/**
* 获取缩放比例
*
* @return
*/
float getZoomLevel();
}

View File

@@ -66,4 +66,25 @@ public interface IMogoMapUIController {
* @return 当前缩放级别下地图上1像素点对应的长度单位米
*/
float getScalePerPixel();
/**
* 获取缩放比例
*
* @return
*/
float getZoomLevel();
/**
* 获取视图东北角坐标
*
* @return
*/
MogoLatLng getCameraNorthEastPosition();
/**
* 获取视图西南角坐标
*
* @return
*/
MogoLatLng getCameraSouthWestPosition();
}

View File

@@ -98,4 +98,28 @@ public class MogoMapUIController implements IMogoMapUIController {
}
return 0;
}
@Override
public float getZoomLevel() {
if ( mDelegate != null ) {
return mDelegate.getZoomLevel();
}
return 0;
}
@Override
public MogoLatLng getCameraNorthEastPosition() {
if ( mDelegate != null ) {
return mDelegate.getCameraNorthEastPosition();
}
return null;
}
@Override
public MogoLatLng getCameraSouthWestPosition() {
if ( mDelegate != null ) {
return mDelegate.getCameraSouthWestPosition();
}
return null;
}
}

View File

@@ -14,6 +14,7 @@ import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
/**
* @author congtaowang
@@ -57,7 +58,7 @@ public class AppsFragmentProvider implements IMogoModuleProvider {
@Override
public int getType() {
return IMogoModuleProvider.TYPE_FRAGMENT;
return ModuleType.TYPE_APP_LIST;
}
@Override

View File

@@ -9,6 +9,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:behavior_hideable="false"
app:behavior_peekHeight="50dp"
app:behavior_peekHeight="92dp"
app:layout_behavior="@string/bottom_sheet_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -7,8 +7,8 @@
<ImageView
android:id="@+id/module_apps_id_app_icon"
android:layout_width="75dp"
android:layout_height="75dp" />
android:layout_width="60dp"
android:layout_height="60dp" />
<TextView
android:id="@+id/module_apps_id_app_name"

View File

@@ -0,0 +1,51 @@
package com.mogo.module.common;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 模块类型
*/
public interface ModuleType {
/**
* 卡片类型 - fragment
*/
int TYPE_CARD_FRAGMENT = 1;
/**
* 卡片类型 - view
*/
@Deprecated
int TYPE_CARD_VIEW = 2;
/**
* 服务类型的模块
*/
int TYPE_SERVICE = 3;
/**
* APP 列表模块
*/
int TYPE_APP_LIST = 4;
/**
* 小智语音形象
*/
int TYPE_VOICE = 5;
/**
* 地图模块
*/
int TYPE_MAP = 6;
/**
* 导航模块
*/
int TYPE_NAVI = 7;
/**
* 小智、天气、时间等
*/
int TYPE_EXTENSION = 8;
}

View File

@@ -18,6 +18,10 @@ public class MogoModule {
*/
private String mName;
/**
* @param path 模块加载路径
* @param name 模块名称
*/
public MogoModule( String path, String name ) {
this.mPath = path;
this.mName = name;

View File

@@ -29,13 +29,21 @@ public class MogoModulePaths {
@Keep
public static final String PATH_MODULE_APPS = "/appslist/ui";
/**
* 添加卡片模块
*
* @param path
*/
@Deprecated
public static void addModule( String path ) {
if ( TextUtils.isEmpty( path.replace( " ", "" ) ) ) {
throw new IllegalArgumentException( "module path can't be empty or null or blank" );
}
mMogoModules.add( new MogoModule( path, "" ) );
throw new IllegalArgumentException( "this method can't be invoked." );
}
/**
* 添加卡片模块
*
* @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" );

View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,9 @@
# launcher头部模块
## 小智语音
## 通知
## 天气
## 时间

View File

@@ -0,0 +1,60 @@
apply plugin: 'com.android.library'
apply plugin: 'com.alibaba.arouter'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode Integer.valueOf(VERSION_CODE)
versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION")
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.arouter
annotationProcessor rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxjava
implementation rootProject.ext.dependencies.rxandroid
if (Boolean.valueOf(RELEASE)) {
api rootProject.ext.dependencies.mogomap
api rootProject.ext.dependencies.mogomapapi
api rootProject.ext.dependencies.mogoutils
api rootProject.ext.dependencies.mogocommons
api rootProject.ext.dependencies.mogoserviceapi
implementation rootProject.ext.dependencies.modulecommon
} else {
api project(":libraries:mogo-map")
api project(":libraries:mogo-map-api")
api project(":foudations:mogo-utils")
api project(":foudations:mogo-commons")
api project(':services:mogo-service-api')
implementation project(':modules:mogo-module-common')
}
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.module
POM_ARTIFACT_ID=module-extensions
VERSION_CODE=1

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,27 @@
package com.mogo.module.extensions;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith( AndroidJUnit4.class )
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals( "com.mogo.module.extensions.test", appContext.getPackageName() );
}
}

View File

@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.module.extensions" />

View File

@@ -0,0 +1,99 @@
package com.mogo.module.extensions;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mogo.commons.mvp.MvpFragment;
/**
* @author congtaowang
* @since 2020-01-05
* <p>
* 描述
*/
public class ExtensionsFragment extends MvpFragment< ExtensionsView, ExtensionsPresenter > implements ExtensionsView {
private View mVoiceIcon;
private View mVoiceMsg;
private TextView mTime;
private TextView mDate;
private View mWeatherContainer;
private ImageView mWeatherIcon;
private TextView mWeatherTemp;
private TextView mWeatherDesc;
private View mMsgContainer;
private TextView mMsgCounter;
@Override
protected int getLayoutId() {
return R.layout.module_ext_layout_extensions;
}
@Override
protected void initViews() {
mVoiceIcon = findViewById( R.id.module_ext_id_voice );
mVoiceMsg = findViewById( R.id.module_ext_id_voice_msg );
mVoiceIcon.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View v ) {
mVoiceMsg.performClick();
}
} );
mVoiceMsg.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View v ) {
}
} );
mTime = findViewById( R.id.module_ext_id_time );
mDate = findViewById( R.id.module_ext_id_date );
mWeatherContainer = findViewById( R.id.module_ext_id_weather_container );
mWeatherIcon = findViewById( R.id.module_ext_id_weather_icon );
mWeatherTemp = findViewById( R.id.module_ext_id_weather_temp );
mWeatherDesc = findViewById( R.id.module_ext_id_weather_desc );
mMsgContainer = findViewById( R.id.module_ext_id_msg );
mMsgCounter = findViewById( R.id.module_ext_id_msg_counter );
}
@NonNull
@Override
protected ExtensionsPresenter createPresenter() {
return new ExtensionsPresenter( this );
}
@Override
public void onActivityCreated( @Nullable Bundle savedInstanceState ) {
super.onActivityCreated( savedInstanceState );
}
@Override
public void renderTime( String date, String time ) {
mDate.setText( date );
mTime.setText( time );
}
@Override
public void renderWeatherInfo( String temp, String desc, int iconId ) {
if ( iconId != 0 ) {
mWeatherIcon.setImageResource( iconId );
mWeatherIcon.setVisibility( View.VISIBLE );
} else {
mWeatherIcon.setVisibility( View.GONE );
}
mWeatherTemp.setText( temp );
mWeatherDesc.setText( desc );
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.module.extensions;
/**
* @author congtaowang
* @since 2020-01-05
* <p>
* 描述
*/
public class ExtensionsModuleConst {
public static final String PATH_EXTENSION = "/extension/ui";
public static final String TYPE = "extension";
}

View File

@@ -0,0 +1,74 @@
package com.mogo.module.extensions;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
/**
* @author congtaowang
* @since 2020-01-05
* <p>
* 描述
*/
@Route( path = ExtensionsModuleConst.PATH_EXTENSION )
public class ExtensionsModuleProvider implements IMogoModuleProvider {
@Override
public Fragment createFragment( Context context, Bundle data ) {
ExtensionsFragment fragment = new ExtensionsFragment();
fragment.setArguments( data );
return fragment;
}
@Override
public View createView( Context context ) {
return null;
}
@NonNull
@Override
public String getModuleName() {
return ExtensionsModuleConst.TYPE;
}
@Override
public IMogoModuleLifecycle getCardLifecycle() {
return null;
}
@Override
public IMogoMapListener getMapListener() {
return null;
}
@Override
public int getType() {
return ModuleType.TYPE_EXTENSION;
}
@Override
public IMogoNaviListener getNaviListener() {
return null;
}
@Override
public IMogoLocationListener getLocationListener() {
return null;
}
@Override
public void init( Context context ) {
}
}

View File

@@ -0,0 +1,111 @@
package com.mogo.module.extensions;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import com.mogo.commons.mvp.Presenter;
import com.mogo.module.extensions.weather.Phenomena;
import com.mogo.module.extensions.weather.WeatherCallback;
import com.mogo.module.extensions.weather.WeatherInfo;
import com.mogo.module.extensions.weather.WeatherModel;
import com.mogo.utils.logger.Logger;
import java.util.Calendar;
/**
* @author congtaowang
* @since 2020-01-05
* <p>
* 描述
*/
public class ExtensionsPresenter extends Presenter< ExtensionsView > implements WeatherCallback {
private static final String TAG = "ExtensionsPresenter";
private String[] mWeeks;
private WeatherModel mWeatherModel;
/**
* 接收时间变化的广播
*/
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive( Context context, Intent intent ) {
try {
refreshTimeAndDate();
} catch ( Exception e ) {
Logger.e( TAG, "error. ", e );
}
}
};
public ExtensionsPresenter( ExtensionsView view ) {
super( view );
mWeeks = getContext().getResources().getStringArray( R.array.module_ext_str_arr_week );
mWeatherModel = new WeatherModel( getContext() );
}
@Override
public void onCreate( @NonNull LifecycleOwner owner ) {
super.onCreate( owner );
registerTimerReceiver();
mWeatherModel.init( this );
mWeatherModel.queryWeatherInformation();
refreshTimeAndDate();
}
/**
* 注册时间变化监听
*/
private void registerTimerReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction( Intent.ACTION_TIME_TICK );
filter.addAction( Intent.ACTION_TIME_CHANGED );
filter.addAction( Intent.ACTION_TIMEZONE_CHANGED );
filter.addAction( Intent.ACTION_CONFIGURATION_CHANGED );
getContext().registerReceiver( mReceiver, filter );
}
private void refreshTimeAndDate() {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get( Calendar.HOUR_OF_DAY );
int minute = calendar.get( Calendar.MINUTE );
int month = calendar.get( Calendar.MONTH );
int day = calendar.get( Calendar.DAY_OF_MONTH );
int week = calendar.get( Calendar.DAY_OF_WEEK );
String timeStr = getContext().getResources().getString( R.string.module_ext_str_time_format, hour, minute );
String dateStr = getContext().getResources().getString( R.string.module_ext_str_date_format, month + 1, day, mWeeks[week - 1] );
mView.renderTime( dateStr, timeStr );
}
@Override
public void onWeatherLoaded( WeatherInfo weatherInfo ) {
if ( weatherInfo == null ) {
return;
}
String temp = getContext().getResources().getString( R.string.module_ext_str_weather_temp_format, weatherInfo.getTemperature() );
Phenomena phenomena = Phenomena.getById( weatherInfo.getPhenomena() );
String desc = phenomena == null ? "" : phenomena.nameCn;
int resId = 0;
mView.renderWeatherInfo( temp, desc, resId );
}
@Override
public void onDestroy( @NonNull LifecycleOwner owner ) {
super.onDestroy( owner );
if ( mWeatherModel != null ) {
mWeatherModel.destroy();
}
}
}

View File

@@ -0,0 +1,30 @@
package com.mogo.module.extensions;
import com.mogo.commons.mvp.IView;
import com.mogo.module.extensions.weather.WeatherInfo;
/**
* @author congtaowang
* @since 2020-01-05
* <p>
* 描述
*/
public interface ExtensionsView extends IView {
/**
* 刷新日期、时间
*
* @param date 日期
* @param time 时间
*/
void renderTime( String date, String time );
/**
* 天气信息
*
* @param desc 天气描述:晴转多云
* @param temp 温度
* @param iconId 图标
*/
void renderWeatherInfo( String temp, String desc, int iconId );
}

View File

@@ -0,0 +1,97 @@
package com.mogo.module.extensions.weather;
import android.text.TextUtils;
import java.util.HashMap;
import java.util.Map;
/**
* @author Lzq
*/
public enum Phenomena {
Sunny( "00", "", "Sunny" ),
Cloudy( "01", "多云", "Cloudy" ),
Overcast( "02", "", "Overcast" ),
Shower( "03", "阵雨", "Shower" ),
Thundershower( "04", "雷阵雨", "Thundershower" ),
ThundershowerWithHail( "05", "雷阵雨伴有冰雹", "Thundershower with hail" ),
Sleet( "06", "雨夹雪", "Sleet" ),
LightRain( "07", "小雨", "Light rain" ),
ModerateRain( "08", "中雨", "Moderate rain" ),
HeavyRain( "09", "大雨", "Heavy rain" ),
Storm( "10", "暴雨", "Storm" ),
HeavyStorm( "11", "大暴雨", "Heavy storm" ),
SevereStorm( "12", "特大暴雨", "Severe storm" ),
SnowFlurry( "13", "阵雪", "Snow flurry" ),
LightSnow( "14", "小雪", "Light snow" ),
ModerateSnow( "15", "中雪", "Moderate snow" ),
HeavySnow( "16", "大雪", "Heavy snow" ),
Snowstorm( "17", "暴雪", "Snowstorm" ),
Foggy( "18", "", "Foggy" ),
IceRain( "19", "冻雨", "Ice rain" ),
Duststorm( "20", "沙尘暴", "Duststorm" ),
LightToModerateRain( "21", "小到中雨", "Light to moderate rain" ),
ModerateToHeavyRain( "22", "中到大雨", "Moderate to heavy rain" ),
HeavyRainToStorm( "23", "大到大雨", "Heavy rain to storm" ),
StormToHeavyStorm( "24", "暴雨到大暴雨", "Storm to heavy storm" ),
HeavyToSevereStorm( "25", "大暴雨到特大暴雨", "Heavy to severe storm" ),
LightToModerateSnow( "26", "小到中雪", "Light to moderate snow" ),
ModerateToHeavySnow( "27", "中到大雪", "Moderate to heavy snow" ),
HeavySnowToSnowStorm( "28", "大到暴雪", "Heavy snow to snowstorm" ),
Dust( "29", "浮尘", "Dust" ),
Sand( "30", "扬沙", "Sand" ),
SandStorm( "31", "强沙尘暴", "Sandstorm" ),
Densefog( "32", "浓雾", "Dense fog" ),
StrongFog( "49", "强浓雾", "Strong fog" ),
DenseFog( "57", "大雾", "Dense fog" ),
ExtraHeavyFog( "58", "特强浓雾", "Extra heavy fog" ),
Haze( "53", "", "Haze" ),
ModerateHaze( "54", "中度霾", "Moderate haze" ),
Severehaze( "55", "重度霾", "Severe haze" ),
SevereHaze( "56", "严重霾", "Severe haze" ),
Unknown( "99", "", "Unknown" ),
Rain( "301", "", "rain" ),
Snow( "302", "", "snow" );
public final String id;
public final String nameCn;
public final String nameEn;
Phenomena( String id, String nameCn, String nameEn ) {
this.id = id;
this.nameCn = nameCn;
this.nameEn = nameEn;
}
static Map< String, Phenomena > mPhenomenas;
static {
if ( mPhenomenas == null ) {
synchronized ( Phenomena.class ) {
if ( mPhenomenas == null ) {
mPhenomenas = new HashMap<>();
for ( Phenomena weather : Phenomena.values() ) {
mPhenomenas.put( weather.id, weather );
}
}
}
}
}
public static synchronized Phenomena getById( String id ) {
if ( TextUtils.isEmpty( id ) ) {
return null;
}
return mPhenomenas.get( id );
}
}

View File

@@ -0,0 +1,5 @@
package com.mogo.module.extensions.weather;
public interface WeatherCallback {
void onWeatherLoaded( WeatherInfo weatherInfo );
}

View File

@@ -0,0 +1,32 @@
package com.mogo.module.extensions.weather;
/**
* 天气
*/
public class WeatherConstants {
public final static String WEATHER_URI = "content://com.zhidao.weather/weatherinfo";
/**
* 天气
*/
public static final String TEMPERATURE = "observetemperature";
/**
* 气象
*/
public static final String PHENOMENA = "observephenomena";
/**
* 风向
*/
public static final String WIND_DIRECTION = "observewinddirection";
/**
* 风力
*/
public static final String WIND_FORCE = "observewindforce";
/**
* 天气消息加载完毕
*/
public static final int MSG_WEATHER_LOADED = 0x1000;
}

View File

@@ -0,0 +1,142 @@
package com.mogo.module.extensions.weather;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import java.util.Objects;
/**
* 天气
*/
public class WeatherInfo implements Parcelable {
/**
* 温度
*/
private String temperature;
/**
* 描述信息
*/
private String phenomena;
/**
* 风向
*/
private String windDirection;
/**
* 风力
*/
private String windForce;
@Override
public String toString() {
return "WeatherInfo{" +
"temperature='" + temperature + '\'' +
", phenomena='" + phenomena + '\'' +
", windDirection='" + windDirection + '\'' +
", windForce='" + windForce + '\'' +
'}';
}
@Override
public boolean equals( Object o ) {
if ( this == o ) {
return true;
}
if ( !( o instanceof WeatherInfo ) ) {
return false;
}
WeatherInfo that = ( WeatherInfo ) o;
return Objects.equals( temperature, that.temperature ) &&
Objects.equals( phenomena, that.phenomena ) &&
Objects.equals( windDirection, that.windDirection ) &&
Objects.equals( windForce, that.windForce );
}
@Override
public int hashCode() {
return Objects.hash( temperature, phenomena, windDirection, windForce );
}
public WeatherInfo() {
}
public WeatherInfo( String temperature, String phenomena, String windDirection, String windForce ) {
this.temperature = temperature;
this.phenomena = phenomena;
this.windDirection = windDirection;
this.windForce = windForce;
}
public String getTemperature() {
return temperature;
}
public void setTemperature( String temperature ) {
this.temperature = temperature;
}
public String getPhenomena() {
return phenomena;
}
public void setPhenomena( String phenomena ) {
this.phenomena = phenomena;
}
public String getWindDirection() {
return windDirection;
}
public void setWindDirection( String windDirection ) {
this.windDirection = windDirection;
}
public String getWindForce() {
return windForce;
}
public void setWindForce( String windForce ) {
this.windForce = windForce;
}
public boolean isLegal() {
return !TextUtils.isEmpty( phenomena )
&& !TextUtils.isEmpty( temperature );
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel( Parcel dest, int flags ) {
dest.writeString( this.temperature );
dest.writeString( this.phenomena );
dest.writeString( this.windDirection );
dest.writeString( this.windForce );
}
protected WeatherInfo( Parcel in ) {
this.temperature = in.readString();
this.phenomena = in.readString();
this.windDirection = in.readString();
this.windForce = in.readString();
}
public static final Creator< WeatherInfo > CREATOR = new Creator< WeatherInfo >() {
@Override
public WeatherInfo createFromParcel( Parcel source ) {
return new WeatherInfo( source );
}
@Override
public WeatherInfo[] newArray( int size ) {
return new WeatherInfo[size];
}
};
}

View File

@@ -0,0 +1,127 @@
package com.mogo.module.extensions.weather;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import androidx.annotation.NonNull;
import com.mogo.utils.ThreadPoolService;
import com.mogo.utils.logger.Logger;
/**
* @author congtaowang
* @since 2020-01-05
* <p>
* 描述
*/
public class WeatherModel {
private static final String TAG = "WeatherModel";
private Context mContext;
private Uri mWeatherUri;
private Handler mHandler;
private ContentResolver mContentResolver;
private ContentObserver mContentObserver;
private WeatherCallback mCallback;
public WeatherModel( Context context ) {
this.mContext = context;
}
public void init( WeatherCallback callback ) {
mCallback = callback;
mWeatherUri = Uri.parse( WeatherConstants.WEATHER_URI );
mContentResolver = mContext.getContentResolver();
mHandler = new Handler( Looper.getMainLooper() ) {
@Override
public void handleMessage( @NonNull Message msg ) {
if ( msg.what == WeatherConstants.MSG_WEATHER_LOADED ) {
if ( mCallback != null ) {
mCallback.onWeatherLoaded( ( ( WeatherInfo ) msg.obj ) );
}
}
}
};
mContentObserver = new ContentObserver( mHandler ) {
@Override
public void onChange( boolean selfChange, Uri uri ) {
super.onChange( selfChange, uri );
try {
queryWeatherInformation();
} catch ( Exception e ) {
Logger.e( TAG, "error. ", e );
}
}
};
mContentResolver.registerContentObserver( mWeatherUri, false, mContentObserver );
}
public void queryWeatherInformation() {
if ( mCallback == null ) {
Logger.e( TAG, "WeatherModel#init should invoked " );
return;
}
startNewThreadToQuery();
}
private void startNewThreadToQuery() {
ThreadPoolService.execute( new Runnable() {
@Override
public void run() {
if ( mContentResolver == null ) {
return;
}
Cursor cursor = mContentResolver.query( mWeatherUri, null, null, null, null, null );
if ( cursor == null ) {
return;
}
WeatherInfo weatherInfo = new WeatherInfo();
if ( cursor.moveToFirst() ) {
int index = cursor.getColumnIndex( WeatherConstants.TEMPERATURE );
if ( index != -1 ) {
weatherInfo.setTemperature( cursor.getString( index ) );
}
index = cursor.getColumnIndex( WeatherConstants.PHENOMENA );
if ( index != -1 ) {
weatherInfo.setPhenomena( cursor.getString( index ) );
}
index = cursor.getColumnIndex( WeatherConstants.WIND_DIRECTION );
if ( index != -1 ) {
weatherInfo.setWindDirection( cursor.getString( index ) );
}
index = cursor.getColumnIndex( WeatherConstants.WIND_FORCE );
if ( index != -1 ) {
weatherInfo.setWindForce( cursor.getString( index ) );
}
Message msg = Message.obtain();
msg.obj = weatherInfo;
msg.what = WeatherConstants.MSG_WEATHER_LOADED;
mHandler.sendMessage( msg );
}
cursor.close();
}
} );
}
public void destroy() {
if ( mContentResolver != null && mContentObserver != null ) {
mContentResolver.unregisterContentObserver( mContentObserver );
}
mContext = null;
mWeatherUri = null;
mHandler = null;
mContentResolver = null;
mContentObserver = null;
mCallback = null;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners android:radius="90dp" />
<solid android:color="#DA2E55" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,125 @@
<?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="60dp"
android:orientation="vertical"
android:paddingLeft="35dp"
android:paddingRight="35dp">
<ImageView
android:id="@+id/module_ext_id_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/module_ext_ic_voice"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/module_ext_id_voice_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/module_ext_str_voice_msg"
android:textColor="@color/module_ext_color_voice_text"
android:textSize="16dp"
app:layout_constraintBottom_toBottomOf="@+id/module_ext_id_voice"
app:layout_constraintLeft_toRightOf="@+id/module_ext_id_voice"
app:layout_constraintTop_toTopOf="@+id/module_ext_id_voice" />
<TextView
android:id="@+id/module_ext_id_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="#FFFFFF"
android:textSize="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="10:10" />
<TextView
android:id="@+id/module_ext_id_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="40dp"
android:gravity="center_vertical"
android:textColor="#FFFFFF"
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/module_ext_id_time"
app:layout_constraintTop_toTopOf="parent"
tools:text="11月20日 周三" />
<LinearLayout
android:id="@+id/module_ext_id_weather_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="13dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/module_ext_id_date"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/module_ext_id_weather_icon"
android:layout_width="22dp"
android:layout_height="22dp"
tools:src="@drawable/module_ext_ic_voice" />
<TextView
android:id="@+id/module_ext_id_weather_temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="9dp"
android:textColor="#FFFFFF"
android:textSize="17dp"
tools:text="28°" />
<TextView
android:id="@+id/module_ext_id_weather_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="13dp"
android:textColor="#FFFFFF"
android:textSize="14dp"
tools:text="晴转多云" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/"
android:textColor="#FFFFFF" />
</LinearLayout>
<FrameLayout
android:id="@+id/module_ext_id_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/module_ext_id_weather_container"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/module_ext_ic_message" />
<TextView
android:id="@+id/module_ext_id_msg_counter"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="right"
android:background="@drawable/module_ext_drawable_msg_bkg"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="10dp"
tools:text="···" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="module_ext_color_voice_text">#FFFFFF</color>
</resources>

View File

@@ -0,0 +1,16 @@
<resources>
<string name="app_name">mogo-module-extensions</string>
<string name="module_ext_str_voice_msg">你好蘑菇2.0开启智慧互联新世界</string>
<string name="module_ext_str_date_format">%1$d月%2$d日 %3$s</string>
<string name="module_ext_str_time_format">%1$d:%2$d</string>
<string name="module_ext_str_weather_temp_format">%s° </string>
<string-array name="module_ext_str_arr_week">
<item>周日</item>
<item>周一</item>
<item>周二</item>
<item>周三</item>
<item>周四</item>
<item>周五</item>
<item>周六</item>
</string-array>
</resources>

View File

@@ -0,0 +1,17 @@
package com.mogo.module.extensions;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals( 4, 2 + 2 );
}
}

View File

@@ -45,6 +45,7 @@ dependencies {
implementation rootProject.ext.dependencies.moduleservice
implementation rootProject.ext.dependencies.moduleapps
implementation rootProject.ext.dependencies.mogoconnection
implementation rootProject.ext.dependencies.moduleextensions
} else {
implementation project(":foudations:mogo-utils")
implementation project(":foudations:mogo-commons")
@@ -55,6 +56,7 @@ dependencies {
implementation project(':services:mogo-service')
implementation project(':modules:mogo-module-apps')
implementation project(':foudations:mogo-connection')
implementation project(':modules:mogo-module-extensions')
}
}

View File

@@ -13,15 +13,20 @@ import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.module.common.MogoModule;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.module.extensions.ExtensionsModuleConst;
import com.mogo.module.main.cards.CardModulesAdapter;
import com.mogo.module.main.cards.MogoModulesHandler;
import com.mogo.module.main.cards.MogoModulesManager;
import com.mogo.module.main.cards.OrientedViewPager;
import com.mogo.module.main.cards.VerticalStackTransformer;
import com.mogo.module.service.ServiceConst;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.connection.IMogoSocketManager;
import com.mogo.service.map.IMogoMapService;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
import com.mogo.utils.logger.Logger;
import java.util.List;
@@ -99,11 +104,20 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
protected void onCreate( @Nullable Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
MogoModulePaths.addModule( new MogoModule( MogoModulePaths.PATH_MODULE_APPS, MogoModulePaths.PATH_MODULE_APPS ) );
MogoModulePaths.addModule( new MogoModule( MogoModulePaths.PATH_MODULE_MAP, MogoModulePaths.PATH_MODULE_MAP ) );
MogoModulePaths.addModule( new MogoModule( ServiceConst.PATH_REFRESH_STRATEGY, ServiceConst.PATH_REFRESH_STRATEGY ) );
MogoModulePaths.addModule( new MogoModule( ExtensionsModuleConst.PATH_EXTENSION, ExtensionsModuleConst.TYPE ) );
mMogoModuleHandler = new MogoModulesManager( this );
mMogoMapService = ( IMogoMapService ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICES_MAP ).navigation();
if ( mMogoMapService != null ) {
mMogoMapService.getHostListenerRegister().registerHostMapListener( mMogoModuleHandler );
mMogoMapService.getHostListenerRegister().registerHostNaviListener( mMogoModuleHandler );
mMogoMapService.getHostListenerRegister().registerMarkerClickListener( this );
}
mMogoSocketManager = ( IMogoSocketManager ) ARouter.getInstance().build( MogoServicePaths.PATH_SOCKET_MANAGER ).navigation();
mMogoSocketManager.init( getApplicationContext(), AppConstants.SOCKET_APP_ID );
mMogoModuleHandler.loadModules();
mMogoModuleHandler.onMapLoadedCallback( new Runnable() {
@Override
public void run() {
@@ -111,23 +125,17 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
loadModules();
}
} );
mMogoMapService = ( IMogoMapService ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICES_MAP ).navigation();
if ( mMogoMapService != null ) {
mMogoMapService.getHostListenerRegister().registerHostMapListener( mMogoModuleHandler );
mMogoMapService.getHostListenerRegister().registerHostNaviListener( mMogoModuleHandler );
mMogoMapService.getHostListenerRegister().registerMarkerClickListener( this );
}
// 加载地图,触发地图加载完毕回调,在初始化其他卡片模块,保证卡片模块可以正确获取地图相关服务。
mMogoModuleHandler.loadMap( R.id.module_main_id_map_fragment_container );
mMogoModuleHandler.loadAppsList( R.id.module_main_id_fragment_container );
mMogoModuleHandler.loadExtensions( R.id.module_main_id_ai_fragment_container );
mLocationClient = mMogoMapService.getSingletonLocationClient( getApplicationContext() );
mLocationClient.addLocationListener( this );
mLocationClient.start();
mMogoModuleHandler.loadService();
mMogoModuleHandler.loadAppsList( R.id.module_main_id_fragment_container );
mMogoSocketManager = ( IMogoSocketManager ) ARouter.getInstance().build( MogoServicePaths.PATH_SOCKET_MANAGER ).navigation();
mMogoSocketManager.init( getApplicationContext(), AppConstants.SOCKET_APP_ID );
}
private void loadModules() {

View File

@@ -24,6 +24,8 @@ public interface MogoModulesHandler extends IMogoMapListener,
void onMapLoadedCallback( Runnable callback );
void loadModules();
/**
* 加载卡片
*
@@ -31,20 +33,6 @@ public interface MogoModulesHandler extends IMogoMapListener,
*/
List< IMogoModuleProvider > loadCardsModule();
/**
* 加载小智语音
*
* @param containerId 容器id
*/
void loadAIAssist( int containerId );
/**
* 加载天气
*
* @param containerId 容器id
*/
void loadWeather( int containerId );
/**
* 加载地图
*
@@ -59,6 +47,13 @@ public interface MogoModulesHandler extends IMogoMapListener,
*/
void loadAppsList( int containerId );
/**
* 加载头部信息
*
* @param containerId
*/
void loadExtensions( int containerId );
/**
* 设置某一个module可用
*
@@ -66,11 +61,6 @@ public interface MogoModulesHandler extends IMogoMapListener,
*/
void setEnable( String module );
/**
* 加载服务
*/
void loadService();
/**
* 销毁
*/

View File

@@ -25,6 +25,7 @@ import com.mogo.module.main.receiver.MogoReceiver;
import com.mogo.module.service.ServiceConst;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
import com.mogo.utils.ResourcesHelper;
import com.mogo.utils.logger.Logger;
@@ -49,11 +50,7 @@ public class MogoModulesManager implements MogoModulesHandler,
private MainActivity mActivity;
private final Map< String, IMogoModuleProvider > mCardProviders = new HashMap<>();
private IMogoModuleProvider mMapProvider;
private IMogoModuleProvider mAppsListProvider;
private IMogoModuleProvider mPushProvider;
private IMogoModuleProvider mRefreshStrategyProvider;
private Map< MogoModule, IMogoModuleProvider > mModuleProviders = new HashMap<>();
private String mEnableModuleName = null;
private Runnable mMapLoadedCallback;
@@ -76,6 +73,19 @@ public class MogoModulesManager implements MogoModulesHandler,
return mActivity.getApplicationContext();
}
@Override
public void loadModules() {
final List< MogoModule > modules = MogoModulePaths.getModules();
if ( modules != null && !modules.isEmpty() ) {
for ( MogoModule module : modules ) {
IMogoModuleProvider provider = load( module.getPath() );
if ( provider != null ) {
mModuleProviders.put( module, provider );
}
}
}
}
@Override
public void onMapLoadedCallback( Runnable callback ) {
mMapLoadedCallback = callback;
@@ -83,42 +93,40 @@ public class MogoModulesManager implements MogoModulesHandler,
@Override
public List< IMogoModuleProvider > loadCardsModule() {
final List< MogoModule > modules = MogoModulePaths.getModules();
final ArrayList< IMogoModuleProvider > providers = new ArrayList<>();
if ( modules != null && !modules.isEmpty() ) {
for ( MogoModule module : modules ) {
IMogoModuleProvider provider = load( module.getPath() );
providers.add( provider );
mCardProviders.put( provider.getModuleName(), provider );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
providers.add( value );
}
}
return providers;
}
@Override
public void loadAIAssist( int containerId ) {
}
@Override
public void loadWeather( int containerId ) {
}
private IMogoModuleProvider getModuleProvider( String tag ) {
return mCardProviders.get( tag );
}
@Override
public void loadMap( int containerId ) {
mMapProvider = load( MogoModulePaths.PATH_MODULE_MAP );
addFragment( mMapProvider, containerId );
loadModuleByType( ModuleType.TYPE_MAP, containerId );
}
@Override
public void loadAppsList( int containerId ) {
mAppsListProvider = load( MogoModulePaths.PATH_MODULE_APPS );
addFragment( mAppsListProvider, containerId );
loadModuleByType( ModuleType.TYPE_APP_LIST, containerId );
}
@Override
public void loadExtensions( int containerId ) {
loadModuleByType( ModuleType.TYPE_EXTENSION, containerId );
}
private void loadModuleByType( int type, int containerId ) {
if ( mModuleProviders.isEmpty() ) {
return;
}
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == type ) {
addFragment( value, containerId );
return;
}
}
}
private IMogoModuleProvider load( String path ) {
@@ -140,23 +148,21 @@ public class MogoModulesManager implements MogoModulesHandler,
.commitAllowingStateLoss();
}
@Override
public void loadService() {
mPushProvider = ( IMogoModuleProvider ) ARouter.getInstance().build( "/push/ui" ).navigation( mActivity.getApplicationContext() );
mRefreshStrategyProvider = ( IMogoModuleProvider ) ARouter.getInstance().build( ServiceConst.PATH_REFRESH_STRATEGY ).navigation( mActivity.getApplicationContext() );
}
@Override
public void setEnable( String module ) {
mEnableModuleName = module;
final Set< Map.Entry< String, IMogoModuleProvider > > entries = mCardProviders.entrySet();
final Set< Map.Entry< MogoModule, IMogoModuleProvider > > entries = mModuleProviders.entrySet();
if ( !entries.isEmpty() ) {
for ( Map.Entry< String, IMogoModuleProvider > entry : entries ) {
final String key = entry.getKey();
for ( Map.Entry< MogoModule, IMogoModuleProvider > entry : entries ) {
final MogoModule key = entry.getKey();
final IMogoModuleProvider provider = entry.getValue();
if ( provider.getType() != ModuleType.TYPE_CARD_FRAGMENT ) {
// 仅卡片需要生命周期
continue;
}
final IMogoModuleLifecycle lifecycle = provider.getCardLifecycle();
if ( lifecycle != null ) {
if ( TextUtils.equals( key, mEnableModuleName ) ) {
if ( TextUtils.equals( key.getName(), mEnableModuleName ) ) {
lifecycle.onPerform();
} else {
lifecycle.onDisable();
@@ -169,208 +175,217 @@ public class MogoModulesManager implements MogoModulesHandler,
@Override
public void onMapLoaded() {
if ( mMapLoadedCallback != null ) {
mMapLoadedCallback.run();
mMapLoadedCallback = null;
}
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getMapListener() != null ) {
provider.getMapListener().onMapLoaded();
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getMapListener() != null ) {
mRefreshStrategyProvider.getMapListener().onMapLoaded();
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getMapListener() != null ) {
value.getMapListener().onMapLoaded();
}
}
}
@Override
public void onTouch( MotionEvent motionEvent ) {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getMapListener() != null ) {
provider.getMapListener().onTouch( motionEvent );
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getMapListener() != null ) {
mRefreshStrategyProvider.getMapListener().onTouch( motionEvent );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getMapListener() != null ) {
value.getMapListener().onTouch( motionEvent );
}
}
} else {
if ( value.getMapListener() != null ) {
value.getMapListener().onTouch( motionEvent );
}
}
}
}
@Override
public void onPOIClick( MogoPoi poi ) {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getMapListener() != null ) {
provider.getMapListener().onPOIClick( poi );
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getMapListener() != null ) {
mRefreshStrategyProvider.getMapListener().onPOIClick( poi );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getMapListener() != null ) {
value.getMapListener().onPOIClick( poi );
}
}
} else {
if ( value.getMapListener() != null ) {
value.getMapListener().onPOIClick( poi );
}
}
}
}
@Override
public void onMapClick( MogoLatLng latLng ) {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getMapListener() != null ) {
provider.getMapListener().onMapClick( latLng );
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getMapListener() != null ) {
mRefreshStrategyProvider.getMapListener().onMapClick( latLng );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getMapListener() != null ) {
value.getMapListener().onMapClick( latLng );
}
}
} else {
if ( value.getMapListener() != null ) {
value.getMapListener().onMapClick( latLng );
}
}
}
}
@Override
public void onLockMap( boolean isLock ) {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getMapListener() != null ) {
provider.getMapListener().onLockMap( isLock );
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getMapListener() != null ) {
mRefreshStrategyProvider.getMapListener().onLockMap( isLock );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getMapListener() != null ) {
value.getMapListener().onLockMap( isLock );
}
}
} else {
if ( value.getMapListener() != null ) {
value.getMapListener().onLockMap( isLock );
}
}
}
}
@Override
public void onMapModeChanged( EnumMapUI ui ) {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getMapListener() != null ) {
provider.getMapListener().onMapModeChanged( ui );
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getMapListener() != null ) {
mRefreshStrategyProvider.getMapListener().onMapModeChanged( ui );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getMapListener() != null ) {
value.getMapListener().onMapModeChanged( ui );
}
}
} else {
if ( value.getMapListener() != null ) {
value.getMapListener().onMapModeChanged( ui );
}
}
}
}
@Override
public void onMapChanged( MogoLatLng location, float zoom, float tilt, float bearing ) {
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getMapListener() != null ) {
mRefreshStrategyProvider.getMapListener().onMapChanged( location, zoom, tilt, bearing );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getMapListener() != null ) {
value.getMapListener().onMapChanged( location, zoom, tilt, bearing );
}
}
} else {
if ( value.getMapListener() != null ) {
value.getMapListener().onMapChanged( location, zoom, tilt, bearing );
}
}
}
}
@Override
public void onInitNaviFailure() {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getNaviListener() != null ) {
provider.getNaviListener().onInitNaviFailure();
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getNaviListener() != null ) {
mRefreshStrategyProvider.getNaviListener().onInitNaviFailure();
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onInitNaviFailure();
}
}
} else {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onInitNaviFailure();
}
}
}
}
@Override
public void onInitNaviSuccess() {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getNaviListener() != null ) {
provider.getNaviListener().onInitNaviSuccess();
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getNaviListener() != null ) {
mRefreshStrategyProvider.getNaviListener().onInitNaviSuccess();
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onInitNaviSuccess();
}
}
} else {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onInitNaviSuccess();
}
}
}
}
@Override
public void onNaviInfoUpdate( MogoNaviInfo naviinfo ) {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getNaviListener() != null ) {
provider.getNaviListener().onNaviInfoUpdate( naviinfo );
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getNaviListener() != null ) {
mRefreshStrategyProvider.getNaviListener().onNaviInfoUpdate( naviinfo );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onNaviInfoUpdate( naviinfo );
}
}
} else {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onNaviInfoUpdate( naviinfo );
}
}
}
}
@Override
public void onStartNavi() {
Logger.i( TAG, "导航已开始" );
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getNaviListener() != null ) {
provider.getNaviListener().onStartNavi();
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getNaviListener() != null ) {
mRefreshStrategyProvider.getNaviListener().onStartNavi();
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onStartNavi();
}
}
} else {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onStartNavi();
}
}
}
}
@Override
public void onStopNavi() {
Logger.i( TAG, "导航已停止" );
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getNaviListener() != null ) {
provider.getNaviListener().onStopNavi();
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getNaviListener() != null ) {
mRefreshStrategyProvider.getNaviListener().onStopNavi();
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onStopNavi();
}
}
} else {
if ( value.getNaviListener() != null ) {
value.getNaviListener().onStopNavi();
}
}
}
}
@Override
public void onLocationChanged( MogoLocation location ) {
if ( mEnableModuleName != null ) {
IMogoModuleProvider provider = getModuleProvider( mEnableModuleName );
if ( provider != null && provider.getLocationListener() != null ) {
provider.getLocationListener().onLocationChanged( location );
}
}
if ( mRefreshStrategyProvider != null ) {
if ( mRefreshStrategyProvider.getLocationListener() != null ) {
mRefreshStrategyProvider.getLocationListener().onLocationChanged( location );
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getType() == ModuleType.TYPE_CARD_FRAGMENT ) {
if ( mEnableModuleName != null && TextUtils.equals( value.getModuleName(), mEnableModuleName ) ) {
if ( value.getLocationListener() != null ) {
value.getLocationListener().onLocationChanged( location );
}
}
} else {
if ( value.getLocationListener() != null ) {
value.getLocationListener().onLocationChanged( location );
}
}
}
}
@@ -381,7 +396,7 @@ public class MogoModulesManager implements MogoModulesHandler,
public void onReceive( Context context, Intent intent ) {
final String action = intent.getAction();
if ( TextUtils.equals( action, Intent.ACTION_POWER_CONNECTED ) ) {
for ( IMogoModuleProvider value : mCardProviders.values() ) {
for ( IMogoModuleProvider value : mModuleProviders.values() ) {
if ( value.getCardLifecycle() != null ) {
value.getCardLifecycle().accOn();
}
@@ -408,11 +423,10 @@ public class MogoModulesManager implements MogoModulesHandler,
}
mReceiver = null;
mActivity = null;
if ( mCardProviders != null ) {
mCardProviders.clear();
if ( mModuleProviders != null ) {
mModuleProviders.clear();
}
mMapProvider = null;
mAppsListProvider = null;
mModuleProviders = null;
mMapLoadedCallback = null;
mEnableModuleName = null;
}

View File

@@ -19,6 +19,7 @@ import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.module.main.R;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
/**
* @author congtaowang
@@ -80,7 +81,7 @@ public class PlaceholderFragmentProvider implements IMogoModuleProvider {
@Override
public int getType() {
return TYPE_FRAGMENT;
return ModuleType.TYPE_CARD_FRAGMENT;
}
@Override

View File

@@ -3,26 +3,27 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0C0C0C"
android:orientation="vertical">
<!-- 小智语音-->
<FrameLayout
android:id="@+id/module_main_id_ai_fragment_container"
android:layout_width="match_parent"
android:layout_height="75dp"
android:background="#f00"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginTop="5dp">
<!-- 卡片-->
<FrameLayout
android:id="@+id/module_main_id_fragment_container"
android:layout_width="0dp"
android:layout_width="360dp"
android:layout_height="match_parent"
android:layout_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
@@ -30,17 +31,19 @@
android:id="@+id/module_main_id_cards_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp"
android:padding="10dp" />
android:layout_marginTop="-15dp"
android:layout_marginBottom="90dp"
android:background="#ffffff"
android:padding="15dp" />
</FrameLayout>
<!-- 地图-->
<FrameLayout
android:id="@+id/module_main_id_map_fragment_container"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:layout_marginLeft="-15dp"
app:layout_constraintLeft_toRightOf="@+id/module_main_id_fragment_container"
app:layout_constraintRight_toRightOf="parent" />
</LinearLayout>

View File

@@ -102,7 +102,7 @@ public class MapFragment extends MvpFragment< MapView, MapPresenter > implements
//设置拖拽手势是否可用。
uiSettings.setScrollGesturesEnabled( true );
//设置倾斜手势是否可用。
uiSettings.setTiltGesturesEnabled( false );
uiSettings.setTiltGesturesEnabled( true );
//设置缩放按钮是否可见。
uiSettings.setZoomControlsEnabled( false );
//设置双指缩放手势是否可用。

View File

@@ -14,6 +14,7 @@ import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
/**
* @author congtaowang
@@ -46,7 +47,7 @@ public class MapFragmentProvider implements IMogoModuleProvider {
@Override
public int getType() {
return IMogoModuleProvider.TYPE_FRAGMENT;
return ModuleType.TYPE_MAP;
}

View File

@@ -1,4 +1,5 @@
apply plugin: 'com.android.library'
apply plugin: 'com.alibaba.arouter'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
@@ -37,6 +38,8 @@ dependencies {
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.arouter
annotationProcessor rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxjava
implementation rootProject.ext.dependencies.rxandroid
if (Boolean.valueOf(RELEASE)) {
api rootProject.ext.dependencies.mogomap
api rootProject.ext.dependencies.mogomapapi
@@ -53,3 +56,5 @@ dependencies {
implementation project(':modules:mogo-module-common')
}
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,48 @@
package com.mogo.module.service;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 自动刷新策略
*/
public class AutoRefreshStrategy {
public static final long ONE_MINUTE = 5 * 1_000L;
/**
* 距离(米)
*/
private int distance = 2_000;
/**
* 时间间距s
*/
private long interval = 3 * ONE_MINUTE;
/**
* 用户打断后的延时s
*/
private long interruptInterval = 1 * ONE_MINUTE;
/**
* 距离(米)
*/
public int getDistance() {
return distance;
}
/**
* 时间间距s
*/
public long getInterval() {
return interval;
}
/**
* 用户打断后的延时
*/
public long getInterruptInterval() {
return interruptInterval;
}
}

View File

@@ -0,0 +1,19 @@
package com.mogo.module.service;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 手动刷新策略
*/
public class CustomRefreshStrategy {
/**
* 缩小倍数
*/
private float zoomOutLevel = 2;
public float getZoomOutLevel() {
return zoomOutLevel;
}
}

View File

@@ -1,148 +0,0 @@
package com.mogo.module.service;
import android.app.Service;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.map.MogoLatLng;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.model.MogoPoi;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.map.navi.MogoNaviInfo;
import com.mogo.map.uicontroller.EnumMapUI;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.utils.logger.Logger;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 数据刷新策略
*/
@Route( path = ServiceConst.PATH_REFRESH_STRATEGY )
public class MogoRefreshStrategyProvider implements IMogoModuleProvider, IMogoMapListener, IMogoLocationListener, IMogoNaviListener {
private static final String TAG = "MogoRefreshStrategyProvider";
@Override
public final Fragment createFragment( Context context, Bundle data ) {
return null;
}
@Override
public final View createView( Context context ) {
return null;
}
@Override
public final IMogoModuleLifecycle getCardLifecycle() {
return null;
}
@Override
public IMogoMapListener getMapListener() {
return this;
}
@Override
public int getType() {
return TYPE_SERVICE;
}
@Override
public IMogoNaviListener getNaviListener() {
return this;
}
@Override
public IMogoLocationListener getLocationListener() {
return this;
}
@NonNull
@Override
public String getModuleName() {
return ServiceConst.PATH_REFRESH_STRATEGY;
}
@Override
public void init( Context context ) {
}
@Override
public void onMapLoaded() {
}
@Override
public void onTouch( MotionEvent motionEvent ) {
}
@Override
public void onPOIClick( MogoPoi poi ) {
}
@Override
public void onMapClick( MogoLatLng latLng ) {
}
@Override
public void onLockMap( boolean isLock ) {
}
@Override
public void onMapModeChanged( EnumMapUI ui ) {
}
@Override
public void onMapChanged( MogoLatLng latLng, float zoom, float tilt, float bearing ) {
Logger.d( TAG, "current map status: %s, zoom = %f, tilt = %f, bearing = %f", latLng, zoom, tilt, bearing );
}
@Override
public void onLocationChanged( MogoLocation location ) {
}
@Override
public void onInitNaviFailure() {
}
@Override
public void onInitNaviSuccess() {
}
@Override
public void onNaviInfoUpdate( MogoNaviInfo naviinfo ) {
}
@Override
public void onStartNavi() {
}
@Override
public void onStopNavi() {
}
}

View File

@@ -0,0 +1,431 @@
package com.mogo.module.service;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.map.MogoLatLng;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.map.model.MogoPoi;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.map.navi.MogoNaviInfo;
import com.mogo.map.uicontroller.EnumMapUI;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.service.network.RefreshCallback;
import com.mogo.module.service.network.RefreshModel;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.map.IMogoMapService;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.statusmanager.StatusDescriptor;
import com.mogo.utils.logger.Logger;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 数据刷新策略
*/
@Route( path = ServiceConst.PATH_REFRESH_STRATEGY )
public class MogoServiceProvider implements IMogoModuleProvider,
IMogoMapListener,
IMogoLocationListener,
IMogoNaviListener,
IMogoStatusChangedListener {
private static final String TAG = "MogoRefreshStrategyProvider";
/**
* 自动刷新策略
*/
private AutoRefreshStrategy mAutoRefreshStrategy = new AutoRefreshStrategy();
private MogoLatLng mLastAutoRefreshLocation = null;
private long mLastRefreshTime = 0;
private IMogoMarkerManager mMarkerManager;
private IMogoMapUIController mUiController;
/**
* 是否已计算出地图显示状态
*/
private boolean mIsMapStatusOk = false;
/**
* 地图显示是横屏还是竖屏:根据地图右上角和左下角坐标计算
*/
boolean mIsVertical = false;
/**
* 手动刷新策略
*/
private CustomRefreshStrategy mCustomRefreshStrategy = new CustomRefreshStrategy();
private float mLastZoomLevel = 0;
private RefreshModel mRefreshModel;
private long mRefreshRemainingTime = Long.MAX_VALUE;
// 上次手动操作的中心点坐标
private MogoLatLng mLastCustomRefreshCenterLocation;
private IMogoMapService mMogoMapService;
private IMogoMarker mCameraCenterMarker = null;
private IMogoStatusManager mStatusManager;
/**
* 地图视图初始化
*/
private boolean mIsCameraInited = true;
private Handler mHandler = new Handler( Looper.getMainLooper() ) {
@Override
public void handleMessage( @NonNull Message msg ) {
super.handleMessage( msg );
switch ( msg.what ) {
case ServiceConst.MSG_TYPE_REFRESH_DECREASE:
mRefreshRemainingTime -= ServiceConst.DECREASE_INTERVAL;
if ( mRefreshRemainingTime == 0 ) {
notifyRefreshData( mAutoRefreshCallback );
} else {
mHandler.sendEmptyMessageDelayed( msg.what, ServiceConst.DECREASE_INTERVAL );
}
break;
}
}
};
private Context mContext;
/**
* 地图视图西南角坐标
*/
private MogoLatLng mCameraSouthWestPosition;
/**
* 地图视图东北角坐标
*/
private MogoLatLng mCameraNorthEastPosition;
/**
* 手动刷新回调
*/
private RefreshCallback mCustomRefreshCallback = new RefreshCallback() {
@Override
public void onSuccess() {
// 用户手动操作地图刷新成功后,设置状态为 true引发延时策略
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, true, true );
mStatusManager.setUserInteractionStatus( ServiceConst.TYPE, false, false );
}
@Override
public void onFail() {
}
};
/**
* 自动刷新回调
*/
private RefreshCallback mAutoRefreshCallback = new RefreshCallback() {
@Override
public void onSuccess() {
invokeAutoRefreshStrategy();
}
@Override
public void onFail() {
invokeAutoRefreshStrategy();
}
private void invokeAutoRefreshStrategy() {
mRefreshRemainingTime = mAutoRefreshStrategy.getInterval();
mHandler.removeMessages( ServiceConst.MSG_TYPE_REFRESH_DECREASE );
mHandler.sendEmptyMessageDelayed( ServiceConst.MSG_TYPE_REFRESH_DECREASE, ServiceConst.DECREASE_INTERVAL );
}
};
@Override
public final Fragment createFragment( Context context, Bundle data ) {
return null;
}
@Override
public final View createView( Context context ) {
return null;
}
@Override
public final IMogoModuleLifecycle getCardLifecycle() {
return null;
}
@Override
public IMogoMapListener getMapListener() {
return this;
}
@Override
public int getType() {
return ModuleType.TYPE_SERVICE;
}
@Override
public IMogoNaviListener getNaviListener() {
return this;
}
@Override
public IMogoLocationListener getLocationListener() {
return this;
}
@NonNull
@Override
public String getModuleName() {
return ServiceConst.TYPE;
}
@Override
public void init( Context context ) {
mContext = context;
mRefreshModel = new RefreshModel( context );
mMogoMapService = ( IMogoMapService ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICES_MAP ).navigation( context );
mMarkerManager = mMogoMapService.getMarkerManager( context );
mUiController = mMogoMapService.getMapUIController();
mStatusManager = ( IMogoStatusManager ) ARouter.getInstance().build( MogoServicePaths.PATH_STATUS_MANAGER ).navigation( context );
mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.USER_INTERACTED, this );
}
@Override
public void onMapLoaded() {
refreshCameraPosition();
}
private void initMapStatus() {
if ( mIsMapStatusOk ) {
return;
}
try {
float width = getMapCameraFactWidth();
float height = getMapCameraFactHeight();
mIsVertical = width < height;
Logger.i( TAG, "map status is vertical : " + mIsVertical );
mIsMapStatusOk = true;
} catch ( Exception e ) {
}
}
/**
* 地图视图对应的实际宽度
*
* @return
*/
private float getMapCameraFactWidth() {
return Utils.calculateLineDistance( mCameraNorthEastPosition, new MogoLatLng( mCameraNorthEastPosition.lat, mCameraSouthWestPosition.lng ) );
}
/**
* 地图视图对应的实际高度
*
* @return
*/
private float getMapCameraFactHeight() {
return Utils.calculateLineDistance( mCameraSouthWestPosition, new MogoLatLng( mCameraNorthEastPosition.lat, mCameraSouthWestPosition.lng ) );
}
/**
* 刷新视图范围坐标
*/
private void refreshCameraPosition() {
mCameraSouthWestPosition = mUiController.getCameraSouthWestPosition();
mCameraNorthEastPosition = mUiController.getCameraNorthEastPosition();
initMapStatus();
if ( mIsVertical ) {
float width = getMapCameraFactWidth();
Logger.i( TAG, "current zoom level width: %f m", width );
} else {
float height = getMapCameraFactHeight();
Logger.i( TAG, "current zoom level height: %f m", height );
}
}
@Override
public void onTouch( MotionEvent motionEvent ) {
switch ( motionEvent.getActionMasked() ) {
case MotionEvent.ACTION_DOWN:
if ( mLastZoomLevel == 0 ) {
mLastZoomLevel = mUiController.getZoomLevel();
Logger.i( TAG, "初始化缩放级别 为:%f", mLastZoomLevel );
}
break;
case MotionEvent.ACTION_UP:
break;
}
}
private void stopAutoRefreshStrategy() {
mHandler.removeMessages( ServiceConst.MSG_TYPE_REFRESH_DECREASE );
}
@Override
public void onPOIClick( MogoPoi poi ) {
}
@Override
public void onMapClick( MogoLatLng latLng ) {
}
@Override
public void onLockMap( boolean isLock ) {
}
@Override
public void onMapModeChanged( EnumMapUI ui ) {
}
@Override
public void onMapChanged( MogoLatLng latLng, float zoom, float tilt, float bearing ) {
if ( mIsCameraInited ) {
mLastCustomRefreshCenterLocation = latLng;
mIsCameraInited = false;
return;
}
if ( mCameraCenterMarker == null ) {
mCameraCenterMarker = mMarkerManager.addMarker( ServiceConst.TYPE,
new MogoMarkerOptions()
.icon( BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_search_poi_location ) )
.latitude( latLng.lat )
.longitude( latLng.lng )
.owner( ServiceConst.TYPE )
);
} else {
mCameraCenterMarker.setPosition( latLng.lat, latLng.lng );
}
if ( mLastZoomLevel != zoom ) {
refreshCameraPosition();
}
// 手动刷新触发
if ( mLastZoomLevel - zoom > mCustomRefreshStrategy.getZoomOutLevel() ) {
// 缩放级别缩小
notifyRefreshData( mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
mLastZoomLevel = zoom;
} else if ( mLastZoomLevel == zoom ) {
// 手动平移
if ( invokeRefreshWhenTranslationByUser( latLng ) ) {
notifyRefreshData( mCustomRefreshCallback );
mLastCustomRefreshCenterLocation = latLng;
}
}
Logger.d( TAG, "current map status: %s, zoom = %f, tilt = %f, bearing = %f", latLng, zoom, tilt, bearing );
}
/**
* 平移地图刷新策略
*
* @return
*/
private boolean invokeRefreshWhenTranslationByUser( MogoLatLng latLng ) {
try {
float factor = 0.0f;
if ( mIsVertical ) {
factor = getMapCameraFactWidth();
} else {
factor = getMapCameraFactHeight();
}
if ( factor == 0.0f ) {
return false;
}
float distance = Utils.calculateLineDistance( latLng, mLastCustomRefreshCenterLocation );
return distance > factor;
} catch ( Exception e ) {
Logger.w( TAG, "warming. ", e );
return false;
}
}
@Override
public void onLocationChanged( MogoLocation location ) {
if ( location == null ) {
return;
}
// 自动刷新触发
if ( mLastAutoRefreshLocation == null ) {
mLastAutoRefreshLocation = new MogoLatLng( location.getLatitude(), location.getLongitude() );
notifyRefreshData( mAutoRefreshCallback );
} else {
float distance = Utils.calculateLineDistance( mLastAutoRefreshLocation, new MogoLatLng( location.getLatitude(), location.getLongitude() ) );
if ( distance > mAutoRefreshStrategy.getDistance() ) {
notifyRefreshData( mAutoRefreshCallback );
}
}
}
/**
* 刷新数据
*/
private void notifyRefreshData( RefreshCallback callback ) {
Logger.d( TAG, mAutoRefreshCallback == callback ? "触发自动刷新" : "触发手动刷新" );
mRefreshModel.refreshData( callback );
}
@Override
public void onInitNaviFailure() {
}
@Override
public void onInitNaviSuccess() {
}
@Override
public void onNaviInfoUpdate( MogoNaviInfo naviinfo ) {
}
@Override
public void onStartNavi() {
}
@Override
public void onStopNavi() {
}
@Override
public void onStatusChanged( StatusDescriptor descriptor, boolean isTrue ) {
if ( descriptor == StatusDescriptor.USER_INTERACTED && isTrue ) {
Logger.i( TAG, "用户状态改变,自动刷新时间延时" );
mRefreshRemainingTime += mAutoRefreshStrategy.getInterruptInterval();
}
}
}

View File

@@ -8,8 +8,22 @@ package com.mogo.module.service;
*/
public class ServiceConst {
/**
* 类型
*/
public static final String TYPE = "STRATEGY_REFRESH";
/**
* 刷新策略模块地址
*/
public static final String PATH_REFRESH_STRATEGY = "/strategy/refresh";
/**
* 倒计时消息
*/
public static final int MSG_TYPE_REFRESH_DECREASE = 0x100;
/**
* 倒计时间隔
*/
public static final int DECREASE_INTERVAL = 1_000;
}

View File

@@ -0,0 +1,51 @@
package com.mogo.module.service;
import com.amap.api.maps.AMapException;
import com.amap.api.maps.model.LatLng;
import com.mogo.map.MogoLatLng;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 描述
*/
public class Utils {
public static float calculateLineDistance( MogoLatLng point1, MogoLatLng point2 ) {
if ( point1 != null && point2 != null ) {
try {
double var2 = point1.lng;
double var4 = point1.lat;
double var6 = point2.lng;
double var8 = point2.lat;
var2 *= 0.01745329251994329D;
var4 *= 0.01745329251994329D;
var6 *= 0.01745329251994329D;
var8 *= 0.01745329251994329D;
double var10 = Math.sin( var2 );
double var12 = Math.sin( var4 );
double var14 = Math.cos( var2 );
double var16 = Math.cos( var4 );
double var18 = Math.sin( var6 );
double var20 = Math.sin( var8 );
double var22 = Math.cos( var6 );
double var24 = Math.cos( var8 );
double[] var28 = new double[3];
double[] var29 = new double[3];
var28[0] = var16 * var14;
var28[1] = var16 * var10;
var28[2] = var12;
var29[0] = var24 * var22;
var29[1] = var24 * var18;
var29[2] = var20;
return ( float ) ( Math.asin( Math.sqrt( ( var28[0] - var29[0] ) * ( var28[0] - var29[0] ) + ( var28[1] - var29[1] ) * ( var28[1] - var29[1] ) + ( var28[2] - var29[2] ) * ( var28[2] - var29[2] ) ) / 2.0D ) * 1.27420015798544E7D );
} catch ( Throwable var26 ) {
var26.printStackTrace();
return 0.0F;
}
} else {
return 0.0F;
}
}
}

View File

@@ -0,0 +1,22 @@
package com.mogo.module.service.network;
import com.mogo.commons.data.BaseData;
import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.Single;
import retrofit2.http.GET;
import retrofit2.http.QueryMap;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 接口描述
*/
public interface RefreshApiService {
@GET( "" )
Observable< BaseData > refreshData( @QueryMap Map< String, Object > params );
}

View File

@@ -0,0 +1,14 @@
package com.mogo.module.service.network;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 刷新回调
*/
public interface RefreshCallback {
void onSuccess();
void onFail();
}

View File

@@ -0,0 +1,65 @@
package com.mogo.module.service.network;
import android.content.Context;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.data.BaseData;
import com.mogo.commons.network.ParamsProvider;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.network.IMogoNetwork;
import com.mogo.utils.network.RequestOptions;
import java.util.Map;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 刷新数据
*/
public class RefreshModel {
private final Context mContext;
private RefreshApiService mRefreshApiService;
public RefreshModel( Context context ) {
this.mContext = context;
IMogoNetwork network = ( IMogoNetwork ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICES_NETWORK ).navigation( context );
this.mRefreshApiService = network.create( RefreshApiService.class, "http://www.baidu.com/" );
}
public void refreshData( final RefreshCallback callback ) {
if ( callback != null ) {
callback.onSuccess();
return;
}
if ( mRefreshApiService != null ) {
final Map< String, Object > params = new ParamsProvider.Builder( mContext ).build();
mRefreshApiService.refreshData( params )
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() )
.subscribe( new SubscribeImpl< BaseData >( RequestOptions.create( mContext ) ) {
@Override
public void onSuccess( BaseData o ) {
super.onSuccess( o );
if ( callback != null ) {
callback.onSuccess();
}
}
@Override
public void onError( String message, int code ) {
super.onError( message, code );
if ( callback != null ) {
callback.onFail();
}
}
} );
}
}
}

View File

@@ -12,6 +12,7 @@ import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
import com.mogo.tanlu.constant.TanluConstants;
import com.mogo.utils.logger.Logger;
@@ -63,7 +64,7 @@ public class TanluCardViewProvider implements IMogoModuleProvider {
@Override
public int getType() {
return IMogoModuleProvider.TYPE_FRAGMENT;
return ModuleType.TYPE_CARD_FRAGMENT;
}
@Override

View File

@@ -20,21 +20,6 @@ import com.mogo.map.navi.IMogoNaviListener;
*/
public interface IMogoModuleProvider extends IProvider {
/**
* 模块类型为fragment
*/
int TYPE_FRAGMENT = 1;
/**
* 模块类型为view
*/
int TYPE_VIEW = 2;
/**
* 服务模块
*/
int TYPE_SERVICE = 3;
/**
* 创建卡片
*
@@ -76,8 +61,7 @@ public interface IMogoModuleProvider extends IProvider {
/**
* 是哪种类型的提供者
* <p>
* {@link #TYPE_FRAGMENT}
* {@link #TYPE_VIEW}
* {@link ModuleType}
*
* @return
*/

View File

@@ -0,0 +1,51 @@
package com.mogo.service.module;
/**
* @author congtaowang
* @since 2020-01-03
* <p>
* 模块类型
*/
public interface ModuleType {
/**
* 卡片类型 - fragment
*/
int TYPE_CARD_FRAGMENT = 1;
/**
* 卡片类型 - view
*/
@Deprecated
int TYPE_CARD_VIEW = 2;
/**
* 服务类型的模块
*/
int TYPE_SERVICE = 3;
/**
* APP 列表模块
*/
int TYPE_APP_LIST = 4;
/**
* 小智语音形象
*/
int TYPE_VOICE = 5;
/**
* 地图模块
*/
int TYPE_MAP = 6;
/**
* 导航模块
*/
int TYPE_NAVI = 7;
/**
* 小智、天气、时间等
*/
int TYPE_EXTENSION = 8;
}

View File

@@ -0,0 +1,16 @@
package com.mogo.service.statusmanager;
/**
* @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

@@ -38,31 +38,85 @@ public interface IMogoStatusManager extends IProvider {
*/
boolean isPushShow();
/**
* 是否开机
*
* @return true - 开机 false - 关机
*/
boolean isAccOn();
/**
* 是否有用户交互
*
* @return
*/
boolean isUserInteracted();
/**
* 设置小智语音UI状态
*
* @param tag 业务类型
* @param show true - 显示 false - 隐藏
*/
void setVoiceUIShow( boolean show );
void setVoiceUIShow( String tag, boolean show );
/**
* 设置 ADAS UI 状态
*
* @param tag 业务类型
* @param show true - 显示 false - 隐藏
*/
void setADASUIShow( boolean show );
void setADASUIShow( String tag, boolean show );
/**
* 设置 V2X UI 状态
*
* @param tag 业务类型
* @param show true - 显示 false - 隐藏
*/
void setV2XUIShow( boolean show );
void setV2XUIShow( String tag, boolean show );
/**
* 设置 PUSH UI 状态
*
* @param tag 业务类型
* @param show true - 显示 false - 隐藏
*/
void setPushUIShow( boolean show );
void setPushUIShow( String tag, boolean show );
/**
* 设置 acc 状态
*
* @param tag 业务类型
* @param isOn true - on, false - off
*/
void setAccStatus( String tag, boolean isOn );
/**
* 设置用户交互状态:地图手势交互、语音控制
*
* @param tag 业务类型
* @param interrupt true - 用户在交互
* @param callback 是否引起回调
*/
void setUserInteractionStatus( String tag, boolean interrupt, boolean callback );
/**
* 注册监听
*
* @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,40 @@
package com.mogo.service.statusmanager;
/**
* @author congtaowang
* @since 2020-01-04
* <p>
* 状态描述
*/
public enum StatusDescriptor {
/**
* adas UI
*/
ADAS_UI,
/**
* 推送UI弹窗
*/
PUSH_UI,
/**
* v2x UI
*/
V2X_UI,
/**
* 小智语音交互 UI
*/
VOICE_UI,
/**
* 开机状态
*/
ACC_STATUS,
/**
* 用户交互状态
*/
USER_INTERACTED
}

View File

@@ -37,7 +37,6 @@ import com.mogo.utils.network.RetrofitFactory;
@Route( path = MogoServicePaths.PATH_SERVICES_NETWORK)
public class MogoNetWorkService implements IMogoNetwork {
@Override
public void init( Context context ) {
MogoInitor.init( context );

View File

@@ -5,8 +5,14 @@ import android.content.Context;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.statusmanager.StatusDescriptor;
import com.mogo.utils.logger.Logger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -20,69 +26,134 @@ import java.util.concurrent.ConcurrentHashMap;
public class MogoStatusManager implements IMogoStatusManager {
/**
* 小智语音UI
* 状态记录
*/
private static final int UI_VOICE = 1;
private static final Map< StatusDescriptor, Boolean > mStatus = new ConcurrentHashMap<>();
/**
* ADAS UI
* 回调集合
*/
private static final int UI_ADAS = 2;
private static final Map< StatusDescriptor, List< IMogoStatusChangedListener > > mListeners = new ConcurrentHashMap<>();
/**
* V2X UI
* 状态类型修改记录
*/
private static final int UI_V2X = 3;
/**
* PUSH UI
*/
private static final int UI_PUSH = 4;
private static final Map< Integer, Boolean > mStatus = new ConcurrentHashMap<>();
private static final Map< StatusDescriptor, String > mModifier = new ConcurrentHashMap<>();
@Override
public boolean isVoiceShow() {
return mStatus.get( UI_VOICE );
return get_bool_val( StatusDescriptor.VOICE_UI );
}
@Override
public boolean isADASShow() {
return mStatus.get( UI_ADAS );
return get_bool_val( StatusDescriptor.ADAS_UI );
}
@Override
public boolean isV2XShow() {
return mStatus.get( UI_V2X );
return get_bool_val( StatusDescriptor.V2X_UI );
}
@Override
public boolean isPushShow() {
return mStatus.get( UI_PUSH );
return get_bool_val( StatusDescriptor.PUSH_UI );
}
@Override
public void setVoiceUIShow( boolean show ) {
mStatus.put( UI_VOICE, show );
public boolean isAccOn() {
return get_bool_val( StatusDescriptor.ACC_STATUS );
}
@Override
public void setADASUIShow( boolean show ) {
mStatus.put( UI_ADAS, show );
public boolean isUserInteracted() {
return get_bool_val( StatusDescriptor.USER_INTERACTED );
}
private boolean get_bool_val( StatusDescriptor descriptor ) {
Boolean val = mStatus.get( descriptor );
return val == null ? false : val;
}
@Override
public void setV2XUIShow( boolean show ) {
mStatus.put( UI_V2X, show );
public void setVoiceUIShow( String tag, boolean show ) {
mStatus.put( StatusDescriptor.VOICE_UI, show );
invokeStatusChangedListener( StatusDescriptor.VOICE_UI, show );
recorderStatusModifier( tag, StatusDescriptor.VOICE_UI );
}
@Override
public void setPushUIShow( boolean show ) {
mStatus.put( UI_PUSH, show );
public void setADASUIShow( String tag, boolean show ) {
mStatus.put( StatusDescriptor.ADAS_UI, show );
invokeStatusChangedListener( StatusDescriptor.ADAS_UI, show );
recorderStatusModifier( tag, StatusDescriptor.ADAS_UI );
}
@Override
public void setV2XUIShow( String tag, boolean show ) {
mStatus.put( StatusDescriptor.V2X_UI, show );
invokeStatusChangedListener( StatusDescriptor.V2X_UI, show );
recorderStatusModifier( tag, StatusDescriptor.V2X_UI );
}
@Override
public void setPushUIShow( String tag, boolean show ) {
mStatus.put( StatusDescriptor.PUSH_UI, show );
invokeStatusChangedListener( StatusDescriptor.PUSH_UI, show );
recorderStatusModifier( tag, StatusDescriptor.PUSH_UI );
}
@Override
public void setAccStatus( String tag, boolean isOn ) {
mStatus.put( StatusDescriptor.ACC_STATUS, isOn );
invokeStatusChangedListener( StatusDescriptor.ACC_STATUS, isOn );
recorderStatusModifier( tag, StatusDescriptor.ACC_STATUS );
}
@Override
public void setUserInteractionStatus( String tag, boolean interrupt, boolean callback ) {
mStatus.put( StatusDescriptor.USER_INTERACTED, interrupt );
if ( callback ) {
invokeStatusChangedListener( StatusDescriptor.USER_INTERACTED, interrupt );
}
recorderStatusModifier( tag, StatusDescriptor.USER_INTERACTED );
}
private void invokeStatusChangedListener( StatusDescriptor descriptor, boolean status ) {
if ( mListeners.containsKey( descriptor ) ) {
Iterator< IMogoStatusChangedListener > iterator = mListeners.get( descriptor ).iterator();
while ( iterator.hasNext() ) {
IMogoStatusChangedListener listener = iterator.next();
if ( listener != null ) {
listener.onStatusChanged( descriptor, status );
}
}
}
}
private void recorderStatusModifier( String tag, StatusDescriptor descriptor ) {
mModifier.put( descriptor, tag );
}
@Override
public void registerStatusChangedListener( String tag, StatusDescriptor descriptor, IMogoStatusChangedListener listeners ) {
if ( listeners == null || descriptor == null ) {
return;
}
if ( !mListeners.containsKey( descriptor ) ) {
mListeners.put( descriptor, new ArrayList<>() );
}
mListeners.get( descriptor ).add( listeners );
}
@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

@@ -15,4 +15,5 @@ include ':libraries:map-amap'
//include ':libraries:map-baidu'
include ':libraries:mogo-map-api'
include ':modules:mogo-module-apps'
include ':modules:mogo-module-extensions'
include ':foudations:mogo-connection'