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

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